PHP Inserting array values into MySQL prepared statement - php

I have an array of values that I am trying to insert into a database. Currently the below only inserts the first key value pair in the array and then returns an error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error' in /_/components/php/functions.php:33
Stack trace:
0 /_/components/php/functions.php(33): PDOStatement->fetchAll()
1 /testdb.php(44): Photo\DB\query('INSERT into cat...', Array, Object(PDO))
2 {main} thrown in /_/components/php/functions.php on line 33
line 33 in functions.php is in this function
function query($query, $bindings, $conn){
$stmt = $conn->prepare($query);
$stmt->execute($bindings);
$results = $stmt->fetchAll(); <---line 33
return $results ? $results : false;
}
The main code is
foreach ($sitecategories as $key => $value) {
// print "this is key $key and this is value $value";
if ( $conn ) {
$catquery=query("INSERT into categories (cat_id, label) VALUES (:catid, :label)",
array('catid'=>$key, 'label'=>$value),
$conn);
} else {
print "could not connect to the database";
}
}
So I am connecting OK to the DB (elsewhere in the code) and the first key value pair is inserted successfully but not the rest of the array. I'm guessing my syntax is incorrect somewhere in
array('catid'=>$key, 'label'=>$value),
but I can't figure it out. Any help much appreciated!

You shouldn't fetchAll() after you INSERT. INSERT has no result set.
I just ran a test of inserting and then calling fetchAll() on the PDOStatement object, and I confirm that this causes the "General error" exception you showed.
$stmt = $dbh->prepare("insert into foo () values ()");
$stmt->execute();
$result = $stmt->fetchAll();
Throws:
PHP Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[HY000]: General error' in /Users/billkarwin/workspace/PHP/21194489.php:14
Stack trace:
#0 /Users/billkarwin/workspace/PHP/21194489.php(14): PDOStatement->fetchAll()
#1 {main}
thrown in /Users/billkarwin/workspace/PHP/21194489.php on line 14

Your array of values is incorrect. The keys need to have the :, too.
array(':catid'=>$key, ':label'=>$value)

Related

PDO::fetchAll not working with MySQL stored procedure

I'm trying to return a row from a database by calling a stored procedure throught PHP. However, when I do this how I normally would I get a "General Error".
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error in C:\xampp\htdocs\Skilaverkefni 4\Courses\read.php:11
Stack trace:
#0 C:\xampp\htdocs\Skilaverkefni 4\Courses\read.php(11): PDOStatement->fetchAll(2)
#1 C:\xampp\htdocs\Skilaverkefni 4\index.php(13): ReadCourse('FOR3L3U')
#2 {main}
thrown in C:\xampp\htdocs\Skilaverkefni 4\Courses\read.php on line 11
Here is the code:
<?php
function ReadCourse($courseID)
{
require "dbCon.php";
$SQL = "SET #p0='" . $courseID . "'; CALL ReadCourse(#p0);";
echo "$SQL";
$logon = $pdo->prepare($SQL);
$logon->execute();
$records = $logon->fetchAll(PDO::FETCH_ASSOC);
print_r($records);
}
?>
After a long Google-session I found out that the issue is most caused by the way I'm handling the reading of the data returned from the stored procedure, how do I do this correctly?
The whole point of PDO is to make it impossible to run any old database query you choose to pass as a string.
From the documentation:
<?php
/* Call a stored procedure with an INOUT parameter */
$colour = 'red';
$sth = $dbh->prepare('CALL puree_fruit(?)');
$sth->bindParam(1, $colour, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 12);
$sth->execute();
print("After pureeing fruit, the colour is: $colour");
?>

Can't select from sys.extended_properties using PHP PDO

When querying a SQL Server database from PHP with this statement:
SELECT [Value] FROM sys.extended_properties WHERE name='MS_Description'
I get this error message:
"Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[IMSSP]: Invalid type.' in C:\inetpub\wwwroot\index.php:104 Stack trace: #0 C:\inetpub\wwwroot\index.php(104): PDOStatement->fetch(2) #1 {main} thrown in C:\inetpub\wwwroot\index.php on line 104"
The php that I'm using is below, line 104 is the start of the While loop:
$sql = "SELECT [Value] FROM sys.extended_properties WHERE name='MS_Description'";
global $pdo;
$qry = $pdo->query($sql);
if (!$qry) {
exit('<pre>' . print_r($qry->errorInfo()));
}
while($row = $qry->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $key => $value) {
echo '<p>Key: ' .$key. ', Value: ' .$value. '</p>';
}
}
The code above works fine when selecting from any other table or view e.g:
SELECT * FROM sys.events
If I execute the statement via SSMS it works fine, any ideas why it doesn't work via PHP?
Casting the columns being selected as varchar(255) solved the problem i.e.
$sql = "SELECT CAST([Value] AS VARCHAR(255)) FROM sys.extended_properties WHERE name='MS_Description'";
Got to the solution based on the answers to this question and this question.

General error: 1843 OCIStmtExecute: ORA-01843: not a valid month (ext\pdo_oci\oci_statement.c:148)'

