CREATE DOMAIN vs CREATE TYPE
Bonjour,
Quelqu'un peut m'expliquer pourquoi MS SQL SERVER ne permet la création de domaine à l'aide de la commande CREATE DOMAIN ?
je rappelle qu'un domaine est un alias de type (natif) sur lequel on peut définir des contraintes (CHECK, NOT NUL, ...). Selon la norme SQL on peut définir un domaine en utilisant la commande CREATE DOMAIN.
Exemple :
--------
Code:
1 2 3
| CREATE DOMAIN D_CONTINENT AS CHAR(8)
DEFAULT 'AFRIQUE'
CONSTRAINT CHK_D_CONTINENT CHECK (VALUE IN ('AFRIQUE','AMERIQUE','ASIE','EUROPE','OCEANIE')) |
=> Quels sont les avantages de l'utilisation des domaines dans un SGBD ?
1. Uniformisation des types de données : on ne verra pas par exemple pour une même base de données une table avec une colonne TELEPHONE avec le type VARCHAR(15) et dans une autre table TELEPHONE avec VARCHAR(20)
2. Lisibilité des types de données + qualité des données: choix des types appropriés des types prédéfinis + les contraintes
3. Il paraît que l'utilisation des domaines à la place des types standards permet d'optimiser l'espace RAM.
=> Et les inconvénients ?
1. ALTER DOMAIN ne permet pas de modifier les types de données (prédéfinis): ALTER DOMAIN ne s'applique que pour les DEFAULT et les CONTRAINTs
2. Problèmes avec DROP DOMAIN :
Code:
DROP DOMAIN name [ CASCADE | RESTRICT ]
et ses prob
la suppression du domaine devrait en principe préserver les colonnes et leurs appliquer le type standard (built-in) sur le lequel le domaine était définit.
Par exemple sous PostGreSQL 9.1, j'ai constaté que la suppression de domaine avec l'option RESTRICT renvoie l'erreur suivante :
Citation:
ERREUR: n'a pas pu supprimer type d_continent car d'autres objets en dépendent
État SQL :2BP01
Détail :table t_cont colonne col dépend de type d_continent
Astuce : Utilisez DROP ... CASCADE pour supprimer aussi les objets dépendants.
Et lorsque j'utilise l'option CASCADE, non seulement le domaine est supprimé mais aussi TOUTES LES COLONNES BASÉES SUR CE DOMAIN !
=> Quand est-il de l'indexation des colonnes utilisant des domaines ?
=> Pourquoi MS SQL SERVER au lieu d'implémenter la commande CREATE DOMAIN préfère des bidouilles du genre pour avoir un résultat similaire ?
Code:
1 2 3 4
| CREATE TYPE toto ....
CREATE RULE R_toto ...
EXEC sp_bindrule R_toto ...
EXEC sp_bindefault .... |
chose curieuse le Book On Line recommande de ne plus utiliser CREATE RULE !
Citation:
CREATE RULE will be removed in a future version of Microsoft SQL Server. Avoid using CREATE RULE in new development work, and plan to modify applications that currently use it. We recommend that you use check constraints instead. Check constraints are created by using the CHECK keyword of CREATE TABLE or ALTER TABLE. For more information, see CHECK Constraints.
Quelqu'un peut m'éclairer ?
Merci d'avance
petite modification pour la génération des scripts
Bonjour,
J'utilise souvent la fonctionnalité générer les scripts d'une base de données.
Parfois pour générer les tables et d'autres fois pour les données.
Pour choisir l'une ou l'autre des options il faut cliquer sur le bouton [Avancé] de la deuxième étape.
Comme il reste de la place dans l'écran, j'aimerais qu'on mette les trois options :
Générer la structure seulement
Générer les données seulement
Générer la structure et les données
Dans trois cases à cocher dans l'écran et non dans la boite de dialogue de paramètres avancés.
Bien à vous
Laurent
Ipv4, IPv6 : Stockage et Opérations
La norme SQL n'a jusqu'à ce jour rien prévu pour le stockage de type donnée IP. Inutile de rappeler ici l'importance et la place de l'adresse ip dans le monde professionnel et personnel. A-t-on besoin de stocker des adresses IP dans une base de donnée relationnelles ? Voici une réponse
Et pourtant rien n'est fait côté SQL Server pour mettre à disposition un type capable de stocker une adresse ip et faciliter les opérations sur cette donnée.
Côté Oracle pareil. Du moins jusqu'à ce jour.
Prenons un cas pour illustrer le besoin :
Comment faire simplement un
Code:
SELECT IP_ADR FROM myTable WHERE IP_ADR > IP_ADR_MIN AND IP_ADR < IP_ADR_MAX
Bien sûr, en bidouillant avec la fonction PARSENAME de SQL Server on peut trouver une porte de sortie pour les IP stockés comme des types de caractères... Mais on ne gagne ni en productivité ni lisibilité ni en performance ...!
Saluons au passage le travail des développeurs du SGDB PostgreSQL sur ce point . PostgreSQL offre des types de données pour stocker IPv4, IPv6 et MAC ADRESSE. Les types CIDR et INET fournis par PostgreSQL permettent de stocker et d'effectuer des opérations ( =, >, <, <>,..) sur les adresses IP (IPv4 et IPv6)
Qu'est ce que les "grands" éditeurs de SGBD attendent ?
CHECK CONSTRAINT/ASSERTION : Personnaliser les messages d'erreurs
=> Contexte
En SQL la liste des types de contraintes que l'on peut poser sur une table est exhaustive : UNIQUE CONSTRAINT, PRIMARY KEY CONSTRAINT, REFERENTIAL CONSTRAINT et CHECK CONSTRAINT. Généralement, les messages d'erreurs renvoyés en cas de problèmes sur les contraintes d'unicité, de clé primaire ou d'intégrité référentielle sont clairs et permettent de rapidement solutionner le problème. Mais pour les contraintes de validation (CHECK) le message d'erreur est générique est est sous la forme :
Citation:
L'instruction %1! est en conflit avec la contrainte %2! "%3!". Le conflit s'est produit dans la base de données "%4!", table "%5!"%6!%7!%8!.
Vous pouvez le vérifier est exécutant la commande ci-après :
Code:
1 2
| SELECT text FROM sys.messages
WHERE message_id = 547 AND language_id = 1036 |
Noter que le message_id = 547 est le code d'erreur relatif au constraint CHECK et language_id = 1036 c'est pour avoir la traduction en français
=> Problème
Comment personnaliser directement les messages d'erreur lors de la définition d'un CONSTRAINT CHECK ou d'une ASSERTION SQL ?
C'est a dire quelque chose du genre :
Code:
1 2
| CREATE TABLE PERIODE (datedebut DATETIME, datefin DATETIME)
ALTER TABLE PERIODE ADD CONSTRAINT CHK_PERIODE CHECK (datedebut <= datefin) VIOLETED_CONSTRAINT_MESSAGE ('la date de debut doit être antérieure ou égale à la date de fin') |
=> Questions/Contournements
Je ne sais pas si SQL SERVER 2012 permet ce genre de chose. Je n'ai pas encore touché à SQL SERVER 2012 ;-)
En tout cas sur SQL Server 2008 R2 c'est pas possible !
Deux rustines sous SQL SERVER 2008R2 pour essayer de se rapprocher de la personnalisation des messages d'erreur pour les CONSTRAINTS CHECKs
--> 1. TRY/CATCH du code d'erreur 547
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ALTER PROCEDURE P_INSERT (@debut DATETIME,@fin DATETIME)
AS
BEGIN TRY
INSERT INTO PERIODE (datedebut,datefin) VALUES(@debut,@fin)
END TRY
BEGIN CATCH
IF @@ERROR = 547
RAISERROR ('la date de debut doit être antérieure ou égale à la date de fin',16,1)
END CATCH
EXEC P_INSERT '20120619','20120618'
/*
la date de debut doit être antérieure ou égale à la date de fin
*/ |
--> 2. TRIGGER
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| ALTER TRIGGER INSTEADOF_TR_PERIODE ON PERIODE
INSTEAD OF INSERT AS
BEGIN
DECLARE @debut DATETIME,@fin DATETIME
SELECT @debut = I.datedebut, @fin = I.datefin FROM INSERTED I
IF (@debut > @fin ) RAISERROR ('la date de debut doit être antérieure ou égale à la date de fin',16,1)
RETURN
END
INSERT INTO PERIODE (datedebut,datefin) VALUES('20120619','20120618')
/*
la date de debut doit être antérieure ou égale à la date de fin
*/ |