2010-06-16 15 views
6

Ho una semplice istruzione INSERT eseguita da uno script PHP eseguito su un server web Apache Linux. Posso eseguire la query fine da SQL Management Studio e normalmente funziona bene anche da PHP. Tuttavia, ogni tanto ricevo un messaggio di errore dal mio script PHP che la query non è riuscita e la funzione mssql_get_last_message() restituisce 'L'istruzione è stata terminata'.Che cosa causa che SQL Server restituisce il messaggio "L'istruzione è stata terminata"?

Quali origini possono causare la restituzione di questo messaggio da SQL Server?

risposta

11

Hai trovato una delle parti più fastidiose di SQL Server. Esistono situazioni in cui è possibile generare un errore e SQL genera due messaggi di errore: il primo per spiegare l'errore e il secondo per dire qualcosa di utile come "L'istruzione è stata terminata" (che, tecnicamente, è il numero dell'errore 3621). Il fatto è che SQL, e quasi tutto ciò che lo tocca - come PHP - può solo vedere/raccogliere/elaborare/o utilizzare in altro modo l'ultimo messaggio di errore unlcear. Quello che è effettivamente utile si perde.

Il modo rapido per capire cosa sta succedendo è eseguire la sequenza di comandi che portano all'errore da SSMS. Questo, a quanto pare, non funzionerà per te.

Un modo più faticoso di capirlo è attivare SQL Profiler per tracciare l'evento Exception e quindi eseguire il processo. Questo dovrebbe mostrare tutti gli errori che si sono verificati. Lancio in altri eventi rilevanti (SP: Starting, SP: StmtStarting, SQL: BatchStarting, qualunque cosa sia applicabile al codice che si sta inviando al database) mostrerà quale comando sta generando l'errore.

1

per ottenere un codice di errore numerico da MSSQL si può fare una select che assomiglia

SELECT @@ errore come CodiceErrore
che dovrebbe restituire il codice di errore corretto.

Puoi anche provare questo codice che è pubblicato su 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

Quindi con il tuo esempio, se rilevo il messaggio "La dichiarazione è stata terminata" dovrei essere in grado di inviare la query che hai fornito per ottenere il codice di errore? –

+0

Non importa, la tua soluzione in teoria suona bene. Tuttavia, la variabile @@ ERROR verrà sovrascritta se un'altra query raggiunge il database prima che sia possibile interrogarla. Su un server occupato questo è altamente probabile. –

+0

Il problema riscontrato è apparentemente un problema noto con il driver mssql. Guarda http://php.net/manual/en/function.mssql-get-last-message.php, specialmente i commenti in fondo.La gente ha lottato con questo problema per molto tempo. – Gary

0

È possibile utilizzare il codice nel messaggio per sapere qual è l'errore. Per esempio:

[2627:. L'istruzione è stata terminata]

In questo caso, il codice di errore è 2627, quindi se si esegue l'SQL di seguito saprete il messaggio

Violazione del vincolo% ls '%. * Ls'. Impossibile inserire la chiave duplicata nell'oggetto '%. * Ls'. Il valore della chiave duplicata è% ls.

Questo è un modo per conoscere l'errore del messaggio corretto. Nel mio esempio l'errore è violazione della chiave primaria

Problemi correlati