Когда вы используете PDO
с драйвер MSSQL вы фактически используете FreeTDS в качестве низкоуровневого драйвера. Существует несколько различных способов выполнения хранимых процедур — языковые запросы и вызов RPC. а>.
FreeTDS также поддерживает версии протокола TDS 4.2 и 7.x. Одно из основных различий между ними заключается в поведении вызова хранимой процедуры. Microsoft изменила поведение с протокола 4.2 на 7.0, не возвращая выходные параметры из языковых запросов. Языковые запросы в основном отправляют текстовый запрос на сервер в пакете TDS.
Пример языкового запроса с PDO (из php.net)
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'Hello!';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
$stmt->execute();
print "The output is $value\n";
На самом деле вы отправляете что-то вроде EXEC sp_takes..... И если вы запустите пример выше с MSSQL, вы получите пустой выходной параметр в TDS 7.х и ожидаемый результат с 4.2. Почему мы не можем использовать 4.2 и быть довольными? Он имеет множество ограничений:
- Только ASCII, конечно.
- RPC и BCP не поддерживаются.
- поля varchar ограничены 255 символами. Если в вашей таблице определены более длинные поля, они будут усечены.
- динамические запросы (также называемые
prepared statements
) не поддерживаются.
Так что 4.2 это не вариант.
Пример вызова RPC (из расширения odbtp php.net)
$stmt = mssql_init('sp_takes_string_returns_string');
$value = 'Hello!';
mssql_bind($stmt, 1, $value, SQLVARCHAR, true, false, 4000);
mssql_execute($stmt);
print "The output is $value\n";
Используя приведенный выше пример с собственным расширением mssql в php, вы получили правильный результат с TDS 7.2. На самом деле вы отправляете бинарный пакет RPC с этим кодом.
Вопрос
Есть ли способ сделать вызов RPC для хранимой процедуры с драйвером PDO и MSSQL?
mssql_execute($stmt); $stmt->fetchAll(); ...
, но до использования значения $value. - person Gavin   schedule 21.12.2013