Getting output of MS stored procedure on php call - php

I am using the sqlsrv ms drivers for php, which work fine (tested with normal queries). I have also tested it with running a stored procedure to update a table data, which also works.
Now I want to use it to run a stored procedure, and I want to retrieve the response. How can this be done?
$server = "...the server address...";
$options = array("UID"=>"...the username...","PWD"=>"...the password...",
"Database" => "...the database..."
);
$conn = sqlsrv_connect($server, $options);
if ($conn === false) {die("<pre>".print_r(sqlsrv_errors(), true));}
$tsql_callSP = "{call ...the stored proc...( ?, ?)}";
$params = array(
array("...first value in...", SQLSRV_PARAM_IN),
array("...second value in...", SQLSRV_PARAM_IN)
);
$stmt3 = sqlsrv_query( $conn, $tsql_callSP, $params);
if( $stmt3 === false )
{
echo "Error in executing statement 3.\n";
die( print_r( sqlsrv_errors(), true));
}
print_r( $stmt3); //attempting to print the return but all i get is Resource id #3
echo "test echo";
sqlsrv_free_stmt( $stmt3);
sqlsrv_close( $conn);
I know that I can use an output parameter, but I will always receive multiple values from the stored proc.

Supposing that the stored procedure is returning the contents of one table with a single SELECT statement, using its output should be as simple as using the result of sqlsrv_query as you would any other selection query result (i.e. using sqlsrv_fetch_object/array on the result)!
So the stored proc could look something like this:
CREATE STORED PROCEDURE test
AS
-- do some other stuff here
-- ...
SELECT * FROM test
GO
And in your php:
// establish db connection, initialize
// ...
$sql = "{call test}"
$result = sqlsrv_query($conn, $sql);
while (sqlsrv_fetch_object($result))
{
// do something with the data
// ...
}

