Error doing db2 insert with PHP parameterized query - php

I'm trying to run a db2 parameterized query in PHP and upon the execution of the insert, I get the error:
Invalid parameter number., SQL state S1002 in SQLDescribeParameter
This is my script:
$getItems = "
SELECT
ID,
EXPIRATION_TIMESTAMP
FROM table1
";
$stmt = odbc_exec($DB2connDEV, $getItems);
$prepInsert = odbc_prepare($DB2connPROD, "INSERT INTO table2 (originalID, expiration_timestamp) VALUES(?,?)");
while($gettingDevItems = odbc_fetch_array($stmt)){
$rows[] = $gettingDevItems;
}
foreach($rows as $row){
$originalID = $row['ID'];
$expiration_timestamp = $row['EXPIRATION_TIMESTAMP'];
$getIdentity = "SELECT IDENTITY_VAL_LOCAL() AS LASTID FROM SYSIBM.SYSDUMMY1";
$insertTable = odbc_execute($prepInsert, array($originalID, $expiration_timestamp));//error at this line
$insertTable = odbc_exec($DB2connPROD, $getIdentity);
$row = odbc_fetch_array($stmt);
$ret = $row['LASTID'];
}
When I do a var_dump on the array of params, I get this:
array(2) {
[0]=>string(1) "2"
[1]=>string(26) "2019-10-03 00:00:00.000000"
}
What am I doing wrong here? Even if I take one value out to only insert one or the other I still get it, so It's not specific to one column.

