【问题标题】:PHP get return value of stored procedurePHP获取存储过程的返回值
【发布时间】:2019-01-04 10:00:35
【问题描述】:

我很高兴通过 PDO 使用 SQL Server 处理遗留 PHP 应用程序。

如何在 PHP 中检索使用RETURN 语句作为输出通道的存储过程的返回值?

示例过程

CREATE PROCEDURE [dbo].[mleko_test]
    @param INT
AS
  BEGIN
    RETURN @param * 3;
  END
GO

如果可能,我宁愿不修改程序。


我知道有类似的问题,但他们不包括这个案例

【问题讨论】:

    标签: php sql-server stored-procedures pdo sqlsrv


    【解决方案1】:

    像这样执行存储过程:"exec ?=mleko_test(?)"

    工作示例:

    <?php
    #------------------------------
    # Connection info
    #------------------------------
    $server = 'server\instance,port';
    $database = 'database';
    $uid = 'user';
    $pwd = 'password';
    
    #------------------------------
    # With PDO
    #------------------------------
    try {
        $conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch ( PDOException $e ) {
        die ( "Error connecting to SQL Server" );
    }
    
    try {
        $sql = "exec ? = mleko_test (?)";
        $param = 3;
        $spresult = 0;
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(1, $spresult, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
        $stmt->bindParam(2, $param);
        $stmt->execute();
    } catch ( PDOException $e ) {
        die ( "Error connecting to SQL Server" );
    }
    
    $stmt = null;
    $conn = null;
    
    echo 'Stored procedure return value (with PDO): '.$spresult."</br>";
    
    #------------------------------
    # Without PDO
    #------------------------------
    $cinfo = array (
        "Database" => $database,
        "UID" => $uid,
        "PWD" => $pwd
    );
    
    $conn = sqlsrv_connect($server, $cinfo);
    if ( $conn === false )
    {
        echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);
        exit;
    }
    
    $sql = "exec ? = mleko_test (?)";
    $param = 3;
    $spresult = 0;
    $params = array(   
        array(&$spresult, SQLSRV_PARAM_OUT), 
        array($param, SQLSRV_PARAM_IN),  
    ); 
    $stmt = sqlsrv_query($conn, $sql, $params);
    if ( $stmt === false ) {
        echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);
        exit;
    }
    
    while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
    }
    
    sqlsrv_free_stmt($stmt);
    sqlsrv_close($conn);
    
    echo 'Stored procedure return value (without PDO): '.$spresult."</br>";
    ?>
    

    注意事项:

    使用 PHP 7.1.12 和 PHP Driver for SQL Server(pdo_sqlsrv 版本 4.3.0+9904)测试。

    【讨论】:

    • 你能把 PDO 版本调高一点吗(因为问题主要是 PDO 相关的)?另外,为什么必须指定length(bindParam 的第三个参数)?我试过没有它,但没有用。
    • @mleko 我使用 PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE 作为 $length 参数进行了一些更改。我更熟悉这个驱动程序的非 PDO 版本,但我发现当在 bindParam 调用中指定 $length 时,驱动程序将其解释为您正在绑定输出(或输入输出)的指示范围。对于仅输入的参数,不需要有长度。
    • 好的,太好了。谢谢
    【解决方案2】:

    我找到了一个使用多查询的解决方案,但 @Zhorov answer 更干净

    <?php
    $connection = new PDO($connectionString, $DB_USERNAME, $DB_PASSWORD);
    
    $stmt = $connection->prepare(<<<SQL
    DECLARE @a INT;
    EXEC @a = mleko_test :in
    SELECT @a AS result;
    SQL
    );
    
    $stmt->execute([":in" => 123]);
    echo $stmt->fetch()["result"] . "\n";
    

    【讨论】:

      【解决方案3】:

      我必须改变

      $sql = "exec ?=mleko_test(?)";
      

      $sql = "{?=call mleko_test(?)}";
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 2013-01-22
        • 1970-01-01
        • 2014-05-03
        • 2021-10-02
        • 2010-10-19
        • 2010-12-12
        相关资源
        最近更新 更多