Запросы 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 года:

https://bugs.php.net/bug.php?id=74592

Другие вопросы по тегам