2010-06-16 10 views
6

J'ai une instruction INSERT très simple exécutée à partir d'un script PHP exécuté sur un serveur web Linux Apache. Je peux exécuter la requête à partir de SQL Management Studio et ça marche aussi bien avec PHP. Cependant, de temps en temps, je reçois un message d'erreur de mon script PHP indiquant que la requête a échoué et que la fonction mssql_get_last_message() renvoie "L'instruction a été interrompue".Qu'est-ce qui fait que SQL Server renvoie le message 'L'instruction a été arrêtée'?

Quelles sources peuvent provoquer ce message à renvoyer à partir de SQL Server?

Répondre

11

Vous avez trouvé l'une des parties les plus ennuyeuses de SQL Server. Il y a des situations où une erreur peut être soulevée, et SQL générera deux messages d'erreur: le premier pour expliquer l'erreur et le second pour dire quelque chose d'utile comme "L'instruction a été terminée" (qui, techniquement, est le numéro d'erreur 3621). La chose est que SQL, et presque tout ce qui le touche - comme PHP - ne peut voir/ramasser/traiter/ou utiliser autrement ce dernier message d'erreur unlcear. Celui qui est réellement utile est perdu.

Le moyen le plus rapide de comprendre ce qui se passe est d'exécuter la séquence de commandes menant à l'erreur de SSMS. Cela, apparemment, ne fonctionnera pas pour vous.

Une méthode plus sophistiquée consiste à lancer SQL Profiler pour suivre l'événement Exception, puis à exécuter votre processus. Cela devrait montrer toutes les erreurs qui se sont produites. Lancer d'autres événements pertinents (SP: démarrage, SP: StmtStarting, SQL: BatchStarting, tout ce qui est applicable au code que vous soumettez à la base de données) montrera quelle commande déclenche l'erreur.

1

Pour obtenir un code d'erreur numérique de MSSQL vous pouvez faire une sélection qui ressemble à

SELECT @@ erreur AS ErrorCode
qui renvoie le code d'erreur correct.

Vous pouvez également essayer ce code qui est affiché sur 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

Donc, avec votre exemple, si je détecte mon message «L'instruction a été interrompue», je devrais être en mesure de soumettre la requête que vous avez fournie pour obtenir le code d'erreur? –

+0

Nevermind, votre solution semble bonne en théorie. Cependant, la variable @@ ERROR sera écrasée si une autre requête frappe la base de données avant que vous ayez une chance de l'interroger. Sur un serveur occupé, c'est très probable. –

+0

Le problème que vous rencontrez est un problème connu avec le pilote mssql apparemment. Regardez http://php.net/manual/en/function.mssql-get-last-message.php, en particulier les commentaires en bas.Les gens luttent avec ce problème depuis longtemps. – Gary

0

Vous pouvez utiliser le code dans le message pour savoir quelle est l'erreur. Par exemple:

[2627:. L'instruction a été interrompue]

Dans ce cas, le code d'erreur est 2627, donc si vous exécutez le SQL ci-dessous, vous saurez le message

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 de la contrainte% ls '%. * Ls'. Impossible d'insérer une clé dupliquée dans l'objet '%. * Ls'. La valeur de la clé en double est% ls.

Ceci est un moyen de connaître la bonne erreur de message. Dans mon exemple, l'erreur est la violation de la clé primaire

Questions connexes