如何在使用 PHP SQLSRV_QUERY 时忽略 T-SQL 打印语句

Cay*_*ian 2 php sql-server sqlsrv

我们正在将一些 PHP 5.3 内部 API 代码转换为 PHP 7.2。转换过程的一部分是从使用 mssql_* DB API 切换到使用 sqlsrv_* DB API。我们发现的一件事是,旧的 MSSQL_EXECUTE 语句会忽略存储过程中的任何 T-SQL Print 语句,但新的 SQLSRV_QUERY 语句不会。

例如,我有以下示例存储过程:

create procedure spTestPrintStmt
  @var1 varchar(50),
  @var2 varchar(50),
  @var3 varchar(50),
  @rtn1 varchar(50) out,
  @rtn2 varchar(50) out
as
begin

  print 'Starting spTestPrintStmt...';

  print 'Vars: ' + @var1 + ',' + @var2 + ',' + @var3;

  select @rtn1 = @var1, @rtn2 = @var2 + @var3;

  print 'Returned: ' + @rtn1 + ',' + @rtn2;

  return 0;
end;
go
Run Code Online (Sandbox Code Playgroud)

我使用以下 PHP 页面来测试上述存储过程:

<html>
  <head>
    <title>Stored Proc Param Test</title>
  </head>
  <body>
    <p>
<?php
  $result = 0;
  $var1 = 'abc';
  $var2 = 'def';
  $var3 = 'ghi';
  $rtn1 = '';
  $rtn2 = '';

  $connectionInfo = array("Database"=>'database', "UID"=>'username', "PWD"=>'password');
  $conn = sqlsrv_connect("dbserver", $connectionInfo);
  if( $conn === false ) {
    echo "Couldn't connect to SQL Server on dbserver.<br />";
    die( print_r( sqlsrv_errors(), true));
  } else {
    echo "Connected!";
  }
  echo '<br/>'; 


  $tsql = "{ ? = call spTestPrintStmt(?,?,?,?,?) }";

  $params = array(
    array($result, SQLSRV_PARAM_INOUT),
    array($var1, SQLSRV_PARAM_IN),
    array($var2, SQLSRV_PARAM_IN),
    array($var3, SQLSRV_PARAM_IN),
    array($rtn1, SQLSRV_PARAM_INOUT),
    array($rtn2, SQLSRV_PARAM_INOUT)
  );

  $stmt = sqlsrv_query($conn, $tsql, $params);
  if ($stmt === false) {
    echo "Error in executing stored proc.";  
    die( print_r( sqlsrv_errors(), true));  
    echo "<br/>";
  }
  sqlsrv_next_result($stmt);  
  echo "Result: " . $result . "<br/>";
  echo "Rtn1: " . $rtn1 . "<br/>";
  echo "Rtn2: " . $rtn2 . "<br/>";

  sqlsrv_free_stmt($stmt);
  sqlsrv_close($conn);
?>
    </p>
  </body>
 </html>
Run Code Online (Sandbox Code Playgroud)

当我运行上述命令时,我得到以下结果:

Connected!
Error in executing stored proc.Array ( [0] => Array ( [0] => 01000 [SQLSTATE] => 01000 [1] => 0 [code] => 0 [2] => [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Starting spTestPrintStmt... [message] => [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Starting spTestPrintStmt... ) ) 
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?我们在 T-SQL 代码中广泛使用打印语句来帮助调试。

Rei*_*lef 5

如果您查看sqlsrv_errors()的 PHP 文档,它指出:

默认情况下,调用任何 SQLSRV 函数时生成的警告均被视为错误。这意味着如果调用 SQLSRV 函数时出现警告,该函数将返回 FALSE。但是,与 SQLSTATE 值 01000、01001、01003 和 01S02 对应的警告永远不会被视为错误。有关更改此行为的信息,请参阅 sqlsrv_configure() 和 warningsReturnAsErrors 设置。

因此,您的打印语句(似乎被视为警告)将作为错误返回。如果您转到链接的sqlsrv_configure()函数文档,您将看到一个选项。

我在建立连接之前添加了以下行:

sqlsrv_configure("WarningsReturnAsErrors",0);
Run Code Online (Sandbox Code Playgroud)

现在,当我运行您的代码时,我不再收到错误。我得到以下信息:

Connected!
Result: 0
Rtn1: 
Rtn2: 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。