How to execute multiple queries using PDO for Sql Server - php

I'd like to execute some queries that doesn't return result set, and then execute a real query, and fetch its result.
Here is an exemple that doesn't work :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1;";
$db->exec($query);
$query = "select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
This code neither doesn't work :
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1; select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
But this code works :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "select 1;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
Thanks for your help

I know this is old, but for other people finding this from Google: you need to use PDOStatement::nextRowset to iterate over the result sets from your multiple queries.
However, it seems there are memory issues when using nextRowset with dblib in some versions (it tried to allocate 94Tb in my case...), so I ended up re-engineering to avoid multiple SQL queries altogether (instead duplicating the value of the DECLARE where it was being used).

PDO::query docs (http://php.net/manual/it/pdo.query.php) say
PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.
This could mean that you can execute with query() both queries with and without result

Related

Two PDO sql statements/Using fetched data for the second statement

So I'm new to PHP/PDO and I'm having some problems with passing the fetched variable on to the second statement. I'm also having problems with exceptions i don't know how the right structure for this situation.
try {
$connection->beginTransaction();
$stmt = $connection->prepare("CALL sproc_patient_profile_physical_exam_hdr(?,?,?)");
$stmt->bindValue(1,$casenumber_fetch,PDO::PARAM_INT);
$stmt->bindValue(2,$patientid_val,PDO::PARAM_INT);
$stmt->bindValue(3,$enteredby,PDO::PARAM_STR);
while($row = $stmt->fetch()){
echo $physicalexamid_insert=$row['physicalexamid'];
/* I need to use this data for another try and catch or sql statements for example*/
$count_physical_exam_id = count($physical_exam_id);
for ($x=0; $x < $count_physical_exam_id; $x++) {
if (!(empty($physical_exam_id[$x]))) {
try {
$connection->beginTransaction();
$stmt = $connection->prepare("CALL sproc_patient_profile_physical_exam_dtl(?,?,?,?,?,?,?)");
$stmt->bindValue(1,$casenumber_fetch,PDO::PARAM_INT);
$stmt->bindValue(2,1,PDO::PARAM_INT);
$stmt->bindValue(3,$physical_exam_id[$x],PDO::PARAM_INT);
$stmt->bindValue(4,$physical_exam_desc[$x],PDO::PARAM_STR);
$stmt->bindValue(5,$normal[$x],PDO::PARAM_INT);
$stmt->bindValue(6,$undone[$x],PDO::PARAM_INT);
$stmt->bindValue(7,$specific[$x],PDO::PARAM_INT);
$stmt->execute();
$connection->commit();
} catch(PDOException $ex) {
//$connection->rollBack();
echo $ex->getMessage();
}
}
}
}
$stmt->execute();
$connection->commit();
} catch(PDOException $ex) {
$connection->rollBack();
echo $ex->getMessage();
Can someone help me with this? Thanks.
There's a couple of issues with your code:
You're not executing the first statement before you call fetch on it.
You're over-writing the $stmt variable in your loop.
The opening section of your code should be like this:
$stmt = $connection->prepare("CALL sproc_patient_profile_physical_exam_hdr(?,?,?)");
$stmt->bindValue(1,$casenumber_fetch,PDO::PARAM_INT);
$stmt->bindValue(2,$patientid_val,PDO::PARAM_INT);
$stmt->bindValue(3,$enteredby,PDO::PARAM_STR);
$stmt->execute();
Once you've done that you can loop through with a control statement like you're doing (e.g. while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { ... }).
Inside that control structure, instead of using the variable $stmt for a new (second) statement, use something like $stmt2 or $inner_stmt, so that you don't over-write the outer variable.

How to know when a MS SQL query returns a RAISERROR in PHP?

I've though that this would work but nothing :(
$sql = "RAISERROR('Error.', 16, 1)";
$rs = $conn->query($sql);
if (!$rs) echo 'Error.';
What I need it's just a way to know that this query has an error.
I tried this too:
try {
$rs = $conn->query($sql);
} catch (Exception $e) {
echo 'Error';
}
Ps. I do have this in the connection:
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

PDO: unbufferred queries error

I understand that this error is generated by a cursor being left open (not consuming all data). However, I thought I had suitably accounted for this by explicitly closing the cursor in my function. Nonetheless I am getting the error message
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while
other unbuffered queries are active.
Specifically this is being triggered when $setting ==0.
What am I doing wrong?
<?php function selector($dbh, $selectString, &$callnumber, $setting)
{
$callnumber++;
try{
$sth = $dbh->prepare($selectString);
$sth->execute();
if ($setting==0){
$results = $sth->fetch(PDO::FETCH_ASSOC);
$sth->closeCursor();
return $results;
}
else if ($setting==1){
$moduleselect = array();
while ($results = $sth->fetch(PDO::FETCH_ASSOC)) {
$moduleselect[] = $results;
$sth->closeCursor();
}
return $moduleselect;
}
}
catch (PDOException $e) {
echo($e->getMessage());
echo ("ref= ".$callnumber);
$dhh=null;
die();
}
}
?>

Sqlite PDO query returns no results

Getting no results no matter how broad my query
PHP: 5.3
Sqlite3: 3.6
PDO: 5.3.3
I would think this should be a very simple process but even looking around I still don't know why I'm getting 0 results. Here is my code:
<?php
$sqlite = new PDO('sqlite:/example.db');
$result = $sqlite->query('SELECT * from foo');
if(!$result)
{
echo 'fail';
return false;
}
?>
Any ideas on what I am doing wrong? The 'foo' table will only have four columns, and this test db only has one table. Running the query in sqlite displays the results fine.
You have to execute the statement first than fetch the result.
You might add try/catch block around the execute method call. and do some error handling.
Here's an example of catching an Exception. Do not use it as a design guideline.
<?php
try
{
$sqlite = new PDO('sqlite:/example.db');
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
$statement = $sqlite->prepare('SELECT * from foo');
try
{
$statement->execute();
}
catch(PDOException $e)
{
echo "Statement failed: " . $e->getMessage();
return false;
}
$result = $statement->fetchAll();
var_dump($result);
?>

How can I use prepared statements combined with Transactions with PHP?

My goal is to use a transaction and a prepared statement simultaneously, to achieve both integrity of data, and prevention of SQL injection.
I have this:
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$cnx->query("SELECT * FROM users WHERE username=$escaped_input");
$cnx->query("SELECT * FROM othertable WHERE some_column=$escaped_input_2");
$cnx->commit();
}
catch (Exception $e){
$cxn->rollback();
echo "an error has occured";
}
I would like to incorporate the query as one would with a prepared statement:
$stmt=$cxn->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($user_input));
$stmt_2=$cxn->prepare("SELECT * FROM othertable WHERE some_column=?");
$stmt_2->execute(array($user_input_2));
How can I achieve that?
Edit
I get this error:
PHP Parse error: syntax error, unexpected T_CATCH
Here is my updated code:
try
{
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cnx->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($username));
$cnx->commit();
while ($row=$stmt->fetch(PDO::FETCH_OBJ)){
echo $stmt->userid;
}
catch(Exception $e) {
if (isset($cnx))
$cnx->rollback();
echo "Error: " . $e;
}
Just call "execute" after you call "beginTransaction".
Where you call "prepare" doesn't really matter.
Here's a complete example:
http://php.net/manual/en/pdo.begintransaction.php
EXAMPLE:
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cxn->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($user_input));
$stmt_2=$cxn->prepare("SELECT * FROM othertable WHERE some_column=?");
$stmt_2->execute(array($user_input_2));
$cnx->commit();
}
catch (Exception $e){
$cxn->rollback();
echo "an error has occurred";
}
PS:
1) I'm assuming, of course, that $user_input and $user_input_2 are available immediately. You don't want your transaction hanging open unnecessarily long ;)
2) Based on your comment reply above, I think you might be confusing "execute" and "begin tran/commit". Please look at my link.
3) Do you even need a transaction? You're just doing two "select's".
4) Finally, why not do one "join" (or union, if compatible) instead of two "select's"?
try
{
$cnx = new PDO ($dsn,$dbuser,$dbpass);
$cnx->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction ();
$stmt = $cnx->prepare ("SELECT * FROM users WHERE username=?");
$stmt->execute(array($username));
$cnx->commit();
while ($row = $stmt->fetch (PDO::FETCH_OBJ)){
echo $row->userid;
}
}
catch (Exception $e) {
if (isset ($cnx))
$cnx->rollback ();
echo "Error: " . $e;
}
}
Did you mean this?
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cnx->prepare("
SELECT * FROM users, othertable
WHERE users.username=?
AND othertable.some_column=?");
$stmt->execute(array($user_input,$user_input_2));
$cnx->commit();
}
catch (Exception $e){
$cnx->rollback();
echo "an error has occured";
}
That is assuming that the two tables data does not have duplicate field names, otherwise you're going to have to use:
SELECT users.field1 as u_field1, othertable.field1 as o_field1 FROM users, othertable
WHERE users.username=?
AND othertable.some_column=?

Categories