Я просмотрел несколько других вопросов, которые кажутся (из названий) такими же, как это. Однако, мой случай немного другой.
Следующие работы (т.е. я получаю «успех», и моя база данных выполняет то, что я ожидаю при выполнении процедуры с заданными переменными):
$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. И если называется так, как я упоминал выше. Аналогично, я подтвердил, что могу использовать параметризованные запросы для любого необработанного запроса (например, вставки, выбора, обновления и хранимой процедуры).
Итак, мой вопрос заключается в том, как я могу вызвать хранимую процедуру с использованием параметризованного запроса и встраивания переменных в строку запроса?
Что еще более важно, я действительно хочу использовать подготовку / выполнение, поэтому, надеюсь, ответ позволит этому и работать.
На вкладках пользователя на 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_rows($stmt)){ //Stuff }
sqlsrv_execute()
возвращает true / false. Если вы хотите проанализировать данные, возвращаемые хранимой процедурой, вы можете обрабатывать их так же, как результат из sqlsrv_query()
.
Если вы забудете sqlsrv_execute()
вы получите сообщение о том, что результат должен быть выполнен до его использования.