【问题标题】:SQL Server Stored Procedure Output Params in PHPPHP中的SQL Server存储过程输出参数
【发布时间】:2009-01-26 19:19:40
【问题描述】:

我需要帮助在 PHP 中从 SQL Server 运行存储过程。 PHP 在 Unix/Linux 服务器上运行。我们无法让 OUTPUT 变量在 PHP 中返回。以下是PHP代码:

$conn = mssql_connect('server', 'user', 'pass');
    mssql_select_db('db', $conn);

    $procedure = mssql_init('usp_StoredProc', $conn);

    $tmpVar1 = 'value';
    $tmpVar2 = 'value2';

    $outVar1 = '';
    $outVar2 = '';

    mssql_bind($procedure, "@var1", $tmpVar1, SQLVARCHAR, false, false);
    mssql_bind($procedure, "@var2", $tmpVar2, SQLVARCHAR, false, false);

    mssql_bind($procedure, "@outVar1", $outVar1, SQLVARCHAR, true);
    mssql_bind($procedure, "@outVar2", $outVar2, SQLVARCHAR, true);

    mssql_execute($procedure,$conn);

    print($outVar1);
    print($outVar2);

存储过程如下所示:

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER proc [dbo].[usp_StoredProc]
(
    @var1 as varchar(36), 
    @var2 as varchar(10), 
    @outVar1 varchar(36) OUTPUT, 
    @outVar2 varchar(36) OUTPUT 
)
as
  select distinct 
    @outVar1 = row1, 
    @outVar2 = row2
  from table1
  where column1 = @var1
    and column2 = @var2

谁能告诉我为什么 $outVar1 和 $outVar2 没有被填充?非常感谢您的帮助!

【问题讨论】:

  • mssql_get_last_message() 有什么有用的信息吗?
  • mssql_get_last_message() 返回“已将数据库上下文更改为“dbName””
  • 你试过36个空格的字符串吗?
  • 是的,我们已经尝试在 mssql_bind 调用中指定长度。还是没有运气。
  • 不,给它一个定制的字符串:$outVar2 = ' ...36 个空格... ';

标签: php sql-server stored-procedures


【解决方案1】:

根据this page on PHP bugs,你必须(强调我的):

为每个人致电mssql_next_result() SP 返回的结果集。这 处理多个结果的方式。

mssql_next_result() 返回 false 您将可以访问输出 参数和返回值。

【讨论】:

  • 您可以将可选的第二个参数传递给 mssql_execute(如果为真),您可以立即访问结果,而无需调用 mssql_next_result...不幸的是,它在这里仍然没有帮助。
  • 虽然一开始听起来很合理。 :-\
  • 如果你不知道存储过程是否会返回结果,这将起作用,即$result = mssql_execute($procedure),不管有没有返回结果,你都可以然后调用 mysql_next_result($result) 获取输出参数
【解决方案2】:

execute 的第二个参数必须是 true,而不是 conn。这应该有效:

$conn = mssql_connect('server', 'user', 'pass');
mssql_select_db('db', $conn);

$procedure = mssql_init('usp_StoredProc', $conn);

$tmpVar1 = 'value';
$tmpVar2 = 'value2';

$outVar1 = '';
$outVar2 = '';

mssql_bind($procedure, "@var1", $tmpVar1, SQLVARCHAR, false, false);
mssql_bind($procedure, "@var2", $tmpVar2, SQLVARCHAR, false, false);

mssql_bind($procedure, "@outVar1", $outVar1, SQLVARCHAR, true);
mssql_bind($procedure, "@outVar2", $outVar2, SQLVARCHAR, true);

mssql_execute($procedure,true);

print($outVar1);
print($outVar2);

