【问题标题】:Stored procedure only partially executes from PHP存储过程仅部分从 PHP 执行
【发布时间】:2012-05-25 03:16:05
【问题描述】:

我有一个在 MS SQL 2008 R2 中运行的存储过程,它在 SQL Management Studio 中运行良好。但是,如果我从 PHP 运行它,它似乎在完成之前停止执行。 SQL 中没有返回错误,PHP 错误日志中也没有返回错误。该过程只是使用第二个存储过程多次写入错误日志。我已将代码缩减为一个简单的循环,以演示重现问题。这是主要的存储过程。

ALTER PROCEDURE [dbo].[usp_failure_test]

AS
DECLARE
@counter int,
@message nvarchar(100)

SET @counter = 0;
WHILE @counter < 100
  BEGIN
    SET @message = 'COUNT: ' + CAST(@counter AS nvarchar);
    EXEC usp_log 0, 'TEST', @message;
    SET @counter += 1;
  END
EXEC usp_log 0, 'TEST', 'Finished';

这调用了过程 usp_log

ALTER PROCEDURE [dbo].[usp_log]
@engine_id int,
@type nvarchar(15),
@message text
AS
DECLARE
@last int,
@log_size int

INSERT INTO [dbo].[log] (engine_id, timestamp, type, message) VALUES (@engine_id, getdate(), @type, @message);
SET @log_size = CONVERT(int, (dbo.get_setting('log_size')))
SET @last = (SELECT TOP 1 id FROM log ORDER BY id DESC)
DELETE FROM log WHERE id < (@last - @log_size)
return

如果我从 SSMS 执行 usp_failure 测试,它会写入所有预期的日志条目,然后成功停止。但是,如果我从 PHP 执行它(使用以下代码),它只会达到 52,然后在没有任何线索的情况下停止。

<?php
$servername = "localhost\sqlexpress";
$connectionInfo = array("UID" => "xxx", "PWD" => "xxx", "Database"=>"xxx", "ReturnDatesAsStrings"=>true, "CharacterSet" =>"UTF-8");
$conn = @sqlsrv_connect($servername, $connectionInfo);
$query = "usp_failure_test";
$params = array();
$result = sqlsrv_query($conn, $query, $params);
?>

我尝试添加额外的代码行,这使得它在更少的迭代后失败。我确保 PHP 有足够的内存可以使用,并且我还检查了 PHP 和 SQL 日志,但无济于事。我们还使用了 SQL 分析器,它也没有显示任何问题。

【问题讨论】:

  • 你的 PHP 会超时吗?代码运行需要多长时间?
  • 感谢您的回复。正如您所看到的,现在已经成功回答了这个问题,但是据记录,运行大约需要 0.25 秒,但是,如果我在其中添加额外的代码行,它将花费更少的时间来运行,并且会在更少的循环迭代后停止.在将 SET NOCOUNT ON 添加到 usp_log 存储过程的开头后,它成功运行了我需要的多次迭代。感谢您的帮助。
  • 只是让我知道以供将来参考-您的程序运行了多少次迭代?我从来没有遇到过返回超过驱动程序处理能力的数据!
  • @andrewsi - 这可能不是数据量本身的问题,而是结果集的数量问题。每个插入/更新查询都会创建一个“x row(s) affected”消息,在 PHP 中它看起来像一个结果集。
  • 原始代码调用了大约 30 次过程。这些中的每一个都将使用上面的 SP 将两个或三个条目写入日志表,并执行各种 SELECT。没有插入或更新。除了一个简单的整数来指示成功或失败之外,这些过程都不会返回任何数据。我已经使用 sqlsrv_configure('ClientBufferMaxKBSize', 20000) 命令操纵了缓冲区大小,但它没有任何区别。它必须是受 SET NOCOUNT ON 设置影响的不同“缓冲区”。

标签: php sql sql-server-2008 stored-procedures


【解决方案1】:

尝试在您的存储过程中使用SET NOCOUNT ON。您可能会遇到从 sql server PHP 驱动程序返回给 PHP 的结果数量的限制。

【讨论】:

  • 出色而快速!!!你是正确的 - 我现在已经在 1000 次迭代中很好地测试了它。谢谢你。只是一件事,是否有必要将其附加到所有存储过程的开头或只是从 PHP 调用的那个?再次感谢。
  • @user - 通常我把它放在所有存储过程的开头,除非出于某种原因我想看到“x 行受影响”消息(例如,在调试时) .
  • 谢谢!这让我发疯了!
猜你喜欢
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多