我是一名老派开发人员,刚刚进入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!!!干杯