2

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

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

我正在使用 PHP 5 和 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 获取结果消息(无论是否错误)?

提前致谢!

4

2 回答 2

1

经过数小时的研究......终于得到了这个概念!事情是这样的:原来的 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!!!干杯!!!

于 2013-07-27T05:30:35.227 回答
0

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

//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);
于 2013-07-23T16:26:48.563 回答