db2_prepare(): Statement Prepare Failed when binding parameter - php

I am trying to prepare a statement for a table function on a DB2 on iSeries, but I'm getting a db2_prepare() warning. When I insert the parameter value directly into the SQL statement, it works fine.
Here is what I'm trying to prepare:
$sql = 'SELECT U8.VALIDUSER(?) '
. 'FROM SYSIBM.SYSDUMMY1';
$stmt = db2_prepare($this->conn, $sql);
db2_bind_param($stmt, 1, 'userID', DB2_PARAM_IN);
PHP returns: Warning: db2_prepare(): Statement Prepare Failed in... for the db2_prepare() line.
If I change it to this, it works:
$sql = 'SELECT U8.VALIDUSER(\'' . $userID . '\') '
. 'FROM SYSIBM.SYSDUMMY1';
$stmt = db2_prepare($this->conn, $sql);
Why does it fail when I bind the parameter, but works when I insert it directly? I naturally want to bind the parameter so I don't have to add unnecessary sanitization for this one situation.
Is there something I'm missing?

As mentioned in the comment, I'm guessing that your problem is that DB2 cannot determine what type your parameter is when it's doing the binding. If you add a CAST around the parameter to tell DB2 what type you are passing, it should work.
I'm not sure if PHP has an option, but in C#, you can pass in the type when defining the parameter, so that might be an option, if it's available, instead of hard-coding the type in SQL.
Check out this other answer I have about how to fetch the "native" DB2 errors, which are likely much more helpful than the ones thrown by PHP. I also have another answer about SQL0418N, which is probably the actual error you would have received if you were looking at the native error.

Related

PHP PDO UPDATE statement with subquery

