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


SommaireTrucs et Astuces en T-SQLProgrammation des bases de données (11)
précédent sommaire suivant
 

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

Mis à jour le 28 septembre 2005 WOLO Laurent

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)

Mis à jour le 28 septembre 2005 WOLO Laurent

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 !!!

Mis à jour le 28 septembre 2005 WOLO Laurent

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
Sélectionner cette date dans votre fonction.

Code tsql : Sélectionner tout
1
2
SELECT DateHeure_Courante  
FROM V_DateHeure_Courante

Mis à jour le 28 septembre 2005 Fabien Celaia

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'
Fermer la fenêtre de droite pour conserver la même connexion, puis dans l'explorateur d'objet, faire clic droit sur la procédure stockée puis Débogage

Mis à jour le 28 septembre 2005 WOLO Laurent

En interrogeant la variable globale @@error, directement après l'appel de la requête : 0=succès, sinon no d'erreur

Mis à jour le 28 septembre 2005 Fabien Celaia

Code tsql : Sélectionner tout
1
2
3
4
SELECT description  
FROM master..sysmessages  
WHERE langid=@@langid  
AND error= VotreNoDErreur

Mis à jour le 28 septembre 2005 Fabien Celaia

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

Mis à jour le 3 juin 2008 Fabien Celaia

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

Mis à jour le 24 mai 2009 SQLpro

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

Mis à jour le 24 mai 2009 SQLpro

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

Mis à jour le 24 mai 2009 SQLpro

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2017 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.

 
Contacter le responsable de la rubrique SQL-Server