Запросы Laravel MSSQL Adhoc вместо подготовленных
Мы используем MSSQL в сочетании с Laravel, который использует библиотеку dblib PDO из PHP. Я заглянул в подсвеченную часть базы данных и увидел, что она использует PDO->prepare($query)->execute($bindings). Поэтому я ожидаю, что он выполнит подготовленный оператор в базе данных SQL.
Но когда я проверяю таблицу, чтобы проанализировать запросы, которые были выполнены. Я вижу, что запросы не выполнялись как подготовленный оператор, а вместо этого были классифицированы как запрос Adhoc.
Кто-нибудь из вас, ребята, знает, почему PHP/Laravel/FreeTDS/MSSQL ведет себя так, или у вас есть идеи, как это исправить?
Спасибо!
0 ответов
Я думаю, что подготовленные заявления через freetds
-> pdo_dblib
не поддерживаются. Однако у меня нет доказательств этого, и я прошу прощения за "ответ", который не является окончательным. Я надеюсь, что это продвинет проблему дальше / предоставит некоторую поверхность для тех, у кого больше знаний.
Ожидается ли поддержка этой функции? Я бы сказал да.
Согласно этому потоку выше, freetds 4.2
состояния:
динамические запросы (также называемые подготовленными операторами) не поддерживаются.
Однако, упущение, что из более поздних версий будет означать, что это поддерживается (мы используемfreetds 7.3
).
docker-container:/test# tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v1.1.24
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: 7.3
iODBC: no
unixodbc: yes
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: no
GnuTLS: no
MARS: yes
docker-container:/test# cat /etc/freetds/freetds.conf
[global]
tds version = 8.0
text size = 2147483647
client charset = UTF-8
Как определить, что это не работает?
Не связанный с Laravel (хотя все еще PHP - 7.1), я не могу получить подготовленные операторы, работающие с использованием pdo_dblib
Водитель.
Запрос, который я использую, чтобы убедиться, что подготовленные операторы действительно используются:
select cp.objtype, st.text, cp.*
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st
where text like '%LIMIT_TO_SPECIFIC_TEST%'
order by cp.objtype desc, usecounts desc, refcounts desc
Я пробовал очень простой запрос с двумя параметрами типа int, а код PHP выглядел так:
$sql = "SELECT id FROM ExampleTable WHERE foreignIdOne = ? AND foreignIdTwo = ?";
$statement = $this->_connection->prepare($sql);
$valueOne = 2;
$valueTwo = 56;
$statement->bindParam(1, $valueOne, PDO::PARAM_INT);
$statement->bindParam(2, $valueTwo, PDO::PARAM_INT);
$statement->execute();
Есть ли обходной путь?
Используя / точно / тот же PHP-код и изменив базовый драйвер на pdo_sqlsrv
, Я могу начать видеть usecounts
увеличиваются, тогда как с pdo_dblib
Я этого не вижу.
Вышеупомянутый поток SO имел "решение" переключения на ODBC
драйвер (хотя не разъясняется, почему это не работает с dblib
).
Какова настоящая причина?
Поэтому мне до сих пор неясно, почему эта функция не работает. Единственная другая информация, которую я могу найти об этом, - это скрытая ошибка php.net от 2017 года: