php 是什么导致 SQL Server 返回消息“语句已终止”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3053669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What causes SQL Server to return the message 'The statement has been terminated'?
提问by Wally Lawless
I have a very simple INSERT statement being executed from a PHP script running on a Linux Apache web server. I can run the query fine from within SQL Management Studio and it normally runs fine from PHP as well. However, every once in awhile I get an error message from my PHP script that the query failed and the mssql_get_last_message() function returns 'The statement has been terminated'.
我从 Linux Apache Web 服务器上运行的 PHP 脚本执行了一个非常简单的 INSERT 语句。我可以在 SQL Management Studio 中正常运行查询,它通常也可以在 PHP 中正常运行。但是,每隔一段时间我就会从我的 PHP 脚本中收到一条错误消息,指出查询失败并且 mssql_get_last_message() 函数返回“语句已终止”。
What sources can cause this message to be returned from SQL Server?
哪些来源会导致此消息从 SQL Server 返回?
回答by Philip Kelley
You have found one of the most annoying parts of SQL Server. There are situations where an error can be raised, and SQL will generated two error messages: the first to explain what the error was, and the second to say something useful like "The statement has been terminated" (which, technically, is error number 3621). The thing is that SQL, and most everything else that touches it--such as PHP--can only see/pick up/process/or otherwise utilize that last unlcear error message. The one that's actually useful gets lost.
您已经发现了 SQL Server 中最烦人的部分之一。在某些情况下可能会引发错误,并且 SQL 将生成两条错误消息:第一个解释错误是什么,第二个说一些有用的信息,例如“语句已终止”(从技术上讲,它是错误号3621)。问题是 SQL 以及大多数与它相关的其他所有内容(例如 PHP)只能查看/获取/处理/或以其他方式利用最后一个未显示的错误消息。真正有用的会丢失。
The quick way to figure out what's going on is to run the sequence of commands leading up to the error from SSMS. This, apparently, will not work for you.
找出发生了什么的快速方法是运行导致 SSMS 错误的命令序列。显然,这对您不起作用。
A fussier way to figure it out is to fire up SQL Profiler to track the Exception event, and then run your process. This should show all errors that occured. Tossing in relevant other events (SP:Starting, SP:StmtStarting, SQL:BatchStarting, whatever is applicable to the code your submitting to the database) will show which command is raising the error.
一种更复杂的方法是启动 SQL Profiler 来跟踪异常事件,然后运行您的进程。这应该显示发生的所有错误。加入相关的其他事件(SP:Starting、SP:StmtStarting、SQL:BatchStarting,任何适用于您提交到数据库的代码)将显示哪个命令引发错误。
回答by Gary
To get a numeric error code from mssql you can do a select that looks something like
要从 mssql 获取数字错误代码,您可以执行一个类似于
SELECT @@ERROR AS ErrorCode
Which SHOULD return the correct error code.
SELECT @@ERROR AS ErrorCode
应该返回正确的错误代码。
You can also try this code which is posted on PHP.NET.
你也可以试试这个发布在 PHP.NET 上的代码。
function query($sQuery, $hDb_conn, $sError, $bDebug)
{
if(!$rQuery = @mssql_query($sQuery, $hDb_conn))
{
$sMssql_get_last_message = mssql_get_last_message();
$sQuery_added = "BEGIN TRY\n";
$sQuery_added .= "\t".$sQuery."\n";
$sQuery_added .= "END TRY\n";
$sQuery_added .= "BEGIN CATCH\n";
$sQuery_added .= "\tSELECT 'Error: ' + ERROR_MESSAGE()\n";
$sQuery_added .= "END CATCH";
$rRun2= @mssql_query($sQuery_added, $hDb_conn);
$aReturn = @mssql_fetch_assoc($rRun2);
if(empty($aReturn))
{
echo $sError.'. MSSQL returned: '.$sMssql_get_last_message.'.<br>Executed query: '.nl2br($sQuery);
}
elseif(isset($aReturn['computed']))
{
echo $sError.'. MSSQL returned: '.$aReturn['computed'].'.<br>Executed query: '.nl2br($sQuery);
}
return FALSE;
}
else
{
return $rQuery;
}
}
回答by Vinicius Monteiro
You can use the code in the message to know which is the error. For example:
您可以使用消息中的代码来了解哪个是错误。例如:
[2627: The statement has been terminated.]
[2627:声明已终止。]
In this case, the error code is 2627, so if you execute the sql below you'll know the message
在这种情况下,错误代码是2627,所以如果你执行下面的sql你就会知道信息
SELECT msg.text
FROM sys.messages msg
INNER JOIN sys.syslanguages lng ON lng.msglangid = msg.language_id
WHERE msg.message_id = 2627
AND lng.alias = 'English'
Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls.
违反 %ls 约束 '%.*ls'。无法在对象 '%.*ls' 中插入重复键。重复的键值为 %ls。
This is a way to know the right message error. In my example the error is violation of primary key
这是一种了解正确消息错误的方法。在我的示例中,错误是违反主键