I'm trying to create a query using PDO, where the query includes a subquery. The code isn't working. Using the workbench, I can do the query and it does perform.
I feel like there is nuance here when it comes to deriving a table while using PDO.
$turn = 1;
$phase = -1;
$status = "waiting";
$gameid = 1;
$stmt = $this->connection->prepare("
UPDATE playerstatus
SET
turn = :turn,
phase = :phase,
status = :status,
value = value + (SELECT reinforce FROM games where id = :gameid)
WHERE
gameid = :gameid
");
$stmt->bindParam(":turn", $turn);
$stmt->bindParam(":phase", $phase);
$stmt->bindParam(":status", $status);
$stmt->bindParam(":gameid", $gameid);
$stmt->execute();
I tried a multitude of adjustments, it simply fails upon executing.
EDIT error:
Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number
A known (but not well documented) limitation with PDO named placholders: the same bind placeholder can't be used more than one time in a statement. Workaround is to use distinct bind placeholder names.
(This limitation in PDO may have been addressed in a later versions(?). I think the root cause is that "behind the scenes", PDO is replacing the named placeholders with positional notation question marks. This problem is not restricted to just UPDATE statements, this same problem plagues all PDO SQL statements using named placeholders.)
Also, not related to the problem, I recommend using bindValue in place of bindParam.
Change the bind placeholder name to be distinct/unique. Shown here, changing one of the occurrences of :gameid to :gameid2
value = value + (SELECT reinforce FROM games where id = :gameid)
WHERE
gameid = :gameid2
^
And we need to supply a value for each bind placeholder. Which means we need to add another line. With bindValue, we can reference the same variable without needing make a copy of it.
$stmt->bindValue(":gameid", $gameid);
$stmt->bindValue(":gameid2", $gameid);
^

mysqli_prepare() returning NULL because it does not recognize the '?'

I have the following code.
` $db = mysqli_connect('localhost', 'zyk', 'nuithadit6-6-6', 'phpAdv');
if ( mysqli_connect_errno() )
{
printf("Connect failed: %s\n", mysqli_connect_errno() );
exit();
}
$thisDB = mysqli_prepare($db, "CREATE DATABASE ?");
echo mysqli_stmt_error($thisDB);;`
When running this code, I get the following warning:
PHP Warning: mysqli_stmt_error() expects parameter 1 to be mysqli_stmt, boolean given in /Library/WebServer/Documents/phpAdvanced/cap1/createDB.php on line 13.
If I change the second parameter to the mysqli_prepare function to the following:
"CREATE DATABASE myDB"
then the Warning goes away. It seems that mysqli_prepare does not like it when the query string has variables in it, and it returns NULL for $thisDB when I use it in this way. As far as I understand, this is NOT the expected behavior.
I've been reading on the manuals and forums, and still no answer yet. Does anybody knows why the mysqli_prepare is not returning the appropriate value?
The version of mysqli is 5.0.8, and my version of php is 5.3.15.
Prepared statements do not accept placeholders for anything that is a MySQL identifier. This includes database, table and column names. You should simply concatenate a sanitised version of your table name to your statement and use mysqli_query().
The reason is this: MySQL will parse a prepared statement and prepare a complete execution plan when you prepare it. This includes which tables it will use, which indexes, and how it will select from the columns. When you execute the statement it substitutes the variable data into the execution plan and creates a result.
If you try and prepare a statement including a MySQL entity like a table as an unknown, MySQl is unable to create the execution plan.

concatenate mysql select query with php variable?

I am trying to concatenate a MySQL SELECT query with PHP variable but got an error.
My PHP statement which gives an error is:
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username =".$user."AND password=".$add);
and error as:
( ! ) Notice: Undefined variable: info in C:\wamp\www\pollBook\poll\login.php on line 18
Call Stack
I don't understand where I missed the code.
When I write query without WHERE clause it works fine.
The reason why your code isn't working
You are attempting to use a variable, $info, that has not been defined. When you attempt to use an undefined variable, you're effectively concatenating nothing into a string, however because PHP is loosely typed, it declares the variable the second you reference it. That is why you're seeing a notice and not a fatal error. You should go through your code, and ensure that $info gets a value assigned to it, and that it is not overwritten at some point by another function. However, more importantly, read below.
Stop what you are doing
This is vulnerable to a type of attack called an SQL Injection. I'm not going to tell you how to concatenate SQL strings. It's terrible practice.
You should NOT be using mysql functions in PHP. They are deprecated. Instead use the PHP PDO Object, with prepared statements. Here's a rather good tutorial.
Example
After you've read this tutorial, you'll be able to make a PDO Object, so I'll leave that bit for you.
The next stage is to add your query, using the prepare method:
$PDO->prepare("SELECT * FROM tbl WHERE `id` = :id");
// Loads up the SQL statement. Notice the :id bit.
$actualID = "this is an ID";
$PDO->bindParam(':id', $actualID);
// Bind the value to the parameter in the SQL String.
$PDO->execute();
// This will run the SQL Query for you.
You are missing space before "AND " and you should use single quotes as suggested in other answers.
$result=mysql_query("SELECT user_id,username,add FROM users WHERE *username =".$user."AND* password=".$add);
Updated:
echo $sql = "SELECT user_id,username,add FROM users WHERE username ='".$user."' AND password='".$add."'";
$result=mysql_query($sql);
although there is no $info variable used in the query but you need to correct the query:
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username ='" . $user . "' AND password='" . $add . "'");
First from the error its looks like one of your variables is not defined. .. check it. Second surround your parameters with ' for safer syntax.
This is because the variables you are using might not have defined above
So first initialize your variables or if its coming from somewhere else(POST or GET) then check with isset method
So complete code would be
$user = 123; // or $user = isset($user)?$user:123;
$add = 123456; // or $add = isset($add)?$add:123456;
And then run your query
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username =".$user."AND password=".$add);

PDO PostgreSQL binding error

I found that when I'm trying to run update query with params, I'm getting error
inconsistent types deduced for parameter
Maybe that's because the type of target field (character varying), everything works fine with text column type. But I don't want to change column type only because of this. Then I was told that I should pass params directly (using bindValue or bindParam, determining the type of each value) instead of sending params array to execute method.
But when I do so I'm getting error
ERROR: bind message supplies 0 parameters, but prepared statement
"pdo_stmt_00000001" requires 1
The test code is
$Stmt = $DB->prepare("SELECT * FROM test_table WHERE test_field=:test_field");
$Stmt->bindValue(':test_field', 'test', PDO::PARAM_STR);
$Stmt->execute();
var_dump($DB->errorInfo());
So, as far as understand, binding does not work at all. Or I'm doing it wrong.
But maybe there is a way of solving it?
I'm running PHP 5.4.12 with PostgreSQL 9.2.3, libpq 8.4.16.
Well, it seems that the only solution is to cast all text values to text like this:
update test_table set test_field = :test_field::text
Otherwise error about inconsistent types is occurring.
I do it this way:
$stmt = $DB->prepare("SELECT * FROM test_table WHERE test_field=:test_field");
$stmt->execute(array(":test_field" => 'test'));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if($result)
{
return $result['id'];
// Or whatever you're trying to get.
}
return null;
You just have to throw in an array of parameters in the execute function, no need to add a special line for the binding.
Tell me if it works for you (or not).

2nd MySQLi Query causes a "Call to a member function execute() on a non-object"

I've got a strange problem. There are 2 queries.
$sql = "SELECT `content_auftrag_id`
FROM `content`
WHERE `content_id` = '".$content_id."' LIMIT 1";
$ergebnis = $db->prepare( $sql );
$ergebnis->execute();
$ergebnis->bind_result( $content_auftrag_vorhanden );
$content_auftrag_id = "test";
$sql = "UPDATE `content` SET `content_auftrag_id` = '".$content_auftrag_id."'
WHERE `content_id` = '".$content_id."'";
$ergebnis2 = $db->prepare( $sql );
$ergebnis2->execute();
When I use them both, then an error occurs for the second one. If I only run the the second, then it works fine. How can it be that both together cause an error?
All variables are there and correct.
Thanks!
Okay, I think you didn't quite got the idea behind PreparedStatements. You shouldn't directly insert the parameters in your SQL-String, but use ?-placeholders and bind them in the Query using the bind_param()-method.
Your error seams to appear here:
$ergebnis2 = $db->prepare( $sql );
This function returns false if it wasn't successful. You should check if the value of ergebnis2 is not false.
Also, you should use the error-method to see the last appeared MySQL-Error.
You can only work on one prepared query at a time, so to speak. See Mysqli::execute() method:
"When using mysqli_stmt_execute(), the mysqli_stmt_fetch() function must be used to fetch the data prior to performing any additional queries."
You can also use the store_result() method to remove this block as well to perform the next query.
Also, take heed from those who warn you about abusing prepared statements like your example. Though it works without error if you don't actually have any parameters to bind to, it basically throws sql injection prevention out the window.
If $ergebnis2 is 'not an object', then I guess it must be false. Which means the prepare() call failed for whatever reason.
What does $db->error return after you have called the 2nd prepare?
Always check your return values, its basic debugging

Categories