Hello,
Dans le cas où j'ai de multiples contraintes check sur une table, est-il possible de gérer l'ordre dans lequel doivent être vérifiées les contraintes et d'arrêter le check dès que l'une d'elle n'est pas vérifiée ?
Hello,
Dans le cas où j'ai de multiples contraintes check sur une table, est-il possible de gérer l'ordre dans lequel doivent être vérifiées les contraintes et d'arrêter le check dès que l'une d'elle n'est pas vérifiée ?
Non... et cela pour des raisons d'optimisation !
Seuls les déclencheurs peuvent être ordonnés.
A +
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
* * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *
Ok merci.
Par contre, cela me fait me poser une autre question.
Est-ce une bonne pratique que de mettre plusieurs contraintes check sur un table ou bien vaut-il mieux tout mettre dans une seule (avec une grosse fonction qui fait le café) ?
J'aurais tendance à séparer les contraintes histoire d'avoir un message d'erreur qui indique le problème précis mais j'suis pas encore expert ^^.
C'était effectivement la bonne question à se poser !
Comme tu ne peut maitriser l'ordre des contraintes CHECK, le mieux est de les distinguer sur le plan "transversal"' s'il y a lieu c'est à dire :
1) grouper les contraintes de domaines (agissant sur la valeur intrinsèque de la colonne)
2) grouper les contraintes interagissantes de niveau ligne1 (vérifiant une ligne avec plusieurs colonnes)
3) grouper les contraintes interagissantes de niveau table (vérifiant un ensemble de lignes)
4) grouper les contraintes interagissantes de niveau base (vérifiant plusieurs ensembles de lignes)
Les deux dernières étant faites soit par des CHECK avec une UDF, soit par des déclencheurs.
Normalement tu ne devrais jamais avec 2 contraintes ayant un sens sémantique différent pour chaque groupe...
A +
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
* * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *
Ca fait plaisir ça
Je ne suis pas sûr de comprendre pas cette remarque. C'est la partie avec "sens sémantique différent" qui me pose problème. Aurais-tu un exemple concret ? (quitte à ce soit un truc très bête qui ne servirait à rien)
Dans mon cas concret, j'ai par exemple la table suivante avec les 2 contraintes en gras (qui contient les articles qui "participent" a des promotions) :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
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
44
45
46
47 CREATE TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI]( [PED_ID] [int] NOT NULL, [PDI_BARCODE] [char](13) NOT NULL, [PDI_DESCRIPTION] [varchar](100) NULL, [PDI_COLOR] [varchar](50) NULL, [PDI_PRICE] [decimal](6, 2) NULL, [PDI_CONSTRUCTION] [varchar](50) NULL, [PDI_NSA] [varchar](50) NULL, [PDI_REF_SUPPLIER] [char](13) NULL, [PDI_SIZE] [varchar](50) NULL, [PDI_CREATED_ON] [datetime] NOT NULL, [PDI_CREATED_BY] [varchar](100) NOT NULL, [PDI_MODIFIED_ON] [datetime] NULL, [PDI_MODIFIED_BY] [varchar](100) NULL, CONSTRAINT [PK_T_PRODUCT_LIST_DEMO_PLD] PRIMARY KEY CLUSTERED ( [PED_ID] ASC, [PDI_BARCODE] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] ADD CONSTRAINT [DF__T_PRODUCT__PLD_C__008BB26A] DEFAULT (getdate()) FOR [PDI_CREATED_ON] GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] ADD CONSTRAINT [DF__T_PRODUCT__PLD_C__017FD6A3] DEFAULT (suser_sname()) FOR [PDI_CREATED_BY] GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] WITH CHECK ADD CONSTRAINT [FK_T_PRODUCT_LIST_DEMO_PLD_T_ACTIVE_PERCENTAGE_DEMO_APD] FOREIGN KEY([PED_ID]) REFERENCES [S_PROMO].[T_PERCENTAGE_DEMO_PED] ([PED_ID]) GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] CHECK CONSTRAINT [FK_T_PRODUCT_LIST_DEMO_PLD_T_ACTIVE_PERCENTAGE_DEMO_APD] GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] WITH CHECK ADD CONSTRAINT [CK_DOUBLE_PROMO_DEMO] CHECK (([S_PROMO].[UF_CHECK_IF_DOUBLE_PROMO_DEMO]([PED_ID],[PDI_BARCODE])=(0))) GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] CHECK CONSTRAINT [CK_DOUBLE_PROMO_DEMO] GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] WITH CHECK ADD CONSTRAINT [CK_VERIFY_CHECK_DIGIT_DEMO_IN] CHECK (([DBO].[UF_VERIFY_CHECK_DIGIT]([PDI_BARCODE])=(1))) GO ALTER TABLE [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] CHECK CONSTRAINT [CK_VERIFY_CHECK_DIGIT_DEMO_IN] GO
La première contrainte vérifie qu'un des articles n'est pas déjà utilisé dans une autre promo qui a lieu au même moment.
La seconde vérifie que le barcode (qui est au format EAN13) est bien correct.
Si j'ai bien compris, la première fait partie du groupe table et la seconde du groupe ligne. Correct ?
Ta remarque veut-elle dire que, lorsque deux contraintes sont classées dans le même groupe, c'est qu'il y a un problème ??
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
* * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *
Partager