QueryofQuery的PHP版本
TL;DR:如何修改下面的QueryofQuery的PHP版本,php,oracle,oci8,Php,Oracle,Oci8,TL;DR:如何修改下面的queryOfQuery()函数以使用OCI8/Oracle后端 在寻找PHP等价物的过程中,我遇到了以下问题: 我想调整这段代码以适应我们的数据库环境(我们使用Oracle和OCI8,而不是编写函数的MySQL)。不幸的是,我刚开始的PHP技能让我无法胜任这项任务。具体来说,我可以看到,mysql\u data\u seek()和mysql\u fetch\u assoc()很可能会被OCI8替代。插件的等价物是什么?还有什么需要调整的吗?修改函数以使用OCI很简单,
queryOfQuery()
函数以使用OCI8/Oracle后端
在寻找PHP等价物的过程中,我遇到了以下问题:
我想调整这段代码以适应我们的数据库环境(我们使用Oracle和OCI8,而不是编写函数的MySQL)。不幸的是,我刚开始的PHP技能让我无法胜任这项任务。具体来说,我可以看到,
mysql\u data\u seek()
和mysql\u fetch\u assoc()
很可能会被OCI8替代。插件的等价物是什么?还有什么需要调整的吗?修改函数以使用OCI很简单,但不幸的是,您失去了从结果集重复获取的能力
我已经在下面发布了完整的功能,但只需要更改三行。我已经注释掉了现有的行,以显示更改的位置
对mysql\u data\u seek()
的调用被简单地删除。如果已经执行了任何回迁,则第一个调用将resultset指针重置为第一条记录。这确保“子查询”获得所有适用的记录。第二个调用再次重置指针,以确保函数执行后的进一步处理将从结果集的开头开始
我查看了指针,但没有看到重置指针的等效项。我认为您可以使用游标来实现这一点,但我不知道PL/SQL,因此无法在这方面提供任何帮助
总之,您可以“查询查询”,但有两个注意事项:
编辑:我对此进行了更深入的研究,我认为这对CFML开发人员来说是一种误导,因为PHP和CFML在术语和方法上存在差异。汤姆·穆克似乎误解了这些差异,因此无意中歪曲了他的职能运作方式 在阅读了全文之后,我相信CFML中的查询会隐式地将所有行提取到web服务器内存中。这就是允许在不与数据库服务器对话的情况下再次“查询”结果集的原因 在PHP中,开发人员对函数的选择控制着这种行为(因此他/她会做出明确的选择)。标准行为将是(为简洁起见简化):
- 获取并处理每一行,保持内存使用率较低,但可能由于不断从数据库服务器接收数据而导致性能降低
- 获取所有行,可能会使用大量内存,但也可以通过直接从web服务器内存工作来查看可能的性能改进
编辑2: 此调整后的queryOfQuery函数未绑定到任何特定数据库;它在给定数组(
rs
)上循环,而不管它是如何生成的:
function queryOfQuery(
$rs, // The recordset to query
$fields = "*", // optional comma-separated list of fields to return, or * for all fields
$distinct = false, // optional true for distinct records
$fieldToMatch = null, // optional database field name to match
$valueToMatch = null // optional unless $fieldToMatch is specified; value to match in the field, as a comma-separated list
) {
$newRs = Array();
$row = Array();
$valueToMatch = explode(",",$valueToMatch);
$matched = true;
if($rs) {
// $issue$ this loop over the results should be moved to lines 20 and 31
foreach($rs AS $row_rs){
if($fields == "*") {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
};
};
if($matched) $row = $row_rs;
}
else {
$fieldsArray=explode(",",$fields);
foreach($fieldsArray as $field) {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
};
};
if($matched) $row[$field] = $row_rs[$field];
};
};
if($matched)array_push($newRs, $row);
};
if($distinct) {
sort($newRs);
for($i = count($newRs)-1; $i > 0; $i--) {
if($newRs[$i] == $newRs[$i-1]) unset($newRs[$i]);
};
};
};
return $newRs;
};
从和
odbc_fetch_row
中找到,但在一个法语页面中找到了它(顺便说一句,您的姓上没有双关语),如果需要,您可以使用谷歌翻译。我希望这会有所帮助。在我看来,$rs只是PHP存储SQL结果的数组。如果这是真的,为什么需要使用DB函数与此数组交互?$rs
属于这种类型。您可以使用var\u dump($rs)
查看详细信息mysql\u fetch\u assoc()
和oci\u fetch\u assoc()
提供了一种与从各自驱动程序返回的特定资源交互的方法。我更新了我的答案,试图理解和解释PHP和CFML在数据库访问方面的差异。虽然这不一定是您想要的答案,但我希望它能为您提供解决问题所需的信息。在我的例子中,我总是将完整的结果集返回到PHP数组中,从该数组中我可以多次引用该数据。理想情况下,QofQ允许我加入数组,并对PHP驻留数据执行其他类似SQL的基本命令(过滤、排序)。这样的任务可能要求太多,而且在任何情况下都不在我最初问题的范围内(这是我应该要求的)。应该可以修改函数以处理数组而不是资源。只需将行while($row_rs=oci_fetch_assoc($rs)){
更改为foreach($row_rs){
并传递从oci_fetch_all()返回的数组(
)(确保使用oci FETCHSTATEMENT\u BY_BY_row
标志!)。
function queryOfQuery($rs, // The recordset to query
$fields = "*", // optional comma-separated list of fields to return, or * for all fields
$distinct = false, // optional true for distinct records
$fieldToMatch = null, // optional database field name to match
$valueToMatch = null) { // optional value to match in the field, as a comma-separated list
$newRs = Array();
$row = Array();
$valueToMatch = explode(",",$valueToMatch);
$matched = true;
//mysql_data_seek($rs, 0);
if($rs) {
//while ($row_rs = mysql_fetch_assoc($rs)){
while ($row_rs = oci_fetch_assoc($rs)){
if($fields == "*") {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
}
}
if($matched) $row = $row_rs;
}else{
$fieldsArray=explode(",",$fields);
foreach($fields as $field) {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
}
}
if($matched) $row[$field] = $row_rs[$field];
}
}
if($matched)array_push($newRs, $row);
};
if($distinct) {
sort($newRs);
for($i = count($newRs)-1; $i > 0; $i--) {
if($newRs[$i] == $newRs[$i-1]) unset($newRs[$i]);
}
}
}
//mysql_data_seek($rs, 0);
return $newRs;
}
function queryOfQuery(
$rs, // The recordset to query
$fields = "*", // optional comma-separated list of fields to return, or * for all fields
$distinct = false, // optional true for distinct records
$fieldToMatch = null, // optional database field name to match
$valueToMatch = null // optional unless $fieldToMatch is specified; value to match in the field, as a comma-separated list
) {
$newRs = Array();
$row = Array();
$valueToMatch = explode(",",$valueToMatch);
$matched = true;
if($rs) {
// $issue$ this loop over the results should be moved to lines 20 and 31
foreach($rs AS $row_rs){
if($fields == "*") {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
};
};
if($matched) $row = $row_rs;
}
else {
$fieldsArray=explode(",",$fields);
foreach($fieldsArray as $field) {
if($fieldToMatch != null) {
$matched = false;
if(is_integer(array_search($row_rs[$fieldToMatch],$valueToMatch))){
$matched = true;
};
};
if($matched) $row[$field] = $row_rs[$field];
};
};
if($matched)array_push($newRs, $row);
};
if($distinct) {
sort($newRs);
for($i = count($newRs)-1; $i > 0; $i--) {
if($newRs[$i] == $newRs[$i-1]) unset($newRs[$i]);
};
};
};
return $newRs;
};