【讨论】:

    【解决方案3】:

    尝试指定输出字段的具体长度

    mssql_bind($procedure, "@outVar1", &$outVar1, SQLVARCHAR, true, false, 36);
    mssql_bind($procedure, "@outVar2", &$outVar2, SQLVARCHAR, true, false, 36);
    

    看看会不会有什么不同。

    还要注意显式 & 以通过引用传递输出变量,尽管我不知道它是否仍然需要。

    【讨论】:

    • 这也是我的下一个想法,+1。提供 36 个空格的字符串也可以作为一个有用的测试。
    • 是的,我们已经尝试了所有有/没有长度的方法。使用引用参数(现在抛出和错误说这种方式已被弃用)和没有。
    • 关于显式引用传递 - 不要认为这是必要的。文档声明该函数只接受引用。
    • 我有一个模糊的回忆,你曾经必须明确地通过 ref 传递,尽管我现在看到文档说它一直都是通过 ref 传递的。谢谢。
    【解决方案4】:

    我怀疑这会导致您的问题,但您为什么使用DISTINCT

    这只是代码错误 - 任何时候你看到它,都意味着有可能返回正在使用 DISTINCT “处理”的重复项,并且可能需要查看为什么会返回重复项。

    【讨论】:

    • Distinct 可以省略,但我们正在寻找 row1 和 row2 的不同组合。如果我们从 SQL Server 管理工具运行存储过程,它运行良好。它在 php 中获取输出参数是我们遇到的问题。
    • 好的。请记住,在这样的 SELECT 分配中,只要您的结果集包含多于一行,您就会收到错误消息。任何时候结果集为空,变量都将保持不变(如果从未分配过,则为 NULL)。
    • 好电话,凯德。但实际查询只返回一行,所以不是这样。这正在杀了我。我们对存储过程所做的一切工作,除了检索输出参数。
    • Tomalak 在您访问 OUTPUT 参数之前必须消耗所有结果集是正确的。当我想使用 OUTPUT 参数返回客户端可以在使用行之前使用的计数估计时,我遇到了麻烦 - 不起作用。
    • 我在好几个地方都见过这个,但是怎么做呢?您必须使用 mssql_execute 执行存储过程,它不会返回资源。
    【解决方案5】:

    不确定您正在运行哪个版本的 PHP,但我认为在一些较旧的版本中,您需要通过引用传递变量以使值再次出现:

    所以你需要在调用函数时将 & 字符放在变量之前:

    mssql_bind($procedure, "@outVar1", &$outVar1, SQLVARCHAR, true);
    mssql_bind($procedure, "@outVar2", &$outVar2, SQLVARCHAR, true);
    

    另外根据this link 一些版本的输出参数有问题

    【讨论】:

    • 是的,我们正在运行 php 5.*,忘记了确切的版本,但这些问题不应该在这个版本中持续存在。 pass-by-reference 方法会抛出一个错误,提示“在 mssql_bind 中通过引用传递已被弃用”
    【解决方案6】:

    嗯。几厘米

    1) "mssql_execute($procedure,$conn);"错误在于第二个参数不是连接。

    2) 如果您收到“存储过程执行失败”,那么我必须在 freetds.conf 中创建一个数据库主机并引用它。

    那时,我没有收到错误,但我也没有收到输出参数。这是 RHEL5 上的 PHP 5.1。

    如果我启用 freeTDS 日志记录,我会看到数据在返回数据包中返回。在这一点上,我也不知道为什么它也不起作用(除了 SQL server 对 PHP 的支持有点缺乏!)

    【讨论】:

    • 谢谢,乔。我们已经从 mssql_query 中删除了 $conn 参数。是的,我刚刚通过 WampServer 从我的 Windows 机器上运行了这个脚本,它运行良好。所以,我相信你是对的,因为 Unix/Linux 上的 PHP 有点缺乏对 SQL Server 的支持。
    【解决方案7】:

    我也有同样的问题。

    假设您使用 FreeTDS 驱动程序与 SQL Server 进行通信,那么驱动程序的工作方式存在一个已知问题。它在常见问题解答中突出显示

    http://www.freetds.org/faq.html#ms.output.parameters

    常见问题解答中建议的 API 文档在这里,但我找不到使用 PHP 访问它的方法:

    http://www.freetds.org/reference/a00276.html

    我仍然无法将其连接起来,并且我将完全放弃输出参数。

    【讨论】:

      【解决方案8】:

      我通过 Adodb 库以非常简单的方式完成了这项工作......

      $addProduct = $obj->ExecuteQuery("Begin;DECLARE @ProductCode as varchar (100) ;EXEC CREATEPRODUCT'$pname', '$price', @ProductCode OUTPUT, '$merchantId';select @ProductCode;End ;");

      $productCode = $addProduct[0][0];

      更多解释你可以访问这个网站.. http://developer99.blogspot.com/2011/07/calling-ms-sql-sp-from-php.html

      【讨论】:

        猜你喜欢
        • 2012-02-02
        • 1970-01-01
        • 2014-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多