2

我们将 MSSQL 与使用 PHP 中的 dblib PDO 库的 Laravel 结合使用。我查看了照亮数据库部分,发现它使用了 PDO->prepare($query)->execute($bindings)。所以我期待它会在 SQL 数据库中执行一个准备好的语句。

但是当我检查表以分析运行的查询时。我看到查询没有作为准备好的语句运行,而是查询被归类为 Adhoc 查询。

你们有谁知道为什么 PHP/Laravel/FreeTDS/MSSQL 会出现这样的行为,或者对如何修复它有任何想法吗?

谢谢!

4

1 回答 1

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

我尝试了一个非常简单的查询,采用 2 个 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();

有解决方法吗?

使用 /exact/ 相同的 PHP 代码并将底层驱动程序更改为pdo_sqlsrv,我可以开始看到usecounts增加,而pdo_dblib我没有看到。

上面的 SO 线程有一个交换到ODBC驱动程序的“解决方案”(尽管没有澄清为什么这不起作用dblib)。

真正的原因是什么?

所以,我仍然不清楚为什么这个功能似乎不起作用。我能找到的唯一其他信息来自 2017 年埋藏的 php.net 错误:

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

于 2020-02-27T08:29:05.050 回答