【问题标题】:Syntax error when executing batch of statements via PDO but fine via SSMS通过 PDO 执行批处理语句时出现语法错误,但通过 SSMS 很好
【发布时间】:2016-10-03 02:03:25
【问题描述】:

我正在编写代码以使用 PHP PDO 从头开始​​创建 MSSQL 数据库。我已经创建了数据库,现在需要执行从 .SQL 文件加载的一堆语句来创建表、数据等。前几行是

EXEC sp_dbcmptlevel 'myDbName', 120
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
BEGIN
EXEC [myDbName].[dbo].[sp_fulltext_database] @action = 'enable'
END
GO
ALTER DATABASE [myDbName] SET ANSI_NULL_DEFAULT OFF 
GO
EXEC sp_dbcmptlevel 'myDbName', 120

...

如果我直接在 SSMS 中运行 .SQL 文件,它会完美运行。如果我加载它并通过 PHP PDO 执行它,我会得到 ​​p>

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near 'GO'.' in ...

查看探查器,我的查询被前缀/包装了

declare @p1 int
set @p1=NULL
exec sp_prepexec @p1 output,NULL,N'EXEC sp_dbcmptlevel ''myDbName', 120
...

并且似乎使用准备好的执行包装器,服务器不喜欢它。我正在执行从 SQL 文件加载的脚本

$db = new PDO('sqlsrv:Server='.$serverName.';Database='.$databaseName, $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8);
$db->prepare($mySqlScript)->execute();

如何修复语法错误以执行 PHP 从 SQL 文件加载的整个命令集?

【问题讨论】:

    标签: php sql sql-server tsql pdo


    【解决方案1】:

    您必须通过“GO”子句将脚本拆分为多个语句,然后逐个运行它们。

    类似:

    $script = file_get_contents('script.sql');
    $statements = explode( 'GO', $script );
    foreach( $statements as $statement ) {
      // here execute the $statement
      $sth = $dbh->prepare($statement);
      $sth->execute();
    }
    

    这是 SSMS 在内部执行的操作,在执行语句之前将语句按“GO”拆分。

    【讨论】:

    • 太好了,谢谢。我认为它是一种黑客行为,但不是必需的方式。您知道无法将整个脚本转储到其中的原因是什么吗?对于性能问题,我原以为能够一次性处理所有内容会更好。
    • 可能这不是库的目标之一,它是一种很容易实现的行为,所以留给我们处理它。您可以像function execScript( $scriptPath ) { // Do the split and the execution } 一样对其进行编码,并在您的代码中处理它,就像它是原始库的一部分一样。这是图书馆将以任何方式(或多或少)做的事情。
    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2019-07-16
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多