I have a method that does Insert
and Updates
in PHP to a Database MySQL
using PDO.
In this case, the structure of the tables is not relevant since if the query does not meet the minimally necessary data of each column, the Script will perform a roleback of the insert.
This Script has a serious error and it is that it executes the insert and update from a query string armed as plain text .
What does the method receive?
Note: these queries are an example, they are not always the same or similar, they may vary depending on the scenario, the data may also change; but the theory is that an insert or update query string is always received.
Currently one array
with the following example structure:
$dbquery =[
'DB1'=>[
'0' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value11,value21,value31)',
'1' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value21,value22,value23)',
'2' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value31,value32,value33)',
],
'DB2'=>[
'0' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value41,value42,value43)',
'1' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value51,value52,value53)',
'2' =>'INSERT INTO table_name(column1,column2,column3) VALUES (value61,value62,value63)',
],
];
The Script Used is this:
Which takes the example structure and goes through it... exchanging databases, tables and executing each Query (Insert, Update) to finally perform a commit:
public function SetData($Query, $Conf = [])
{
try {
$conn = $this->DataBaseConnection($this->CheckServerSwitch($Conf)); //establece la conexion
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->beginTransaction();
$conn->exec("set names utf8");
foreach ($Query as $DB_2USE => $QArr) {
$conn->exec('USE ' . $DB_2USE);
foreach ($QArr as $key => $QString) {
$cQ = $conn->exec($QString); //ejecuta el query
if ($this->CheckIfStartWith(['str' => $QString, 'beg' => 'UPDATE'])) { //valida si es un Update
$count['u'] = $count['u'] + $cQ;
}
if ($this->CheckIfStartWith(['str' => $QString, 'beg' => 'INSERT'])) { //valida si es un Insert
$count['i'] = $count['i'] + $cQ;
}
++$cT;
}
}
if (0 != $count['i']) {
$smgINS_TXT = 'Registros Insertados: ' . $count['i'] . '<br>';
}
if (0 != $count['u']) {
$smgUPD_TXT = 'Registros Actualizados: ' . $count['u'];
}
$conn->commit();
return $smgINS_TXT . $smgUPD_TXT;
} catch (PDOException $e) {
$conn->rollback();
return ['error'=>true, 'type'=>6, 'obj'=>$e]
}
}
Questions and doubts:
In the research carried out, the examples I find Examples that implement bind (bindValue, bindParam) use a single insert, but in my scenario I am trying to insert/update several records, so that at the end I can do the commit and if there is an error I do rollback and avoid badly inserted data... but I'm not implementing bind ...
How is the implementation of Bind
when the scenario is the one I present?
I know that I should start by changing my array to something like this:
$dbquery =[
'DB1'=>[
'0' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value11,
'column2'=>value12,
'column3'=>value13,
],
'1' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value21,
'column2'=>value22,
'column3'=>value23,
],
'2' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value31,
'column2'=>value32,
'column3'=>value33,
],
],
'DB2'=>[
'0' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value41,
'column2'=>value42,
'column3'=>value43,
],
'1' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value51,
'column2'=>value52,
'column3'=>value53,
],
'2' =>[
'query' => 'INSERT INTO table_name(column1,column2,column3) VALUES (?,?,?)',
'column1'=>value61,
'column2'=>value62,
'column3'=>value63,
],
],
];
Another example of the Array but with different nodes:
$dbquery =[
'DB1'=>[
'0' =>[
'query' => 'INSERT INTO table_name_1(column1,column2) VALUES (?,?)',
'column1'=>value11,
'column2'=>value12,
],
'1' =>[
'query' => 'INSERT INTO table_name_2(column1,column2,column3,column4) VALUES (?,?,?,?)',
'column1'=>value21,
'column2'=>value22,
'column3'=>value23,
'column4'=>value24,
],
],
];
but what changes should I make to my script (if refactoring)?
seeking is found
Documentation:
it is simply necessary to nest in a foreach that analyzes the values and does the bind value... it was necessary to re-organize the code so that the script has the expected scope.
https://www.php.net/manual/en/pdo.begintransaction.php#90239
Based on the Structure proposed in the Question:
The script would look like this: