$columns = $this->get_columns($tablename);
}
foreach($params as $key => $value) {
- // First of all, handle already detected LOBs
+ // Decouple column name and param name as far as sometimes they aren't the same
+ $columnname = $key; // Defaul columname (for DB introspecting is key), but...
+ if ($key == 'newfieldtoset') { // found case where column and key diverge, handle that
+ $columnname = key($value); // columnname is the key of the array
+ $params[$key] = $value[$columnname]; // set the proper value in the $params array and
+ $value = $value[$columnname]; // set the proper value in the $value variable
+ }
+ // Continue processing
+ // Now, handle already detected LOBs
if (is_array($value)) { // Let's go to bind special cases (lob descriptors)
if (isset($value['clob'])) {
$lob = oci_new_descriptor($this->oci, OCI_DTYPE_LOB);
oci_bind_by_name($stmt, $key, $lob, -1, SQLT_CLOB);
- $lob->writeTemporary($this->oracle_dirty_hack($tablename, $key, $params[$key]['clob']), OCI_TEMP_CLOB);
+ $lob->writeTemporary($this->oracle_dirty_hack($tablename, $columnname, $params[$key]['clob']), OCI_TEMP_CLOB);
$descriptors[] = $lob;
continue; // Column binding finished, go to next one
} else if (isset($value['blob'])) {
}
// TODO: Put propper types and length is possible (enormous speedup)
// Arrived here, continue with standard processing, using metadata if possible
- if (isset($columns[$key])) {
- $type = $columns[$key]->meta_type;
- $maxlength = $columns[$key]->max_length;
+ if (isset($columns[$columnname])) {
+ $type = $columns[$columnname]->meta_type;
+ $maxlength = $columns[$columnname]->max_length;
} else {
$type = '?';
$maxlength = -1;
default: // Bind as CHAR (applying dirty hack)
// TODO: Optimise
- oci_bind_by_name($stmt, $key, $this->oracle_dirty_hack($tablename, $key, $params[$key]));
+ oci_bind_by_name($stmt, $key, $this->oracle_dirty_hack($tablename, $columnname, $params[$key]));
}
}
}
if (is_null($newvalue)) {
$newsql = "$newfield = NULL";
} else {
- $params[$newfield] = $newvalue;
- $newsql = "$newfield = :$newfield";
+ // Set the param to array ($newfield => $newvalue) and key to 'newfieldtoset'
+ // name in the build sql. Later, bind_params() will detect the value array and
+ // perform the needed modifications to allow the query to work. Note that
+ // 'newfieldtoset' is one arbitrary name that hopefully won't be used ever
+ // in order to avoid problems where the same field is used both in the set clause and in
+ // the conditions. This was breaking badly in drivers using NAMED params like oci.
+ $params['newfieldtoset'] = array($newfield => $newvalue);
+ $newsql = "$newfield = :newfieldtoset";
}
$sql = "UPDATE {" . $table . "} SET $newsql $select";
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);