2010-02-16 1 views
-3

version courte: le pilote sqlsrv (wrapper client natif) "mange" les erreurs de violation de contraintes générées à partir des déclencheurs; le pilote mssql (ntwdlib wrapper) les signale très bien.SQL Server 2005, Pilote SQL pour PHP v1.1 mange des erreurs de "transaction condamnée dans le déclencheur"

  • SQL Server 2005
  • PHP 5.3.1
  • Pilote SQL Server pour PHP 1,1

appareil:

CREATE TABLE t (
    t INT NOT NULL PRIMARY KEY 
); 
CREATE VIEW v AS 
    SELECT CURRENT_TIMESTAMP AS v 
; 
CREATE TRIGGER vt ON v 
INSTEAD OF INSERT 
AS BEGIN 
BEGIN TRY 
    INSERT INTO t SELECT 1 UNION ALL SELECT 1; 
END TRY 
BEGIN CATCH 
    RAISERROR('fubar!', 17, 0); 
END CATCH 
END; 

en cours d'exécution INSERT INTO v SELECT CURRENT_TIMESTAMP; par Management Studio donne

(0 row(s) affected) 
Msg 3616, Level 16, State 1, Line 1 
Transaction doomed in trigger. Batch has been aborted. 
Msg 50000, Level 17, State 0, Procedure vt, Line 8 
fubar! 

aucune erreur est rapporté quand je le lance à travers sqlsrv_query:

$conn = sqlsrv_connect(...); 
var_dump(sqlsrv_query($conn, 'INSERT INTO v SELECT CURRENT_TIMESTAMP')); 
var_dump(sqlsrv_errors()); 

sorties

resource(11) of type (SQL Server Statement) 
NULL 

l'application a (il semble) aucun moyen de savoir que le déclencheur a échoué autre que à travers les déclarations ultérieures échouant. La question: Quoi de neuf? Utilisez-vous ce pilote PHP? Utilisez-vous des vues avec des déclencheurs DML? Le pilote signale-t-il transactions condamnées?

modifier 2010-02-17 11:50: la première version de la question à tort prétendu que j'ai vu l'artefact avec la gâchette contenant un INSERT simple. Eh bien, cela se produit uniquement lorsque le fichier DML violant les contraintes se trouve dans un bloc TRY. Désolé pour la confusion.

modifier 2010-03-03: juste pour que vous les gars ne sont pas trop attaché au niveau de gravité dans RAISERROR, le code réel tente de réémettre l'erreur pris avec ERROR_NUMBER, ERROR_SEVERITY et ERROR_STATE.

En outre, s'il vous plaît faites attention aux questions posées:

La question: Quoi de neuf? Utilisez-vous ce pilote PHP? Utilisez-vous des vues avec des déclencheurs DML? Le pilote signale-t-il transactions condamnées?

Veuillez ne pas essayer de récolter la prime sans avoir une expérience de première main de la situation décrite ici.

Répondre

0

J'ai déjà rencontré ce problème par le passé, ce n'est pas seulement PHP qui est complexe. Pour une raison quelconque, que je ne peux pas comprendre et trouver dans toute la documentation, vous devez spécifier la gravité à son maximum de 18 pour les non-administrateurs système. Essayez ceci:

CREATE TABLE t (
    t INT NOT NULL PRIMARY KEY 
); 
CREATE VIEW v AS 
    SELECT CURRENT_TIMESTAMP AS v 
; 
CREATE TRIGGER vt ON v 
INSTEAD OF INSERT 
AS BEGIN 
BEGIN TRY 
    INSERT INTO t SELECT 1 UNION ALL SELECT 1; 
END TRY 
BEGIN CATCH 
    RAISERROR('fubar!', 18, 0); 
END CATCH 
END; 

Note: Je n'ai changé la gravité 17 et 18 dans le code ci-dessus.

+0

Le niveau de gravité 18 est "Erreur interne non fatale détectée" - Ces messages indiquent qu'il existe un problème de logiciel interne, mais l'instruction se termine et la connexion à SQL Server est conservée. Par exemple, un message de niveau de gravité 18 se produit lorsque le processeur de requêtes SQL Server détecte une erreur interne lors de l'optimisation de la requête. L'administrateur système doit être informé chaque fois qu'un message de niveau de gravité 18 se produit. –

+0

n'aide pas. Est-ce que * vous * voyez une différence entre 17 et 18 lorsque vous exécutez l'extrait PHP qui fait partie de la question? –

0

Un Niveau de Gravité de 17 indique "Ressources Insuffisantes". Essayez d'utiliser 16 à la place. (Error Message Severity Levels)

De la référence canonique: Error Handling in SQL 2000 – a Background

Niveau de gravité - un nombre de 0 à 25. L'histoire Stort est que si le niveau de gravité est dans la plage 0-10, le message est informatif ou un avertissement, et pas une erreur. Erreurs résultant d'erreurs de programmation dans votre code SQL ont un niveau de gravité dans la plage 11-16. Les niveaux de gravité 17-25 indiquent les problèmes de ressources, les problèmes matériels ou les problèmes internes dans SQL Server , et si la gravité est 20 ou supérieur, la connexion est terminée. Pour la longue histoire, voir la section Plus sur les niveaux de gravité pour certains tidbits intéressants. Pour le système messages que vous pouvez trouver la gravité niveau master..sysmessages, mais pour certains messages SQL Server utilise un différent niveau de gravité que ce qui est dans sysmessages.

Voir aussi: Error Handling in SQL 2005 and Later

+0

Nope, n'aide pas –

+0

Est-ce que le downvoter s'il vous plaît laissez un commentaire. Merci. –

+1

"Non, n'aide pas" - C'est une réponse utile. Esprit décrivant pourquoi? –

0

Avez-vous essayé une gravité de 10 ou ci-dessous? D'ailleurs, j'ai toujours eu de la chance avec SQL Driver et PHP. Sur 2005 et 2008. Si cela ne fonctionne pas, essayez un serveur différent pour vous assurer que ce n'est pas votre configuration de serveur.

+0

Si le niveau de gravité est compris entre 0 et 10, le message est informatif ou un avertissement, et non une erreur –

+0

@Nick Berandi: avez-vous remarqué les questions posées ici? S'il vous plaît poster des suggestions qui ne répondent pas à la question en tant que commentaires. –

+0

-1 Vous avez attaché à un exemple artificiel. le vrai code va comme: BEGIN TRY ... END TRY COMMENCER RAISERROR (ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_CODE()) END CATCH' (ou alors, vous avez l'idée); l'erreur détectée peut être quelque chose et doit quitter le pilote sqlsrv. aussi, j'ai écrit que le même déclencheur signale des erreurs quand j'utilise php_mssql.dll en PHP. avez-vous lu la question? juste ignorer la gravité spécifique déjà, le problème est évidemment ailleurs. –

Questions connexes