PHP-MSSQL从存储过程中获取结果


PHP - MSSQL getting results from Stored Procedures

我是一名老派开发人员,刚刚进入WWW编程世界。我正在为与我合作的公司开发一个使用HTML、CSS、PHP和MSSQL Server 2008 R2的应用程序。

在我的应用程序中,我使用存储过程在数据库中插入、修改、删除或查询信息。根本不使用TSQL指令,只是从PHP代码中执行存储过程。

我使用PHP5和SQLSRV驱动程序进行数据库交互。

到目前为止一切都很好,但现在我被插入部分卡住了。。。如果一切正常,SP将插入记录,如果不正常,则不会。。。但直到我再次查询表,看看记录是否存在,我才看到结果。

我在PHP中使用以下代码来运行在表中插入记录的SP:

function spinserta($tabla, $columnas, $valores, $cnct) {
   $stmt = 'Exec spinsert @tabla=?,@columnas=?,@valores=?';         
   $params = array($tabla,$columnas,$valores);
   $result = sqlsrv_query($cnct,$stmt,$params) ;
   return $result;
}

如果事务不成功,我在$result变量中没有得到任何信息,并且希望从SP获得结果消息,以便向用户显示错误消息。

如何从SP获取结果消息(无论是否为错误)?

提前感谢!

这是我的一个应用程序中的一些代码。看看它是否有帮助:

//Query SQL
$tsql = "Exec spinsert @tabla=?,@columnas=?,@valores=?"; 
$params = array($tabla,$columnas,$valores);
//Execute the stored query 
$stmt = sqlsrv_query($conn, $tsql, $params);
if ($stmt === false)
{
    echo "<h3>Error in query preparation or execution.</h3>";
    ListErrors();
    die;
}
else {
    echo "Insert Successful";
}
// this should help for the non-insert/update case
$arr = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
var_dump($arr);

经过数小时的研究。。。。终于有了概念!事情是这样的:最初的PHP代码是:

function spinserta($tabla, $columnas, $valores, $cnct) {
   $stmt = 'Exec spinsert @tabla=?,@columnas=?,@valores=?';         
   $params = array($tabla,$columnas,$valores);
   $result = sqlsrv_query($cnct,$stmt,$params) ;
   return $result;
}

原始SP为:

ALTER PROCEDURE [dbo].[spinsert] 
    @tabla varchar(50),
    @columnas varchar(8000),
    @valores varchar(8000)
AS
BEGIN
    SET NOCOUNT ON;
    declare @orden varchar(8000)
    declare @return_value int
    set @orden='Insert into ' + @tabla + ' (' + @columnas + ') values (' + @valores + ')';
    execute (@orden);
    return 
END

非常直接。。。当php代码被执行并且SP成功时,变量$result被加载为"Resource id#14",如果SP失败,$result值为null。

事情进展顺利!!!但不是我想要的方式。然后我发现了这篇文章:http://msdn.microsoft.com/en-us/library/ms178592.aspx

在此基础上,我修改了SP:

ALTER PROCEDURE [dbo].[spinsert] 
    @tabla varchar(50),
    @columnas varchar(8000),
    @valores varchar(8000)
AS
BEGIN
    SET NOCOUNT ON;
    declare @orden varchar(8000)
    declare @return_value int
    begin try
        set @orden='Insert into ' + @tabla + ' (' + @columnas + ') values (' + @valores + ')';
        set @return_value=0;
        execute (@orden);
    end try
    begin catch
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
        SELECT @return_value = ERROR_NUMBER()
        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
    end catch
    return @return_value
END

和PHP代码:

function spinserta($tabla,$columnas,$valores,$cnct) {
    $tsql = 'Exec spinsert @tabla=?,@columnas=?,@valores=?';            
    $params = array($tabla,$columnas,$valores);
    $stmt = sqlsrv_query($cnct,$tsql,$params) ; 
    $errors=sqlsrv_errors();
    if ($stmt === false or $stmt===0) {
        foreach( $errors as $error ) {
            $stmt=str_replace("'","","Error: ". $error['code']. " - " . $error['message']);
            }
    } else {
        $stmt="1";
    }       
    return $stmt;
}

我最初的方法有两个问题,1在数据库引擎端,SP并没有真正生成系统错误,尽管语句失败了。使用Try-Catch技术,再加上RAISEERROR概念,SP最终在语句失败时生成系统错误。在这之后,只需要对PHP代码进行一些小的调整。

使用这种方法,发送到数据库的信息的验证是在数据库引擎端完成的,无需编写大量代码,只需在提交时验证表单中的字段。所需要的是确保数据库表、关系、约束、完整性和其他方面得到很好的应用,并且数据库将保护自己免受错误数据的影响。如果提交了表单中提供的信息中的错误,数据库将拒绝这些错误,代码将向用户显示后面的正确错误。

我想看看类似的东西是否适用于MySQL。。。,我想是的!

非常感谢Maximus2012!!!干杯