【发布时间】:2018-05-08 21:29:28
【问题描述】:
我有带有 pdo_sqlsrv 扩展的 PHP 5.3 和一个 MSSQL2008 数据库。以下代码使用准备好的语句从表中检索数据,一切正常。但是,当我多次重复该语句时,在 SQL Server 配置文件中我可以看到准备好的语句没有被重用。在每个 SQL 请求上,都会再次准备语句。
$this->statement = $connection->prepare("SELECT Lang,MemoryArea,ID,TextType,TextValue FROM CoreLanguage WHERE TextType = :textType;");
$this->statement->bindValue(":textType", "URL");
$this->statement->execute();
$data = $this->statement->fetchAll(PDO::FETCH_ASSOC) or array();
$this->statement->closeCursor();
$this->statement->bindValue(":textType", "SYSTEM");
$this->statement->execute();
$data = $this->statement->fetchAll(PDO::FETCH_ASSOC) or array();
$this->statement->closeCursor();
这种行为的原因可能是变量 $textType 的字符串长度不同。正如您在分析器列表中看到的那样,使用不同的输入参数数据类型(nvarchar(6) 和 nvarchar(3))准备了两次相同的语句。
这些数据请求的 SQL Server Profiler 日志条目:
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,N'@P1 nvarchar(3)',N'SELECT Lang,MemoryArea,ID,TextType,TextValue FROM CoreLanguage WHERE TextType = @P1;',N'URL'
select @p1
declare @p1 int
set @p1=3
exec sp_prepexec @p1 output,N'@P1 nvarchar(6)',N'SELECT Lang,MemoryArea,ID,TextType,TextValue FROM CoreLanguage WHERE TextType = @P1;',N'SYSTEM'
select @p1
如果输入字符串数据的长度始终相同,则 SQL 服务器会重用该语句。但是,这种情况很少发生......
有谁知道为什么 SQL 服务器不重用已经准备好的语句?或者我如何将输入参数 @P1 操作为合适的数据类型,例如 nvarchar(40)(与 TextType 列定义相同)?
也许我错过了一个特定于驱动程序的选项?
【问题讨论】:
-
您可以尝试将PDO属性
PDO::ATTR_EMULATE_PREPARES设置为false。 -
我现在尝试在准备语句之前设置属性:
$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);这并没有改变结果。关键是它可以工作,但前提是参数字符串长度完全相同。否则,由于@P1 的参数长度不同,它会创建一个新的预处理语句。
标签: php sql-server-2008 pdo