【问题标题】:PHP: Param count and argument count don't matchPHP:参数计数和参数计数不匹配
【发布时间】:2011-06-29 20:57:00
【问题描述】:

我的 php 应用程序正在使用 MS SQLSrv 驱动程序。调用数据库中的存储过程时,运行 sqlsrv_execute() 后出现以下错误:参数计数和参数计数不匹配。我的代码如下:

    $sql = "{call myStoredProcedure(?, ?, ?, ?, ?, ?)}";

    //Passing by reference instead of value, otherwise sqlsrv_prepare is not happy
    $params = array(array(&$param1, SQLSRV_PARAM_IN),
                    array(&$param2, SQLSRV_PARAM_IN),
                    array(&$param3, SQLSRV_PARAM_IN),
                    array(&$param4, SQLSRV_PARAM_IN),
                    array(&$param5, SQLSRV_PARAM_IN),
                    array(&$param6, SQLSRV_PARAM_OUT)
                    );

    /* Create the statement. */
    $stmt = sqlsrv_prepare( $conn, $sql, $params);
    if( $stmt )
    {
         echo "Statement prepared.\n";
    }
    else
    {
         echo "Error in preparing statement.\n";
         die( print_r( sqlsrv_errors(), true));
    }

    //TODO: Resolve error, "param count and argument count don't match"
    $stmt = sqlsrv_execute($conn, $sql, $params);

    //This statement will run, but no rows are returned and rowCount is false.
    //$stmt = sqlsrv_query($conn, $sql, $params);

    $rowCount = sqlsrv_num_rows( $stmt );
    $numFields = sqlsrv_num_fields( $stmt );

    //Rest of code...

我为此花了一个小时并梳理了 PHP.Net 和 Microsoft 文档。有没有其他人遇到过类似的错误?任何帮助表示赞赏。

是的,我检查了我的参数计数,我的存储过程需要 6 个参数。

更新:

存储过程sn-p:

ALTER PROCEDURE [dbo].[myStoredProcedure] 
    @param1 VARCHAR(64),
    @param2 VARCHAR(64),
    @param3 DATETIME, 
    @param4 DATETIME,
    @param5 INT = 9,
    @param6 INT OUTPUT
AS
BEGIN

//Do stuff 

END

【问题讨论】:

  • 你能发布一些关于实际存储过程的信息吗?
  • 疯狂猜测,因为我远非专家,但由于最后一个参数是输出参数,我不明白为什么应该绑定它:存储的 proc 不会做任何事情具有给定的值。
  • 不幸的是,根据我在 Microsoft 文档中阅读的内容,您必须提供所有参数、输入、输出以及双向输入/输出。
  • 我也不是专家,但在此处的示例中 (msdn.microsoft.com/en-us/library/cc296181.aspx),参数被传递给 sqlsrv_prepare,然后执行返回值 ($stmt)(在您的代码中,您再次使用 $sql 和 $params 执行)。监督还是设计?

标签: php database sql-server-2005


【解决方案1】:

您错误地使用了SQLSRV_EXECUTE。您得到的错误实际上是一个 PHP 错误,告诉您将错误的参数传递给 SQLSRV_EXECUTE

定义为: sqlsrv_execute(resource $stmt)
但是你打电话给:sqlsrv_execute($conn, $sql, $params)

假设存储过程设置正确,我已经修复了下面的代码。让我知道它是否有效。

$sql = "{call myStoredProcedure(?, ?, ?, ?, ?, ?)}";

//Passing by reference instead of value, otherwise sqlsrv_prepare is not happy
$params = array(array(&$param1, SQLSRV_PARAM_IN),
                array(&$param2, SQLSRV_PARAM_IN),
                array(&$param3, SQLSRV_PARAM_IN),
                array(&$param4, SQLSRV_PARAM_IN),
                array(&$param5, SQLSRV_PARAM_IN),
                array(&$param6, SQLSRV_PARAM_OUT)
                );

/* Create the statement. */
$stmt = sqlsrv_prepare( $conn, $sql, $params);
if( $stmt )
{
     echo "Statement prepared.\n";
}
else
{
     echo "Error in preparing statement.\n";
     die( print_r( sqlsrv_errors(), true) );
}

//Shouldn't assign this to $stmt, $stmt can be reused for multiple sqlsrv_execute() calls
$result = sqlsrv_execute($stmt);

if($result === false)
{
    //Error handling
}
else
{
    $rowCount = sqlsrv_num_rows( $result );
    $numFields = sqlsrv_num_fields( $result );
}

【讨论】:

  • 另外,请注意更改“$result = sqlsrv_execute($stmt);”此处准备/执行策略的部分要点是,您可以更改上面分配的变量,然后再次执行以获得新结果。
  • 感谢您的回答。我挣扎了一个多小时才让准备好的陈述生效。 PS:确保数据库用户对存储过程具有“执行”权限;)
猜你喜欢
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2017-12-31
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
相关资源
最近更新 更多