You need to call sqlsrv_fetch() and sqlsrv_get_field() to get data from the returned statement.
From the example code in the manual for sqlsrv_get_field:
$stmt = sqlsrv_query( $conn, $tsql);
if( $stmt === false )
{
echo "Error in statement preparation/execution.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Make the first row of the result set available for reading. */
if( sqlsrv_fetch( $stmt ) === false )
{
echo "Error in retrieving row.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Note: Fields must be accessed in order.
Get the first field of the row. Note that no return type is
specified. Data will be returned as a string, the default for
a field of type nvarchar.*/
$name = sqlsrv_get_field( $stmt, 0);
echo "$name: ";
Beyond that, I am not sure when you say you will receive multiple values whether you mean there will be multiple fields in one row (in which case you will want to make more calls to sqlsrv_get_field()), more than one row (in which case you will have to use a while loop with the call to sqlsrv_fetch() in the loop), or more than one result set (in which case you'll want a while loop using sqlsrv_next_result()).

Related

PHP sqlsrv_fetch_array problem && sqlsrv_num_rows -1

a new webserver has been stood up for me. It is Ubuntu 20.04 and has PHP 7.4.3 on it. I am working with MS SQL Server 2012. I can send my SQL query to the DB server and see it in SQL Server Profiler. I can copy it from the profiler and it runs fine in SQL Management Studio but, I am having a problem when I try to echo the results to my page. When I use sqlsrv_num_rows I get -1. Could I get a hand please?
<?php
if(isset($_POST['getPassBtn'])){
#DATABASE LOGIN
include './php/inc/dbLogin/mydb.php';
#FORM POST VARIABLES
$badge = $_POST['empId'];
//$badge = (int)$badge;
#check badge entry for paramiters
if($badge == '' || $badge < 10000 || $badge > 30000){
echo '<br/> ERROR : Invalid Badge Number <br/>';
die();
}
$sql = "USE mydb SET NOCOUNT ON SELECT badgeNumber, userPassword FROM dbo.users WHERE badgeNumber = '$badge' ORDER BY badgeNumber ASC --getTestData.php";
//$sql = "USE toolsMeskwaki SELECT * FROM bingoProgressive.users ORDER BY badgeNumber ASC --getTestData.php";
$params = array();
$options = array( 'Scrollable' => 'buffered');
$stmt = sqlsrv_query( $conn, $sql, $params, $options);
#check if query returns false
if( $stmt === false ) {
die( print_r( sqlsrv_errors(), true));
}else{
echo '<br/> Query sent to SQL Server <br/>';
}
/*
$row_count = sqlsrv_num_rows( $stmt );
if ($row_count === false){
echo "Error in retrieveing row count.";
}else{
echo $row_count;
}
*/
#Fetching Data by array
while($row = sqlsrv_fetch_array($stmt)){
echo 'badgeNumber '.$row['badgeNumber'];
echo 'userPassword '.$row['userPassword'];
}
#release query
sqlsrv_free_stmt($stmt);
#CLOSE DATA BASE CONNECTION
sqlsrv_close($conn);
echo "<br/> SQL Server Connection closed.<br />";
}else{
echo '<br/> click GET btn to connect SQL Server <br/>';
}
?>
You're submitting three different statements:
USE mydb
SET NOCOUNT ON
SELECT badgeNumber, userPassword FROM dbo.users WHERE badgeNumber = '$badge' ORDER BY badgeNumber ASC
It works in SQL Management Studio for two reasons:
Auto-magic statement detection, although deprecated for several years (you're now expected to use ; as delimiter), is still supported.
The query tool is specifically designed to run several statements at once.
We know that sqlsrv_query() supports it because it isn't returning false. But, given that you're running three statements, you need you use sqlsrv_next_result() twice to move to the third result set.
On a side note:
You can use sqlsrv_connect() to provide the initial database. You only need to switch DBs if you use several of them and you don't want to add the name as mydb.dbo.users.
SQLSRV supports prepared statements (see sqlsrv_prepare() and sqlsrv_execute()).

varchar Output value not returning from sql server in php

I have a php file which executes a sql server stored procedure and returns a OUTPUT value which is of VARCHAR datatype. If the output value is set to integer it is working fine. if the output value is set to varchar it returns empty value. below is my php code and sql server stored procedure. please help me where am wrong. Thank you
$retbillno = 'REF';
$sp_name = "{call Stp_Bill(?,?)}";
$params = array(
array($massno, SQLSRV_PARAM_IN),
array($retbillno, SQLSRV_PARAM_INOUT)
);
$stmt3 = sqlsrv_query( $conn, $sp_name, $params);
if( $stmt3 === false )
{
echo "Error in executing statement 3.\n";
die( print_r( sqlsrv_errors(), true));
//die( print_r( "0", true));
}
else
{
sqlsrv_next_result($stmt3);
echo $retbillno;
sqlsrv_free_stmt( $stmt3);
sqlsrv_close( $conn);
}
and stored procedure
CREATE PROCEDURE Stp_Bill
#massno INT,
#retbillno VARCHAR(20) OUTPUT
AS
BEGIN
SELECT #retbillno='REF02455'
RETURN
END
I have had to deal with similar issue with C# and SQL output parameter of datatype VARCHAR. What I found was that when declaring the parameter in C# I need to mention its size
// The below will not return any value larger than the length of existing value in someInitialValue
var myOutParam = new SqlParameter("#calculatedParam", someInitialValue);
myOutParam.Direction = ParameterDirection.InputOutput;
con.ExecuteQuery(...);
// if for example myInitialValue was "A" and your returned "XYZ" from the procedure, your finalValue would only be "X"
var finalValue = myOutParam.Value;
Proper way to address this issue is to provide the parameter declaration with the expected size
// The below declaration will return properly
var myOutParam = new SqlParameter("#calculatedParam", someInitialValue);
myOutParam.Direction = ParameterDirection.InputOutput;
myOutParam.Size=3;
con.ExecuteQuery(...);
// if for example myInitialValue was "A" and your returned "XYZ" from the procedure, your finalValue would only be "XYZ"
var finalValue = myOutParam.Value;
Translate this to your PHP requirements and it should address your issue.

I am using PHP ODBC to write to an access database, but it won't write to the database

I'm trying to use PHP/ODBC to connect to an access file. The problem is that I can read from the database but I can't write to it using the below:
$conn = odbc_connect('SKW-DB','','');
if (!$conn)
{
exit ("ODBC Connection Failed ". $conn);
}
$stmt = "INSERT INTO PRODUCT (ProductCode, ProductName) VALUES ('TestCode', 'TestEntry')";
$result = odbc_exec ($conn,$stmt);
echo "Result1: ";
echo $result;
$result returns nothing. Again, I am able to read from the database, connectivity isn't an issue. I just can't write to it.
That's because you're simply ASSUMING the query can never fail. It did fail, and returned a boolean false. echo false literally prints out nothing.
Try this instead:
$result = odbc_exec($conn, $stmt);
if ($result === false ) {
die(odbc_errormsg($conn));
}
And what you get back from odbc_exec() cannot be echoed out anyways. On success, it returns a statement handle, which is NOT something you can simply print out.
Sounds like you need a little more debugging code.
First, try var_dumping the $result instead of echoing it.
var_dump($result);
There's certain PHP variable types that echo can't/won't display.
Next -- chances are your query's causing an error of some sort, so try using the odbc error reporting functions after making your query
$result = odbc_exec ($conn,$stmt);
echo "Result1: ";
var_dump( $result );
if($result)
{
var_dump( odbc_error($conn) );
var_dump( odbc_errormsg($conn) );
}

PHP Get return value from MSSQL Stored Procedure

I can't get the OUTPUT parameter from my SQL Server (MSSQL 2012) SP to return to PHP. My Stored procedure is:
CREATE PROCEDURE spGetNextSeqID #ID AS INT OUTPUT
AS
BEGIN
BEGIN TRANSACTION
SELECT #ID = SEQUENCE_NO + 1 FROM tblCSRSequence WITH (TABLOCKX)
UPDATE tblCSRSequence SET SEQUENCE_NO=#ID
COMMIT TRANSACTION
END
And my PHP code is:-
<?php
include "DBConnect.php";
$conn = sqlsrv_connect( $serverName, $connection);
if( !$conn )
{
echo "Connection could not be established to ".$serverName;
die( print_r( sqlsrv_errors(), true));
}
$sql="{call dbo.spGetNextSeqID( ? )}";
$outSeq=0;
$params = array
(
array($outSeq, SQLSRV_PARAM_OUT)
);
$stmt = sqlsrv_query( $conn, $sql, $params );
if( $stmt == false)
die( print_r( sqlsrv_errors(), true) );
sqlsrv_free_stmt( $stmt);
sqlsrv_close( $conn );
echo $outseq;
?>
I know the SP is getting called and working - I checked it with a trace and can see that it's generating the following:-
declare #p1 varchar(max)
set #p1='154'
exec dbo.spGetNextSeqID #p1 output
select #p1
Each time I refresh my browser page it calls the SP and increments the counter by 1 but never returns the value to the calling PHP function. I've been fiddling with this for about 2 days now - I've scoured the similar posts but none of the suggested fixes (like SET NOCOUNT ON etc) work.
Anyone got any ideas?
New:
I missed that you are using a single parameter as both input and output. Please try the following.
array($outSeq, SQLSRV_PARAM_INOUT)
Then using
sqlsrv_next_result($stmt);
echo $outSeq;
Reference:
http://technet.microsoft.com/en-us/library/cc644932(v=sql.105).aspx
Old:
You must set up $outSeq with the appropriate data type. Try initialize the value to $outSeq = 0.00, since your output type is MONEY.
Please reference the following article:
http://technet.microsoft.com/en-us/library/cc626303(v=sql.105).aspx

PHP with sqlsrv_num_rows

I'm attempting to execute a query of a SQL Server database, looking at a many to many relationship. I link the table I want the rows from with the relationship table, and plug in the unique id, in this case the $guid.
The query is functional, sometimes. It will work, and then I switch out solely the $guid for another one, and it fails, even though I'm staring at the table and it has values associated with that new $guid.
<?php
$guid = '{893C7BF8-E8C5-41D5-9C61-A72CF62DDBA8}';
// Connect to Database
$server = "###($#";
$connectionSettings = array("Database"=>"db", "UID"=>"user", "PWD"=>"pword");
$connection = sqlsrv_connect($server, $connectionSettings);
if (!$connection){
die("Failed Connection");
}
// Prepare and Execute Query
$sql = "SELECT *
FROM STREAMS.ATTACHMENTS a INNER JOIN STREAMS.RELATTACHMENTS ra
ON a.ROWGUID = ra.ATTACHMENT_GUID
WHERE ra.FEATURE_GUID = '" . $guid . "'";
$results = sqlsrv_query($connection, $sql);
$rowCount = sqlsrv_num_rows( $results );
if ($rowCount === false)
echo "failure";
else
echo $rowCount;
while($row = sqlsrv_fetch_array($results)){
echo "loop";
}
?>
Even stranger, the output to this code is the following:
failurelooploop
So that implies that the sqlsrv_num_rows command counted no rows in the result... but it also implies that the same results set has 2 rows, since the while loop went around twice.
Can anybody explain this funky behavior?
Thanks.
I will bet that you have some sort of error: sqlsrv_num_rows will return FALSE if something goes wrong. You can get the error output through:
// probably don't want this in production.
print_r( sqlsrv_errors());
I'll guess the cause has to do with your guid column, but I can't be sure. :-)
Oh, and unless you need the number of rows, don't use it. Use do... while instead:
$row = sqlsrv_fetch_array($results);
if($row)
{
do{
echo "loop";
} while( $row = sqlsrv_fetch_array( $results ) );
}
else
{
// No results found
// you can output print_r( sqlsrv_errors() ); here
}
This error shows for cursor type SQLSRV_CURSOR_FORWARD & SQLSRV_CURSOR_DYNAMIC . my personal preference is not to use it. if you still want to use it pass extra parameter to query function like :
$stmt = sqlsrv_query( $connection, $sql, array(), array( "Scrollable" => 'keyset' ));
// $stmt = sqlsrv_query( $connection, $sql, array(), array( "Scrollable" => 'dynamic' ));
// $stmt = sqlsrv_query( $connection, $sql, array(), array( "Scrollable" => 'static' ));
check more : https://msdn.microsoft.com/en-us/library/hh487160.aspx
-- http://php.net/manual/en/function.sqlsrv-query.php

Categories