SQL Server - La FAQConsultez toutes les FAQ
Nombre d'auteurs : 13, nombre de questions : 119, dernière mise à jour : 31 mai 2011 Ajouter une question
Question / réponses à tout ce que vous avez toujours voulu savoir sur Microsoft SQL Server sans jamais oser le demander
- Comment désactiver et réactiver un déclencheur ?
- Comment désactiver et réactiver une contrainte ?
- Comment tester qu'une colonne a été modifiée dans un trigger Insert ou Update ?
- Comment récuperer la date système dans une fonction utilisateur ?
- Comment débugger une procédure stockée ?
- Comment savoir si un ordre SQL s'est bien déroulé ?
- Comment retrouver le libellé d'un message d'erreur par rapport à son n° ?
- Comment requêter sur 2 tables de deux bases différentes ?
- Comment faire une jointure référentielle ?
- Comment faire une auto jointure ?
- Comment faire une jointure naturelle ?
MS SQL Serveur, à partir de la version 2000, prévoit une option dans l'instruction
ALTER TABLE qui permet de désactiver et réactiver un déclencheur.
Exemple :
L'exemple suivant utilise l'option DISABLE TRIGGER de l'instruction ALTER TABLE pour
désactiver le déclencheur et permettre une insertion qui devrait normalement entraîner une violation du déclencheur.
Le déclencheur est ensuite réactivé à l'aide de l'option ENABLE TRIGGER.
Code tsql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | CREATE TABLE trig_example (id INT, name VARCHAR(10), salary MONEY) go -- Creation du déclencheur CREATE TRIGGER trig1 ON trig_example FOR INSERT as IF (SELECT COUNT(*) FROM INSERTED WHERE salary > 100000) > 0 BEGIN print "TRIG1 Error: Vous tentez d'inserer un salaire > $100,000" ROLLBACK TRANSACTION END GO -- Tentative d'insertion d'une valeur qui viole la contrainte. INSERT INTO trig_example VALUES (1,'Pat Smith',100001) GO -- Nous allons maintenant désactiver le déclencheur. ALTER TABLE trig_example DISABLE TRIGGER trig1 GO -- Nous allons inserer une valeur qui normalement viole le déclencheur INSERT INTO trig_example VALUES (2,'Chuck Jones',100001) GO -- Réactivation du déclencheur ALTER TABLE trig_example ENABLE TRIGGER trig1 GO -- Et l'on teste si notre déclencheur est réactivé. INSERT INTO trig_example VALUES (3,'Mary Booth',100001) GO |
MS SQL Serveur, à partir de la version 2000, prévoit une option dans l'instruction
ALTER TABLE qui permet de désactiver et réactiver un déclencheur.
Exemple :
L'exemple suivant désactive la contrainte définissant les salaires pouvant être inclus
dans les données. L'option WITH NOCHECK CONSTRAINT est utilisée avec ALTER TABLE pour
désactiver la contrainte et permettre une insertion qui devrait normalement entraîner
une violation de la contrainte. WITH CHECK CONSTRAINT réactive la contrainte.
Code tsql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CREATE TABLE cnst_example (id INT NOT NULL, name VARCHAR(10) NOT NULL, salary MONEY NOT NULL CONSTRAINT salary_cap CHECK (salary < 100000) ) -- Nous commençons par inserer deux lignes INSERT INTO cnst_example VALUES (1,'Joe Brown',65000) INSERT INTO cnst_example VALUES (2,'Mary Smith',75000) -- Ensuite, nous tentons de violer notre contrainte check INSERT INTO cnst_example VALUES (3,'Pat Jones',105000) -- Nous désactivons la contrainte puis nous relançons ALTER TABLE cnst_example NOCHECK CONSTRAINT salary_cap INSERT INTO cnst_example VALUES (3,'Pat Jones',105000) -- Nous réactivons notre contrainte puis violant la requête. ALTER TABLE cnst_example CHECK CONSTRAINT salary_cap INSERT INTO cnst_example VALUES (4,'Eric James',110000) |
Dans un trigger Insert ou Update uniquement, vous pouvez faire usage,
de la clause IF UPDATE(Colonne1) pour tester si une colone a été modifié par un insert ou un update.
Noter que vous pouvez étendre la construction sur plusieurs colonnes en utilisant des opérateurs AND,OR
Exemple :
Code tsql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | --Soit une table T_Table dont la définition est la suivante: CREATE TABLE T_TABLE1 ( TAB_ID INT NOT NULL PRIMARY KEY, TAB_VAL NUMERIC(32) NOT NULL ) GO --Nous initialisons la table INSERT INTO T_TABLE1 VALUES(1,500) INSERT INTO T_TABLE1 VALUES(2,1500) INSERT INTO T_TABLE1 VALUES(3,2000) INSERT INTO T_TABLE1 VALUES(4,1800) GO --Supposant que nous vonlons interdire l'ajout et la modification des valeurs dans cette table --Nous créons un déclencheur a cet effet. CREATE TRIGGER TG_NO_ADD_UPDATE ON T_TABLE1 FOR INSERT,UPDATE AS IF UPDATE(TAB_ID) RAISERROR ('Interdiction formelle d''ajouter ou modifier les données de cette tables', 16, 10) go --Tentative d'ajout d'une ligne INSERT INTO T_TABLE1 VALUES(5,600) GO --Cette instruction est refoulée !!! |
SQL server interdit l'utilisation de la fonction getdate() dans une fonction utilisateur.
Pour contourner cette dificulté,nous créons une vue qui renvoie la date courante
Code tsql : | Sélectionner tout |
1 2 3 | CREATE VIEW V_DateHeure_Courante AS SELECT CURRENT_TIMESTAMP AS DateHeure_Courante |
Code tsql : | Sélectionner tout |
1 2 | SELECT DateHeure_Courante FROM V_DateHeure_Courante |
Dans l'analyseur de requête, ouvrir une connexion sur le serveur où se trouve la procédure et executer :
Code tsql : | Sélectionner tout |
exec sp_sdidebug 'legacy_on'
En interrogeant la variable globale @@error, directement après l'appel de la requête : 0=succès, sinon no d'erreur
Code tsql : | Sélectionner tout |
1 2 3 4 | SELECT description FROM master..sysmessages WHERE langid=@@langid AND error= VotreNoDErreur |
Il y a de nombreuses manières plus ou moins implicites de déterminer une table
- NomDeTable
- NomDuSchema.NomDeTable
- NomDeLaBase.NomDuSchema.NomDeTable
- NomDeLaBase..NomDeLaTable
- NomDuServeurNomDeLaBase.NomDuSchema.NomDeTable
Si l'on souhaite, dans le cas extrême, lier 2 tables de 2 bases distinctes, situées chacune sur un serveur distinct, il faudra donc utiliser la nomenclature complète, en prenant soin au préalable de déterminer le serveur distant/lié
Code tsql : | Sélectionner tout |
1 2 3 | SELECT P.Nom, P.Prenom, L.NomLocalite FROM Personnes P INNER JOIN ServeurDistant.BaseDistante..Localites L ON P.CodeLocalite=L.IDLocalite |
Cette fonction permet de réaliser la jointure d'une table fille avec sa table mère liée par l'intégrité référentielle.
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | CREATE FUNCTION dbo.F_SCRIPT_REF_JOIN (@SHEMA_MERE SYSNAME, @TABLE_MERE SYSNAME, @ALIAS_LEFT SYSNAME, @SHEMA_FILLE SYSNAME, @TABLE_FILLE SYSNAME, @ALIAS_RIGHT SYSNAME) RETURNS VARCHAR(max) AS /****************************************************************************** * fonction de calculs de jointure référentielle * ******************************************************************************* * Fred. Brouard - http://SQLPro.developpez.com - www.sqlspot.com - 2009-04-10 * ******************************************************************************* * Cette fonction calcule la jointure référentielle entre deux tables, l'une * * mère l'autre fille * ******************************************************************************/ BEGIN DECLARE @OUT VARCHAR(max); SET @OUT = ''; SELECT @OUT = @OUT + @ALIAS_LEFT +'.' + COL_MERE +' = ' + @ALIAS_RIGHT + '.' + COL_FILLE + ' AND ' FROM (SELECT KCU_PRIMARY.COLUMN_NAME AS COL_MERE, KCU_FOREIGN.COLUMN_NAME AS COL_FILLE FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC_PRIMARY ON RC.UNIQUE_CONSTRAINT_SCHEMA = TC_PRIMARY.CONSTRAINT_SCHEMA AND RC.UNIQUE_CONSTRAINT_NAME = TC_PRIMARY.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC_FOREIGN ON RC.CONSTRAINT_SCHEMA = TC_FOREIGN.CONSTRAINT_SCHEMA AND RC.CONSTRAINT_NAME = TC_FOREIGN.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU_PRIMARY ON TC_PRIMARY.CONSTRAINT_SCHEMA = KCU_PRIMARY.CONSTRAINT_SCHEMA AND TC_PRIMARY.CONSTRAINT_NAME = KCU_PRIMARY.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU_FOREIGN ON TC_FOREIGN.CONSTRAINT_SCHEMA = KCU_FOREIGN.CONSTRAINT_SCHEMA AND TC_FOREIGN.CONSTRAINT_NAME = KCU_FOREIGN.CONSTRAINT_NAME WHERE TC_PRIMARY.TABLE_SCHEMA = @SHEMA_MERE AND TC_PRIMARY.TABLE_NAME = @TABLE_MERE AND TC_FOREIGN.TABLE_SCHEMA = @SHEMA_FILLE AND TC_FOREIGN.TABLE_NAME = @TABLE_FILLE AND KCU_PRIMARY.ORDINAL_POSITION = KCU_FOREIGN.ORDINAL_POSITION ) AS T; IF LEN(@OUT) > 4 SET @OUT = SUBSTRING(@OUT, 1, LEN(@OUT) - 4); RETURN @OUT; END GO |
Il s'agit de joindre la table sur un clone de cette même table (par exemple avec un des pseudo table inserted ou deleted) c'est à dire de clef à clef.
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | CREATE FUNCTION dbo.F_SCRIPT_SELF_JOIN (@SHEMA SYSNAME, @TABLE SYSNAME, @ALIAS_LEFT SYSNAME, @ALIAS_RIGHT SYSNAME) RETURNS VARCHAR(max) AS /****************************************************************************** * fonction de calcul d'auto jointure * ******************************************************************************* * Fred. Brouard - http://SQLPro.developpez.com - www.sqlspot.com - 2009-04-10 * ******************************************************************************* * Cette fonction calcule la jointure naturelle de deux tables, * ******************************************************************************/ BEGIN DECLARE @OUT VARCHAR(max); SET @OUT = ''; SELECT @OUT = @OUT + @ALIAS_LEFT +'.' + COLUMN_NAME +' = ' + @ALIAS_RIGHT + '.' + COLUMN_NAME + ' AND ' FROM (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC ON KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME WHERE TC.TABLE_SCHEMA = @SHEMA AND TC.TABLE_NAME = @TABLE AND CONSTRAINT_TYPE = 'PRIMARY KEY') AS T; IF LEN(@OUT) > 4 SET @OUT = SUBSTRING(@OUT, 1, LEN(@OUT) - 4); RETURN @OUT; END GO |
Effectuer la jointure naturelle, c'est joindre les deux tables sur les colonnes ayant même nom. Rappelons que dans un système d'information, les informations doivent avoir un nom unique (norme AFNOR).
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | CREATE FUNCTION dbo.F_SCRIPT_NATURAL_JOIN (@SHEMA_LEFT SYSNAME, @TABLE_LEFT SYSNAME, @ALIAS_LEFT SYSNAME, @SHEMA_RIGHT SYSNAME, @TABLE_RIGHT SYSNAME, @ALIAS_RIGHT SYSNAME) RETURNS VARCHAR(max) AS /****************************************************************************** * fonction de calcul de jointure naturelle * ******************************************************************************* * Fred. Brouard - http://SQLPro.developpez.com - www.sqlspot.com - 2009-04-10 * ******************************************************************************* * Cette fonction calcule la jointure naturelle de deux tables, * ******************************************************************************/ BEGIN DECLARE @OUT VARCHAR(max); SET @OUT = ''; SELECT @OUT = @OUT + @ALIAS_LEFT +'.' + COLUMN_NAME +' = ' + @ALIAS_RIGHT + '.' + COLUMN_NAME + ' AND ' FROM (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @SHEMA_LEFT AND TABLE_NAME = @TABLE_LEFT INTERSECT SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @SHEMA_RIGHT AND TABLE_NAME = @TABLE_RIGHT) AS T; IF LEN(@OUT) > 4 SET @OUT = SUBSTRING(@OUT, 1, LEN(@OUT) - 4); RETURN @OUT; END GO |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.