2

I have pleasure to work with legacy PHP application using SQL Server via PDO.

How in PHP can I retrieve return value of stored procedure which is using RETURN statement as output channel?

Example procedure

CREATE PROCEDURE [dbo].[mleko_test]
    @param INT
AS
  BEGIN
    RETURN @param * 3;
  END
GO

If possible, I would prefer to not modify procedure.


I am aware that there are similar questions, but they don't cover this case

3 Answers 3

4

Execute stored procedure like this: "exec ?=mleko_test(?)".

Working example:

<?php
#------------------------------
# Connection info
#------------------------------
$server = 'server\instance,port';
$database = 'database';
$uid = 'user';
$pwd = 'password';

#------------------------------
# With PDO
#------------------------------
try {
    $conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch ( PDOException $e ) {
    die ( "Error connecting to SQL Server" );
}

try {
    $sql = "exec ? = mleko_test (?)";
    $param = 3;
    $spresult = 0;
    $stmt = $conn->prepare($sql);
    $stmt->bindParam(1, $spresult, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
    $stmt->bindParam(2, $param);
    $stmt->execute();
} catch ( PDOException $e ) {
    die ( "Error connecting to SQL Server" );
}

$stmt = null;
$conn = null;

echo 'Stored procedure return value (with PDO): '.$spresult."</br>";

#------------------------------
# Without PDO
#------------------------------
$cinfo = array (
    "Database" => $database,
    "UID" => $uid,
    "PWD" => $pwd
);

$conn = sqlsrv_connect($server, $cinfo);
if ( $conn === false )
{
    echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
    exit;
}

$sql = "exec ? = mleko_test (?)";
$param = 3;
$spresult = 0;
$params = array(   
    array(&$spresult, SQLSRV_PARAM_OUT), 
    array($param, SQLSRV_PARAM_IN),  
); 
$stmt = sqlsrv_query($conn, $sql, $params);
if ( $stmt === false ) {
    echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
    exit;
}

while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
}

sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);

echo 'Stored procedure return value (without PDO): '.$spresult."</br>";
?>

Notes:

Tested with PHP 7.1.12 and PHP Driver for SQL Server (pdo_sqlsrv version 4.3.0+9904).

Sign up to request clarification or add additional context in comments.

3 Comments

Can you move PDO version higher(as question is mainly PDO related)? Also, why specifying length (3rd parameter to bindParam) is mandatory? I tried without it and it didn't worked.
@mleko I've made some changes using PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE as $length parameter. I'm more familiar with not PDO version of this driver, but what I've found is that when $length is specified in the bindParam call, the driver interprets it as an indication that you are binding an output (or in-out) parameter. For input-only parameters, there is no need to have a length.
Ok, great. Thank you
0

I came to a solution using multi-query but @Zhorov answer is cleaner

<?php
$connection = new PDO($connectionString, $DB_USERNAME, $DB_PASSWORD);

$stmt = $connection->prepare(<<<SQL
DECLARE @a INT;
EXEC @a = mleko_test :in
SELECT @a AS result;
SQL
);

$stmt->execute([":in" => 123]);
echo $stmt->fetch()["result"] . "\n";

Comments

0

I had to change

$sql = "exec ?=mleko_test(?)";

for

$sql = "{?=call mleko_test(?)}";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.