2010-06-16 2 views
6

У меня очень простая инструкция INSERT, выполняемая из PHP-скрипта, запущенного на веб-сервере Linux Apache. Я могу выполнить запрос отлично из SQL Management Studio, и он нормально работает и с PHP. Тем не менее, каждый раз через некоторое время я получаю сообщение об ошибке с моего скрипта PHP, что запрос завершился неудачно, и функция mssql_get_last_message() возвращает «Оператор завершен».Что заставляет SQL Server возвращать сообщение «Заявление завершено»?

Какие источники могут привести к возврату этого сообщения с SQL Server?

ответ

11

Вы нашли одну из самых раздражающих частей SQL Server. Бывают ситуации, когда ошибка может быть повышена, и SQL генерирует два сообщения об ошибках: первое объясняет, что такое ошибка, а второе - что-то полезное, например «Оператор завершен» (что, технически, является номером ошибки 3621). Дело в том, что SQL и большинство остальных, что его затрагивает - например, PHP, - могут видеть/получать/обрабатывать/или иным образом использовать последнее сообщение об ошибке. Тот, который действительно полезен, теряется.

Быстрый способ выяснить, что происходит, это запустить последовательность команд, ведущих к ошибке из SSMS. Это, по-видимому, не сработает для вас.

Более суровый способ понять это, чтобы запустить SQL Profiler для отслеживания события Exception, а затем запустить ваш процесс. Это должно показать все ошибки, которые произошли. Тонирование в соответствующих других событиях (SP: Starting, SP: StmtStarting, SQL: BatchStarting, что бы ни было применимо к коду, который вы отправляете в базу данных) покажет, какая команда вызывает ошибку.

1

Чтобы получить числовой код ошибки из MSSQL вы можете сделать выбор, который выглядит как

SELECT @@ ERROR AS ErrorCode
, который должен возвращать правильный код ошибки.

Вы также можете попробовать этот код, который размещен на 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; 
    } 
} 
+0

Так что, например, если я обнаружил, что сообщение «Сообщение было прервано», я могу отправить запрос, который вы предоставили, чтобы получить код ошибки? –

+0

Nevermind, ваше решение в теории звучит хорошо. Тем не менее, переменная @@ ERROR будет перезаписана, если другой запрос попадет в базу данных, прежде чем у вас появится возможность запросить его. На занятом сервере это очень вероятно. –

+0

Проблема, с которой вы сталкиваетесь, - это известная проблема с драйвером mssql. Посмотрите http://php.net/manual/en/function.mssql-get-last-message.php, особенно комментарии внизу.Люди долгое время боролись с этой проблемой. – Gary

0

Вы можете использовать код, указанный в сообщении, чтобы узнать, что представляет собой ошибка. Например:

[2627:. Заявление было прекращено]

В этом случае код ошибки 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' 

Нарушение ограничения% ls '%. * Ls'. Невозможно вставить дублирующий ключ в объект '%. * Ls'. Значение дублирующегося ключа равно% ls.

Это способ узнать правильное сообщение об ошибке. В моем примере ошибка является нарушением первичного ключа

Смежные вопросы