Maybe odbc can't support reuse of prepared statement, or your driver, or other part of your code, or another thing.
Anyway, move the prepared statement inside your foreach loop to make sure you will rebuild it:
foreach($rows as $row){
$prepInsert = odbc_prepare($DB2connPROD, "INSERT INTO table2 (originalID, expiration_timestamp) VALUES(?,?)");
...

Related

pg_prepare and pg_fetch_object

I am preparing a statement in php using the postgres extension.
Then I try to fetch the result as an object using pg_fetch_object.
No rows returned, from the prepared statement but it should.
I also get the following warning:
Warning: pg_prepare(): Query failed: ERROR: prepared statement "parking" already exists in C:\xampp\htdocs\map\MapMarkers.php on line 33
$devices_query = pg_query($conn, "SELECT applications.name category, devices.* FROM app_as.application applications, app_as.device devices WHERE applications.id = devices.application_id");
//variables are bound in the loop
$parking_pst = pg_prepare($conn, "parking", "SELECT distinct on (name) name,application_name,longitude,latitude,parking_car_status status,received_at FROM V_DEVICE_PARKING WHERE name = $1");
while ($devices = pg_fetch_object($devices_query)) {
pg_execute($conn, "parking",[$devices->name]);
while ($parking = pg_fetch_object($parking_pst)) {
$devices->parking_car_status = $parking->parking_car_status;
}
$data['DEVICES'][] = $devices;
}
You're getting this error/warning because you are calling pg_fetch_object() on the pg_prepare() call. Essentially, every time you iterate in the while() loop, you are calling pg_prepare() again, inadvertently trying to create a new prepared statement called "parking."
What you really mean to do is to get the result of pg_execute() and then pull the results with pg_fetch_object():
$devices_query = pg_query($conn, "SELECT applications.name category, devices.* FROM app_as.application applications, app_as.device devices WHERE applications.id = devices.application_id");
$prepare_result = pg_prepare($conn, "parking", "SELECT distinct on (name) name,application_name,longitude,latitude,parking_car_status status,received_at FROM V_DEVICE_PARKING WHERE name = $1");
// Maybe process $prepare_result as needed here
while ($devices = pg_fetch_object($devices_query)) {
$execute_result = pg_execute($conn, "parking", [$devices->name]);
while ($parking = pg_fetch_object($execute_result)) {
$devices->parking_car_status = $parking->parking_car_status;
}
$data['DEVICES'][] = $devices;
}

PHP PDO Query isn't reading bind values

So I'm trying to execute the following sql query:
$stmt = $connect->query("SELECT `FID`,`StorageID`,`DestructionDate` FROM `files` WHERE `DestructionDate` < ':date'");
$stmt->bindValue(":date",$date);
$stmt->execute();
while ($row = $stmt->fetch()) {
$fid = $row['FID'];
echo $fid . " ";
}
The above code will return all records from files, it simply ignores the WHERE statement at all, and just to be clear, when I run the same statement on phpMyAdmin it runs just fine, in fact I even tried binding the value inside the query itself like this
$stmt = $connect->query("SELECT FID,StorageID,DestructionDate FROM files WHERE DestructionDate < '$date'");
And the query was executed correctly and only gave me the records that satisfy the WHERE condition, so the error is definitely in the bindValue() and execute() lines.
From docs:
PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object
You possibly want PDO::prepare() followed by PDOStatement::execute(). (There's normally no need to painfully bind params one by one.)
Additionally, you have bogus quotes around the placeholder:
':date'
You'll note that as soon as you execute the statement because params won't match.
2 solutions :
First:
$stmt = $connect->prepare("SELECT `FID`,`StorageID`,`DestructionDate` FROM `files` WHERE `DestructionDate` < :date");
$stmt->execute(array('date' => $date);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
Second:
$stmt = $connect->prepare("SELECT `FID`,`StorageID`,`DestructionDate` FROM `files` WHERE `DestructionDate` < ?");
$stmt->execute(array($date));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
In both cases, you don't need to 'quote' the string to be replaced (:date or ?) because PDO parse the value in the right type corresponding to the column to match.

store sql statement in MySQL then run it

Is it possible to store the following SQL statement in MySQL then run it in a prepared statement?
Mysql table:
Table name: mystatements
Columns:id, statements
The following syntax is stored in the statements field:
SELECT id, AES_DECRYPT(secret,'$key') as txtsecret
FROM TABLE_1
Now in php:
first: I do a select query to get my statement
$stmt = $mysqli->prepare("SELECT statements FROM mystatements limit 1");
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$statement.=$row['txtstatement'];
}
second: using the variable ($statement) from the the query above and add it to query below to run the in the prepared statement:
$key='password123';
$stmt = $mysqli->prepare($statement);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['txtsecret'];
}
Also my stored syntax contains AES_DECRYPT(secret,'$key') just to complicate things. is what i'm trying to achieve possible? have I gone about this completely the wrong way?
Ok..
$key='password123';
$sql = str_replace('$key', $key, $statement); //replace $key to correct value
$stmt = $mysqli->prepare($sql);
Result:
SELECT id, AES_DECRYPT(secret,'$key') as txtsecret FROM TABLE_1
to
SELECT id, AES_DECRYPT(secret,'password123') as txtsecret FROM TABLE_1

How to keep temporary mysqli table available in php during statement execution?

I am busy trying to execute a set of statements that involve the use of a temporary table.
My goal is to create the temporary table, insert values to it and then do a like comparison of the temporary tables contents to another table.
These statements are working perfectly in phpmyadmin when executed from RAW SQL, but I'm assuming that the table is not available when I try to insert the data.
Below is the code for my php function + mysqli execution:
function SearchArticles($Tags){
global $DBConn, $StatusCode;
$count = 0;
$tagCount = count($Tags);
$selectText = "";
$result_array = array();
$article_array = array();
foreach($Tags as $tag){
if($count == 0){
$selectText .= "('%".$tag."%')";
}else {
$selectText .= ", ('%".$tag."%')";
}
$count++;
}
$query = "CREATE TEMPORARY TABLE tags (tag VARCHAR(20));";
$stmt = $DBConn->prepare($query);
if($stmt->execute()){
$query2 = "INSERT INTO tags VALUES ?;";
$stmt = $DBConn->prepare($query2);
$stmt->bind_param("s", $selectText);
if($stmt->execute()){
$query3 = "SELECT DISTINCT art.ArticleID FROM article as art JOIN tags as t ON (art.Tags LIKE t.tag);";
$stmt = $DBConn->prepare($query3);
if($stmt->execute()){
$stmt->store_result();
$stmt->bind_result($ArticleID);
if($stmt->num_rows() > 0){
while($stmt->fetch()){
array_push($article_array, array("ArticleID"=>$ArticelID));
}
array_push($result_array, array("Response"=>$article_array));
}else{
array_push($result_array, array("Response"=>$StatusCode->Empty));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
}else{
array_push($result_array, array("Response"=>$StatusCode->SQLError));
}
$stmt->close();
return json_encode($result_array);
}
The first statement executes perfectly, however the second statement gives me the error of:
PHP Fatal error: Call to a member function bind_param() on a non-object
If this is an error to do with the Temp table not existing, how do i preserve this table long enough to run the rest of the statements?
I have tried to use:
$stmt = $DBConn->multi_query(query);
with all the queries in one, but i need to insert data to one query and get data from the SELECT query.
Any help will be appreciated, thank you!
You have a simple syntax error use the brackets around the parameters like this
INSERT INTO tags VALUES (?)
This is not an issue with the temporary table. It should remain throughout the same connection (unless it resets with timeout, not sure about this part).
The error is that $stmt is a non-object. This means that your query was invalid (syntax error), so mysqli refused to create an instance of mysqli_stmt and returned a boolean instead.
Use var_dump($DBConn->error) to see if there are any errors.
Edit: I just noticed that your query $query2 is INSERT INTO tags VALUES ? (the ; is redundant anyway). If this becomes a string "text", this would become INSERT INTO tags VALUES "text". This is a SQL syntax error. You should wrap the ? with (), so it becomes INSERT INTO tags VALUES (?).
In conclusion, change this line:
$query2 = "INSERT INTO tags VALUES ?;";
to:
$query2 = "INSERT INTO tags VALUES (?);";
also note that you don't need the ; to terminate SQL statements passed into mysqli::prepare.

Multiple prepared statements (SELECT)

I'm trying to change my SQL queries with prepared statements.
The idea: I'm getting multiple records out of the database with a while loop and then some additional data from the database in the loop.
This is my old SQL code (simplified):
$qry = "SELECT postId,title,userid from post WHERE id='$id'";
$rst01 = mysqli_query($mysqli, $qry01);
// loop trough mutiple results/records
while (list($postId,$title,$userid) = mysqli_fetch_array($rst01)) {
// second query to select additional data
$query05 = "SELECT name FROM users WHERE id='$userid";
$result05 = mysqli_query($mysqli, $query05);
$row05 = mysqli_fetch_array($result05);
$name = $row05[name ];
echo "Name: ".$name;
// do more stuff
// end of while loop
}
Now I want to rewrite this with prepared statements.
My question: is it possible to run a prepared statement in the fetch of another prepared statement ? I still need the name like in the old SQL code I do for the $name.
This is what've written so far.
$stmt0 = $mysqli->stmt_init();
$stmt0->prepare("SELECT postId,title,userid from post WHERE id=?");
$stmt0->bind_param('i', $id);
$stmt0->execute();
$stmt0->bind_result($postId,$title,$userid);
// prepare second statement
$stmt1 = $mysqli->stmt_init();
$stmt1->prepare("SELECT name FROM users WHERE id= ?");
while($stmt0->fetch()) {
$stmt1->bind_param('i', $userid);
$stmt1->execute();
$res1 = $stmt1->get_result();
$row1 = $res1->fetch_assoc();
echo "Name: ".$row1['name'] ;
}
It returns an error for the second statement in the loop:
Warning: mysqli_stmt::bind_param(): invalid object or resource mysqli_stmt in ...
If I use the old method for the loop and just the prepared statement to fetch the $name it works.
You can actually do this with a single JOINed query:
SELECT p.postId, p.title, p.userid, u.name AS username
FROM post p
JOIN users u ON u.id = p.userid
WHERE p.id = ?
In general, if you are running a query in a loop, there is probably a better way of doing it.

Categories