Cet article propose des fonctions et des vues afin de connaître les composante d’une base de données, ainsi que des vues pour pouvoir recréer ces objets.
Cet article s’est limité aux objets INDEX et contraintes. Nous la poursuivrons par d’autres articles consacré à la rétro ingénierie des données, des tables et du code..
ATTENTION : certaines vues utilisent des fonctions et d’autres d’autres vues. Bref, il vous faut la plupart du temps tous ces objets pour faire fonctionner cet outil.
1 – une fonction qui créée la liste des colonnes d’un index
CREATE FUNCTION dbo.F_INDEXCOLS (@schemaname NVARCHAR(128),
@tablename NVARCHAR(128),
@indexname NVARCHAR(128))
RETURNS NVARCHAR(2192)
AS
BEGIN
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Recherche la liste des colonnes d'un index dans l'ordre positionnel des *
* colonnes de cet index et avec le sens du tri *
*******************************************************************************
* paramètres : @schemaname nom du schéma de la table (si NULL ou vide dbo) *
* @tablename nom de la table *
* @indexname nom de l'index *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
-- si table ou index null renvoi null
IF @tablename IS NULL OR @indexname IS NULL
RETURN NULL;
-- recherche de l'id de la table
SET @schemaname = COALESCE(NULLIF(@schemaname, ''), 'dbo');
DECLARE @XID INT, @TID INT;
SELECT @XID = indid
FROM sysindexes
WHERE name = @indexname;
SET @TID = OBJECT_ID('['+@schemaname + '].[' + @tablename+']');
-- si la table n'est pas trouvée, rencoie NULL
IF @TID IS NULL
RETURN NULL
-- variable de retour
DECLARE @COLS NVARCHAR(2192);
SET @COLS = N'';
-- requête de concaténation
SELECT TOP 100 PERCENT WITH TIES
@COLS = @COLS + '['+c.name
+ CASE
WHEN INDEXKEY_PROPERTY(@TID, @XID, keyno, 'IsDescending') = 1
THEN '] ASC, '
ELSE '], '
END
FROM sysindexes i
INNER JOIN sysobjects o
on i.id = o.id
INNER JOIN sysindexkeys k
on k.indid = i.indid AND k.id = i.id
INNER JOIN syscolumns c
on k.colid = c.colid and o.id = c.id
WHERE o.name = @tablename
AND i.name = @indexname
ORDER BY keyno
-- pas de colonne dans cet index ?
IF COALESCE(@COLS, '') <> ''
SET @COLS = SUBSTRING(@COLS, 1, LEN(@COLS) - 1)
RETURN @COLS
END
2 – une fonction qui créée la liste des colonnes d’une contrainte
CREATE FUNCTION dbo.F_CONSTRAINTCOLS (@constraint_schema NVARCHAR(128),
@constraint_name NVARCHAR(128))
RETURNS NVARCHAR(2064)
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Recherche la liste des colonnes d'une contrainte (en principe FOREIGN KEY) *
*******************************************************************************
* paramètres : @constraint_schema schéma de la contrainte (a défaut dbo) *
* @constraint_name nom de la contrainte *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
BEGIN
IF @constraint_name IS NULL
RETURN NULL;
DECLARE @COLS NVARCHAR(2064);
SET @COLS = N'';
SELECT @COLS = @COLS + '['+COLUMN_NAME + '],'
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
WHERE CONSTRAINT_SCHEMA = COALESCE(@constraint_schema, 'dbo')
AND CONSTRAINT_NAME = @constraint_name
IF COALESCE(@COLS, '') <> ''
SET @COLS = SUBSTRING(@COLS, 1, LEN(@COLS) - 1)
RETURN @COLS
END
3 – vue donnant les caractéristiques des index SQL
CREATE VIEW dbo.V_META_INDEX
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les index et l'ensemble de leurs paramètres hors stats et blobs *
*******************************************************************************
* colonnes : schema_name nom du schema auquel appartient la table ou la vue *
* table_name nom de la table ou de la vue *
* table_type type de table (base table ou vue) *
* index_name nom de l'index *
* col_number nombre de colonnes composant l'index *
* cols composition des colonnes de l'index *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT u.name as schema_name
, o.name as table_name
, CASE o.xtype
WHEN 'U' THEN 'TABLE'
WHEN 'V' THEN 'VUE'
END AS table_type
, i.name as index_name
, count(c.name) AS col_number
, dbo.F_META_INDEXCOLS(u.name, o.name, i.name) as cols
, CASE
WHEN EXISTS(SELECT *
FROM syscolumns cc
WHERE COLUMNPROPERTY(o.id , cc.name , 'IsIdentity' ) = 1
AND cc.id = o.id)
THEN 1
ELSE 0
END AS has_identity
, INDEXPROPERTY (o.id , i.name , 'IndexFillFactor') AS fill_Factor
, INDEXPROPERTY (o.id , i.name , 'IsPadIndex') AS pading_page
, INDEXPROPERTY (o.id , i.name , 'IsPageLockDisallowed') AS no_page_lock
, INDEXPROPERTY (o.id , i.name , 'IsRowLockDisallowed') AS no_row_lock
, INDEXPROPERTY (o.id , i.name , 'IsClustered') AS cluster
, INDEXPROPERTY (o.id , i.name , 'IsUnique') AS unic
, CONSTRAINT_TYPE
, CASE o.xtype
WHEN 'U' THEN 'TABLE UTILISATEUR'
WHEN 'V' THEN 'VUE'
END AS TABLE_TYPE
FROM sysindexkeys k
INNER JOIN sysobjects o
on o.id = k.id
INNER JOIN sysusers u
on o.uid = u.uid
INNER JOIN sysindexes i
on k.indid = i.indid AND k.id = i.id
INNER JOIN syscolumns c
on k.colid = c.colid and o.id = c.id
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
on tc.TABLE_NAME = o.name AND tc.CONSTRAINT_NAME = i.name
WHERE o.xtype IN ('U', 'V')
AND o.name <> 'dtproperties'
AND INDEXPROPERTY (o.id , i.name , 'IsFulltextKey') = 0
AND INDEXPROPERTY (o.id , i.name , 'IsStatistics') = 0
GROUP BY u.name, o.name, i.name, o.id, CONSTRAINT_TYPE, o.xtype
4 – vue donnant la définition des contraintes DEFAULT
CREATE VIEW dbo.V_META_DEFAULT_CONSTRAINT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les contraintes de type DEFAULT *
*******************************************************************************
* colonnes : TABLE_SCHEMA nom du schema auquel appartient la table *
* TABLE_NAME nom de la table *
* DEFAULT_CONSTRAINT_NAME nom de la contrainte DEFAULT *
* DEFAULT_VALUE valeur à défaut (entre parenthèses) *
* COLUMN_NAME nom de la colonne visée par défaut *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT TABLE_SCHEMA, TABLE_NAME, o.name AS DEFAULT_CONSTRAINT_NAME,
COLUMN_DEFAULT AS DEFAULT_VALUE, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
INNER JOIN syscolumns c
ON OBJECT_ID('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']') = c.id
INNER JOIN sysobjects o
ON c.cdefault = o.id
WHERE COLUMN_DEFAULT IS NOT NULL
AND TABLE_SCHEMA +'.' +TABLE_NAME <> 'dbo.dtproperties'
5 – vue donnant la définition des contraintes CHECK
CREATE VIEW dbo.V_META_CHECK_CONSTRAINT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les contraintes de type DEFAULT *
*******************************************************************************
* colonnes : TABLE_SCHEMA nom du schema auquel appartient la table *
* TABLE_NAME nom de la table *
* CHECK_CONSTRAINT_NAME nom de la contrainte DEFAULT *
* CHECK_CLAUSE prédicat de contrainte (entre parenthèse) *
* COLUMN_NAME nom de la colonne visée par défaut *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT TABLE_SCHEMA, TABLE_NAME, CC.CONSTRAINT_NAME AS CHECK_CONSTRAINT_NAME,
CHECK_CLAUSE
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN INFORMATION_SCHEMA.CHECK_CONSTRAINTS AS CC
ON TC.CONSTRAINT_SCHEMA = CC.CONSTRAINT_SCHEMA
AND CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
6 – vue donnant la définition des contraintes FOREIGN KEY
CREATE VIEW dbo.V_META_FOREIGNKEY_CONSTRAINT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les contraintes de type FOREIGN KEY *
*******************************************************************************
* colonnes : TABLE_SCHEMA nom du schema de la table contrainte *
* TABLE_NAME nom de la table contrainte *
* FOREIGNKEY_CONSTRAINT_NAME nom de la contrainte FOREIGN KEY *
* CONSTRAINT_COLS colonnes contraintes *
* REF_TABLE_SCHEMA nom du schema de la table référencée *
* REF_TABLE_NAME nom de la table référencée *
* REF_CONSTRAINT_COLS colonnes référencées *
* UPDATE_RULE mode de gestion du UPDATE *
* DELETE_RULE mode de gestion du DELETE *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT TCC.TABLE_SCHEMA, TCC.TABLE_NAME,
RC.CONSTRAINT_NAME AS FOREIGNKEY_CONSTRAINT_NAME,
dbo.F_META_CONSTRAINTCOLS(RC.CONSTRAINT_SCHEMA, RC.CONSTRAINT_NAME) AS CONSTRAINT_COLS,
TCR.TABLE_SCHEMA AS REF_TABLE_SCHEMA, TCR.TABLE_NAME AS REF_TABLE_NAME,
dbo.F_META_CONSTRAINTCOLS(UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME) AS REF_CONSTRAINT_COLS,
UPDATE_RULE, DELETE_RULE
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
-- table contrainte
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TCC
ON RC.CONSTRAINT_SCHEMA = TCC.CONSTRAINT_SCHEMA
AND RC.CONSTRAINT_NAME = TCC.CONSTRAINT_NAME
-- table ref
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TCR
ON RC.UNIQUE_CONSTRAINT_SCHEMA = TCR.CONSTRAINT_SCHEMA
AND RC.UNIQUE_CONSTRAINT_NAME = TCR.CONSTRAINT_NAME
7 – vue donnant la définition des contraintes PRIMARY KEY
CREATE VIEW dbo.V_META_PRIMARYKEY_CONSTRAINT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les contraintes de type PRIMARY KEY *
*******************************************************************************
* colonnes : TABLE_SCHEMA nom du schema de la table contrainte *
* TABLE_NAME nom de la table contrainte *
* PRIMARYKEY_CONSTRAINT_NAME nom de la contrainte PRIMARY KEY *
* CONSTRAINT_COLS colonnes contraintes *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT schema_name AS TABLE_SCHEMA, table_name AS TABLE_NAME,
index_name AS PRIMARYKEY_CONSTRAINT_NAME, cols AS CONSTRAINT_COLS
FROM V_META_INDEX
WHERE table_type = 'TABLE'
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND schema_name + '.' + table_name <> 'dbo.dtproperties'
8 – vue donnant la définition des contraintes UNIQUE
CREATE VIEW dbo.V_META_UNIQUE_CONSTRAINT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Liste les contraintes de type UNIQUE *
*******************************************************************************
* colonnes : TABLE_SCHEMA nom du schema de la table contrainte *
* TABLE_NAME nom de la table contrainte *
* UNIQUE_CONSTRAINT_NAME nom de la contrainte UNIQUE *
* CONSTRAINT_COLS colonnes contraintes *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT schema_name AS TABLE_SCHEMA, table_name AS TABLE_NAME,
index_name AS PRIMARYKEY_CONSTRAINT_NAME, cols AS CONSTRAINT_COLS
FROM V_META_INDEX
WHERE table_type = 'TABLE'
AND CONSTRAINT_TYPE = 'UNIQUE'
9 – vue donnant les ordres SQL de création des contraintes PRIMARY KEY avec les méta données de l’index sous jacent
CREATE VIEW dbo.V_CREATE_PRIMARYKEY_INDEX
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les contraintes PRIMARY KEY avec les méta données d'indexation *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de la PRIMARY KEY *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'ALTER TABLE [' + schema_name + '].[' + table_name + '] ADD CONSTRAINT [' +
index_name + '] PRIMARY KEY ' +
CASE cluster WHEN 1 THEN 'CLUSTERED (' WHEN 0 THEN '(' END + cols +')' +
CASE WHEN fill_Factor > 0 THEN 'WITH FILLFACTOR = ' + CAST(fill_Factor AS VARCHAR(32)) + ' '
ELSE '' END +
'ON [' + groupname + '];' AS SQL_COMMAND
FROM V_META_INDEX MI
INNER JOIN sysindexes i
ON MI.index_name = i.name
INNER JOIN sysfilegroups fg
ON i.groupid = fg.groupid
WHERE table_type = 'TABLE'
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND schema_name + '.' + table_name <> 'dbo.dtproperties'
10 – vue donnant les ordres SQL de création des contraintes UNIQUE avec les méta données de l’index sous jacent
CREATE VIEW dbo.V_CREATE_UNIQUE_INDEX
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les contraintes UNIQUE avec les méta données d'indexation *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de la UNIQUE *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'ALTER TABLE [' + schema_name + '].[' + table_name + '] ADD CONSTRAINT [' +
index_name + '] UNIQUE ' +
CASE cluster WHEN 1 THEN 'CLUSTERED (' WHEN 0 THEN '(' END + cols +')' +
CASE WHEN fill_Factor > 0 THEN 'WITH FILLFACTOR = ' + CAST(fill_Factor AS VARCHAR(32)) + ' '
ELSE '' END +
'ON [' + groupname + '];' AS SQL_COMMAND
FROM V_META_INDEX MI
INNER JOIN sysindexes i
ON MI.index_name = i.name
INNER JOIN sysfilegroups fg
ON i.groupid = fg.groupid
WHERE table_type = 'TABLE'
AND CONSTRAINT_TYPE = 'UNIQUE'
11 – vue donnant les ordres SQL de création des index indépendats de toutes contraintes
CREATE VIEW dbo.V_CREATE_NONCONSTRAINED_INDEX
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les index indépendant des contraintes SQL (PRIMARY KEY, UNIQUE) *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de l'index *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'CREATE ' + CASE unic WHEN 1 THEN 'UNIQUE ' ELSE '' END +
'INDEX [' + index_name + '] ON [' + schema_name +'].[' + table_name + '] (' +
cols + ') ' +
CASE WHEN fill_Factor > 0 THEN 'WITH FILLFACTOR = ' + CAST(fill_Factor AS VARCHAR(32)) + ' '
ELSE '' END +
'ON [' + groupname + '];' AS SQL_COMMAND
FROM V_META_INDEX MI
INNER JOIN sysindexes i
ON MI.index_name = i.name
INNER JOIN sysfilegroups fg
ON i.groupid = fg.groupid
WHERE TABLE_TYPE = 'TABLE'
AND CONSTRAINT_TYPE IS NULL
12 – vue donnant les ordres SQL de création des contraintes DEFAULT
CREATE VIEW dbo.V_CREATE_DEFAULT
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les ordre SQL de création des contraintes DEFAULT *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de la contrainte *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'ALTER TABLE [' + TABLE_SCHEMA +'].[' + TABLE_NAME +
'] ADD CONSTRAINT [' + DEFAULT_CONSTRAINT_NAME + '] DEFAULT ' +
DEFAULT_VALUE + ' FOR [' + COLUMN_NAME +'];' AS SQL_COMMAND
FROM dbo.V_META_DEFAULT_CONSTRAINT
WHERE TABLE_SCHEMA + '.' + TABLE_NAME <> 'dbo.dtproperties'
13 – vue donnant les ordres SQL de création des contraintes CHECK
CREATE VIEW dbo.V_CREATE_CHECK
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les ordre SQL de création des contraintes CHECK *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de la contrainte *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'ALTER TABLE [' + TABLE_SCHEMA +'].[' + TABLE_NAME +
'] ADD CONSTRAINT [' + CHECK_CONSTRAINT_NAME + '] CHECK ' + CHECK_CLAUSE
AS SQL_COMMAND
FROM dbo.V_META_CHECK_CONSTRAINT
14 – vue donnant les ordres SQL de création des contraintes FOREIGN KEY
CREATE VIEW dbo.V_CREATE_FOREIGNKEY
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les ordre SQL de création des contraintes FOREIGN KEY *
*******************************************************************************
* colonnes : SQL_COMMAND contient l'ordre SQL de création de la contrainte *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
******************************************************************************/
SELECT 'ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME +
'] ADD CONSTRAINT [' + FOREIGNKEY_CONSTRAINT_NAME + '] FOREIGN KEY (' +
CONSTRAINT_COLS +') REFERENCES [' + REF_TABLE_SCHEMA + '].[' +
REF_TABLE_NAME + '] (' + REF_CONSTRAINT_COLS + ')' +
UPDATE_RULE + ' ' + DELETE_RULE AS SQL_COMMAND
FROM dbo.V_META_FOREIGNKEY_CONSTRAINT
15 – vue donnant les ordres Transact SQL de modifiction des index pour le paramétrage fin
CREATE VIEW dbo.V_ALTER_INDEX
AS
/******************************************************************************
* Frédéric Brouard - SQLpro - http://www.sqlspot.com - 2008-08-28 *
*******************************************************************************
* Génère les modification nécessaires au paramétrage fin des index *
*******************************************************************************
* colonnes : SQL_COMMAND contient les ordres SQL de création de l'index *
* NOTA : il est conseillé de jouer cette vue dans l'analyseur de requête *
* avec sortie des résultats en mode texte (sauts de ligne et GO) *
*******************************************************************************
* copyright F. Brouard / SQLpro / SQLspot - pour ebuyclub.com *
*******************************************************************************/
SELECT 'CREATE ' + CASE unic WHEN 1 THEN 'UNIQUE ' ELSE '' END +
CASE cluster WHEN 1 THEN 'CLUSTERED ' ELSE '' END +
'INDEX [' + index_name + '] ON [' + schema_name +'].[' + table_name + '] (' +
cols + ') WITH ' +
CASE WHEN pading_page = 1 THEN 'PAD_INDEX, ' ELSE '' END +
CASE WHEN fill_Factor > 0 THEN 'FILLFACTOR = ' + CAST(fill_Factor AS VARCHAR(32)) +', '
ELSE '' END +
'DROP_EXISTING ON [' + groupname + '];' + CHAR(13) + CHAR(10) +
'GO' +CHAR(13) + CHAR(10) +
CASE WHEN no_page_lock = 1 THEN 'EXEC sp_indexoption ''[' + schema_name +'].[' +
table_name +'].[' +index_name + ']'', ''DisAllowPageLocks'', 1;' +
CHAR(13) + CHAR(10) + 'GO' +CHAR(13) + CHAR(10) ELSE '' END +
CASE WHEN no_row_lock = 1 THEN 'EXEC sp_indexoption ''[' + schema_name +'].[' +
table_name +'].[' +index_name + ']'', ''DisAllowRowLocks'', 1;' +
CHAR(13) + CHAR(10) + 'GO' +CHAR(13) + CHAR(10) ELSE '' END AS SQL_COMMAND
FROM V_META_INDEX MI
INNER JOIN sysindexes i
ON MI.index_name = i.name
INNER JOIN sysfilegroups fg
ON i.groupid = fg.groupid
***
Frédéric BROUARD – SQLpro – MVP SQL Server
Spécialiste SQL/BD modélisation de données
SQL & SGBDR http://sqlpro.developpez.com/
Expert SQL Server : http://www.sqlspot.com
audits – optimisation – tuning – formation