Как выполнить хранимую процедуру в php с помощью sqlsrv и "?" параметр style

Я просмотрел несколько других вопросов, которые кажутся (из названий) такими же, как это. Однако мой случай несколько иной.

следующие работы (т. е. я получаю "успех", и моя база данных выполняет то, что я ожидаю при запуске процедуры с заданными переменными):

$sql = "MyDB.dbo.myProcedure {$var1}, {$var2}, {$var3}";
$result = sqlsrv_query($myConn, $sql);
if (!$result) {
    echo 'Your code is fail.';
}
else {
    echo 'Success!';
}

Я хочу избежать (или уменьшить возможность) SQL-инъекции, создав строку SQL с помощью параметров. Например:

$sql = "select * from aTable where col1 = ? AND col2 = ?";
$result = sqlsrv_query($myConn, $sql, array($var1, $var2));
//please note. This code WILL work!

но когда я делаю это с хранимой процедура не выполняется. Он терпит неудачу без ошибок, сообщаемых через sqlsrv_errors (), никаких действий в базе данных и $result === false.

чтобы быть ясным, следующее не удается:

$sql = "MyDB.dbo.myProcedure ?, ?, ?";
$result = sqlsrv_query($myConn, $sql, array($var1, $var2, $var3));

аналогично оператор prepare/execute, созданный таким же образом, также потерпит неудачу:

$sql = "MyDB.dbo.myProcedure ?, ?, ?";
$stmt = sqlsrv_prepare($myConn, $sql, array(&$var1, &$var2, &$var3));
foreach($someArray as $key => $var3) {
    if(sqlsrv_execute($stmt) === false) {
        echo 'mucho fail.';
    }
}
//this code also fails.

для полноты я подтвердил, что рассматриваемая хранимая процедура работает непосредственно в среде SQL Management Studio и вызывается так, как я упоминал выше. Точно так же я подтвердил, что can используйте параметризованные запросы для любого необработанного запроса (например, insert, select, update vs a stored procedure).

Итак, мой вопрос в том, как я могу вызвать хранимую процедуру, используя параметризованный запрос против встраивания переменных в строку запроса?

что еще более важно, я действительно хочу использовать prepare/execute, поэтому, надеюсь, ответ позволит это работать.

2 ответов


вклады пользователя в php.net запишите, как выполнить хранимую процедуру с помощью sqlsrv-prepare.

в случае удаления из php.net вклады пользователей в будущем вот что у него было(есть) в списке:

$procedure_params = array(
array(&$myparams['Item_ID'], SQLSRV_PARAM_OUT),
array(&$myparams['Item_Name'], SQLSRV_PARAM_OUT)
);
// EXEC the procedure, {call stp_Create_Item (@Item_ID = ?, @Item_Name = ?)} seems to fail with various errors in my experiments
$sql = "EXEC stp_Create_Item @Item_ID = ?, @Item_Name = ?";
$stmt = sqlsrv_prepare($conn, $sql, $procedure_params);

вот страница руководства,http://php.net/manual/en/function.sqlsrv-prepare.php


это продолжение ответа @chris85.

здесь стоит отметить, что после того, как заявление подготовлено, вам нужно его выполнить:

$sql = "EXEC stp_Create_Item @Item_ID = ?, @Item_Name = ?";
$stmt = sqlsrv_prepare($conn, $sql, $procedure_params);
if (!sqlsrv_execute($stmt)) {
    echo "Your code is fail!";
    die;
}
while($row = sqlsrv_fetch_array($stmt)){
    //Stuff
}

sqlsrv_execute() возвращает только true или false. Если вы хотите проанализировать данные, возвращенные хранимой процедурой, вы можете обработать их так же, как результат из sqlsrv_query().

если вы забыли sqlsrv_execute() вы получите сообщение об ошибке, что результат должен быть выполнен, прежде чем его можно будет использовать.