Я просмотрел несколько других вопросов, которые кажутся (из названий) такими же, как этот. Тем не менее, мой случай немного отличается.
Следующие работы (т.е. я получаю «успех», и моя база данных выполняет то, что я ожидаю при запуске процедуры с заданными переменными):
$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));
Аналогично, оператор подготовки / выполнения, созданный таким же образом, также потерпит неудачу:
$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 И если она вызывается так, как я упоминал выше. Кроме того, я подтвердил, что я Можно используйте параметризованные запросы для любого необработанного запроса (например, вставка, выбор, обновление или хранимая процедура).
Итак, мой вопрос, как я могу вызвать хранимую процедуру, используя параметризованный запрос против встраивания переменных в строку запроса?
Что еще более важно, я на самом деле хочу использовать подготовку / выполнение, так что, надеюсь, ответ также позволит это сработать.
Вклады пользователей на 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()
вы получите сообщение о том, что результат должен быть выполнен до того, как его можно будет использовать.