I am trying to insert to a oracle table using pdo. Its getting an error:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[HY000]: General error: 1843 OCIStmtExecute: ORA-01843: not a
valid month` (ext\pdo_oci\oci_statement.c:148)' in
D:\xampp\htdocs\ipack\insertstatus.php:60 Stack trace: #0
D:\xampp\htdocs\ipack\insertstatus.php(60): PDOStatement->execute() #1
{main} thrown in D:\xampp\htdocs\ipack\insertstatus.php on line 60
This is my code:
$today = date("d-m-Y");
$stmt = $dbh->prepare("INSERT INTO PRTJOBSTATUS (INTJOBNO,SLNO,OPDATE,OPERTYPE,OPUSER,REMARKS,STATUSCODE,STATDATE)
values (:intjn,:sn,:opdt,:optype,:opusr,:rmks,:stcd,:stdt)");
$stmt->bindParam(':intjn',$intjobno);
$stmt->bindParam(':sn',$slno);
$stmt->bindParam(':opdt',$today);
$stmt->bindParam(':optype',$optype);
$stmt->bindParam(':opusr',$opuser);
$stmt->bindParam(':rmks',$remarks);
$stmt->bindParam(':stcd',$statuscode);
$stmt->bindParam(':stdt',$today);
if($stmt->execute()) {
echo '1 row has been inserted';
}
$dbh = null;
You're inserting into a column "STATDATE". I would imagine this will be of type Date. Therefore you'll have to pass a date object into the insert statement.
Change your $today variable to return a string in the following format 'DD-MON-YYYY' eg 31-DEC-2015
Then change your insert statement to the following:
"INSERT INTO PRTJOBSTATUS (INTJOBNO,SLNO,OPDATE,OPERTYPE,OPUSER,REMARKS,STATUSCODE,STATDATE)
values (:intjn,:sn,:opdt,:optype,:opusr,:rmks,:stcd,TO_DATE(:stdt,'DD-MON-YYYY'))"

Inserting data into database with pdo prepared statment

Inserting data into database with pdo prepared statment, doesnt work for me:
I use this function:
public function get_number_of_matches(){
$stmt = $this->pdo->prepare("INSERT INTO `words`( `word_name`, `word_count`, `search_id`) VALUES (:word, :count,:searchID)");
$stmt->bindParam(':word', $word);
$stmt->bindParam(':count', $count);
$stmt->bindParam(':searchID', $search_id);
for($i=0;$i<count($this->words);$i++){
if(preg_match_all('/'.$this->words[$i].'/i', $this->text,$matches)){
$count=count($matches[0]);
$word=$this->words[$i];
$search_id=1;
$stmt->execute();
break;
}
}
return 0;
}
Basically, I try to loop over the values and put them into the database.. no error is given.. nothing goes into the database ..why?
This is how I connect to the database:
class DBConnection {
public static $connect;
public static function connect(){
if(!isset(self::$connect)){
try{
self::$connect=new PDO('mysql:host=localhost;dbname=tweeter', 'root', '');
}catch(Exception $ex){
echo $ex->getMessage();
}
}
return self::$connect;
}
}
UPDATE
Also..see here:
I do the same thing with a different query..but when I try to put object properties inside a variable I get an error:
$tweet= $tweet->tweet ;
$user=$tweet->tweeter_name;
$link= $tweet->link;
Those variables go into a query:
$pdo= DBConnection::connect();
$stmt = $pdo->prepare("INSERT INTO `tweets`( `tweet`, `tweeter_name`, `link`, `date`, `search_id`) VALUES (:tweet, :tweeter_name, :link, :date, :search_id)");
$stmt->bindParam(':tweet', $tweet);
$stmt->bindParam(':tweeter_name', $user);
$stmt->bindParam(':link', $link);
$stmt->bindParam(':date', $date);
$stmt->bindParam(':search_id', $search_id);
I get errors like this:
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 36
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 37
Notice: Trying to get property of non-object in C:\xampp\htdocs\Twitter\demo.php on line 38
I can print the properties..but when allocating them to those binded variables..the above errors crop up
I get also this:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'tweeter_name' cannot be null' in C:\xampp\htdocs\Twitter\demo.php:40 Stack trace: #0 C:\xampp\htdocs\Twitter\demo.php(40): PDOStatement->execute() #1 {main} thrown in C:\xampp\htdocs\Twitter\demo.php on line 40
I checked instead like this:
$tweet= "111111"; // $tweet->tweet ;
$user= "22222222"; // $tweet->tweeter_name;
$link= "3333333"; // $tweet->link;
$date= "444444";
and it worked..for some reason it hates those object properties ?!?
This should go as input:
RT #OrganicLiveFood: Scientists Warn #EPA Over #Monsanto's #GMO Crop Failures & Dangers #prop37 #labelGMO #yeson37 http://t.co/2XhuVxO8
Doumastic
TweetCaster for iOS
Mon, 19 Nov 2012 20:40:55 +0000
RT #OrganicLiveFood: Scientists Warn #EPA Over #Monsanto's #GMO Crop Failures & Dangers #prop37 #labelGMO #yeson37 http://t.co/2XhuVxO8
But it doesnt...?!?
Add self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after connecting.
It would make sure PDO will throw PDOExceptions on every error, making them very easy to see. The error would then outline exactly what's wrong.
Check the return value from $stmt->execute(), if there was a problem it will return false and you should check $stmt->errorInfo() for details.
Or else use the ERRMODE_EXCEPTION that #Madara Uchiha suggests, but if you're not already handling exceptions in your application, this can be hard to adapt to.
Re: your update.
You should check error status from both PDO::prepare() and PDOStatement::execute() every time you call them. The error about "Trying to get property of non-object" likely means that $stmt is actually the boolean value false instead of a valid PDOStatement object. Your call to $stmt->bindParam() fails because false is not an object, so it cannot have a bindParam() method.
In my opinion it's much easier to pass parameters by value instead of binding variables by reference. Here's an example of both error-checking and parameters by value:
$pdo = DBConnection::connect();
$sql = "INSERT INTO `tweets`( `tweet`, `tweeter_name`, `link`, `date`, `search_id`)
VALUES (:tweet, :tweeter_name, :link, :date, :search_id)";
if (($stmt = $pdo->prepare($sql)) === false) {
die(print_r($pdo->errorInfo(), true));
}
$params = array(
':tweet' => $tweet,
':tweeter_name' => $user,
':link' => $link,
':date' => $date,
':search_id' => $search_id
);
if (($status = $stmt->execute($params) === false) {
die(print_r($stmt->errorInfo(), true));
}
The error "Column 'tweeter_name' cannot be null'" that you saw in the exception means that your tweeter_name column is declared NOT NULL, but your $user variable had no value when you bound it to the :tweeter_name parameter.

Calling a function/procedure present inside an Oracle package from PHP

I am working with PHP-PDO and Oracle 11g. I am working with Oracle packages which have many functions and stored procedures. Now when I make a call to one of the functions from sql*plus or sql developer IDE, I run this command to get the result set.
select package_name.function_name(param1,param2) from dual
It works fine and returns my result set. Now when I do the same, I am getting errors from the PDO Exception handling. The code with on PHP end looks like this,
$stmt = "select package_name.function_name (?,?) from dual";
$res = $this->ConnOBJ->prepare($stmt);
$param1 = '1';
$param2 = null;
$result->bindParam(1,$param1);
$result->bindParam(2,$param2);
$result->execute();
And I get back an exception which is being logged into my log file.
Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 904 OCIStmtExecute: ORA-00904: "PACKAGE_NAME"."FUNCTION_NAME"": invalid identifier (/var/www/php-5.3.3/ext/pdo_oci/oci_statement.c:146)' in /opt/web/dir/ora_class.php:209 Stack trace: #0 /opt/web/dir/ora_class.php(209): PDOStatement->execute() #1 /opt/web/dir/ora_class.php(298): dbPDO->execPackage() #2 {main} thrown in /opt/web/dir/ora_class.php on line 209
Am I passing the query in a wrong way? Or am I binding the parameters in a wrong way?
Update
I have now got the data going through to Oracle, and have found how to pass null values. My code now is
$stmt = "select package_name.function_name(?,?) from dual";
$res = $this->ConnOBJ->prepare($stmt);
$param1 = 1;
$param2 = null;
$res->bindParam(1,$param1,PDO::PARAM_INT);
$res->bindParam(2,$param2,PDO::PARAM_NULL);
$res->execute();
var_dump($res->fetchAll());
And now when I pass data, I get back the error
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 932 OCIStmtFetch: ORA-00932: inconsistent datatypes: expected CHAR got DTYCWD (/var/www/php-5.3.3/ext/pdo_oci/oci_statement.c:467)' in /opt/web/dir/ora_class.php:216 Stack trace: #0 /opt/web/dir/ora_class.php(216): PDOStatement->fetchAll() #1 /opt/web/dir/ora_class.php(305): dbPDO->execPackage() #2 {main} thrown in /opt/web/dir/ora_class.php on line 216
I am making sure all the types are right, but I still am getting back the same error. I even removed the null value and passed in a string, and changed the pdo type to PDO::PARAM_STR, but it still gives me the error.
Does the function take one parameter or two? In SQL*Plus, you're passing two parameters. In PHP, you're passing only one. If the function requires two parameters and there is no overloaded method that takes only one parameter, you'd get this error.
I am not using PDO anymore, I would be using OCI drivers. Thank you for all the help.
Here is a link to an answer for a similar question [LINK] : https://stackoverflow.com/a/57558306/7897970
or best
//Your connection details
$conn = oci_connect($username, $password, '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))' );
/* Your query string; you can use oci_bind_by_name to bind parameters or just pass the variable in it*/
$query = "begin :cur := functionName('".$param1."','".$param2."','".$param3."'); end;";
$stid = oci_parse($conn, $query);
$OUTPUT_CUR = oci_new_cursor($conn);
oci_bind_by_name($stid, ':cur', $OUTPUT_CUR, -1, OCI_B_CURSOR);
oci_execute($stid);
oci_execute($OUTPUT_CUR);
oci_fetch_all($OUTPUT_CUR, $res);
// To get your result
var_dump($res);

Categories