Vous pouvez le faire de deux façons.
- Créez un script d'insertion pour chaque table unique. Ceci est plus facile à programmer, mais nécessite un travail supplémentaire pour chaque nouvelle dimension ajoutée.
- Créez un script qui identifie dynamiquement les dimensions, la valeur de clé et la valeur "Inconnu" appropriée en fonction du type de données pour chaque attribut. Cela peut être très compliqué à créer, mais est auto-maintenu tant que vous n'ajoutez aucun nouveau type de données.
Je m'attends à ce que le meilleur choix dépend entièrement du nombre de tables de dimension dont vous disposez et de la fréquence à laquelle vous en ajoutez de nouvelles.
MISE À JOUR
Pour ce que ça vaut, voici une procédure stockée je l'ai écrit il y a quelques années. Je suis sûr qu'il pourrait utiliser une mise à jour, et pour une raison quelconque, mon système ne reconnaît plus les caractères de saut de ligne, mais il devrait vous être proche.
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
ALTER PROCEDURE [dbo].[InsertDimSeedRecords]
/*
-----------------------------------------------------------------------------------------------------------
Object Name: dbo.InsertDimSeedRecords
Project: Enterprise Data Warehouse
Purpose: Used to add seed rows to dimension tables, identified as tables prefixed with
Dim or contained in the dim schema.
Detailed description:
1. Identifies all dimension tables based on the Table and Schema parameters
2. Drops Constraints preventing changes to table data
3. Deletes seed values or Truncates tables based on TruncateData parameter
4. Generates new seed value insert statements
5. Inserts new records into table.
6. Re-create constraints
7. Enable constraints (currently disabled)
Example:
EXEC dbo.InsertDimSeedRecords
@DimTableName = 'All',
@Schema = 'All',
@DisplayResults = 'Y',
@ExecuteActions = 'N'
Parameters:
DimTableName - Accepts the Table Name by itself or qualified with the schema name for backward compatibility.
Values 'DimWorkOrder' and 'dbo.DimWorkOrder' will affect the same table.
'All' can be used to affect all dim tables in the specified schema.
@Schema - The schema name to affect. Ex: 'dim','dbo'; Default is 'dbo'
@TruncateData - If 'Y', truncates the dimension tables prior to reseeding.
If 'N', deletes the seed values (negative SK) from the table and inserts newly generated seed values.
Default is 'N'
@DisplayResults - If 'Y', displays a detailed list of all actions executed/planned, including successful actions.
If 'N', Successful actions are not displayed. Default = 'N'
@DisplayErrors - If 'Y', displays all ations that failed to execute, with error numbers and return codes
If 'N', no error details are returned, a ReturnCode is the only result set.
Use 'N' in automated or scripted tasks
Default is 'N'
@ExecuteActions - If 'N', all the tasks will be generated, but not executed. Use this to check what actions would
be performed without making any changes.
If 'Y', all tasks will be executed.
Default is 'Y' to allow for backward compatibility with previous versions
-----------------------------------------------------------------------------------------------------------
Rev | Date Modified | Developer | Change Summary
-----------------------------------------------------------------------------------------------------------
1 | 2013-11-01 | XXXXXXXX | Created
*/
@DimTableName SYSNAME,
@Schema SYSNAME = 'dbo',
@TruncateData CHAR(1) = 'N',
@DisplayResults CHAR(1) = 'N',
@DisplayErrors CHAR(1) = 'N',
@ExecuteActions CHAR(1) = 'Y'
AS
BEGIN
--/*
--*/
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#ErrorLog') IS NOT NULL
BEGIN
DROP TABLE #ErrorLog;
END
CREATE TABLE #ErrorLog (
TableObject NVARCHAR(256),
StepNum INT,
StepCommand NVARCHAR(MAX),
ErrorMessage NVARCHAR(4000),
ErrorNumber INT,
ErrorSeverity INT,
ErrorState INT,
ErrorLine INT,
ErrorProcedure NVARCHAR(200)
);
DECLARE @TableNameCRSR SYSNAME,
@SchemaNameCRSR SYSNAME;
DECLARE Table_Cursor CURSOR --Retrieve all tables to be affected
FOR
SELECT SCHEMA_NAME(o.schema_id),
o.NAME
FROM sys.objects AS O
WHERE o.type = 'U' --U = User Table
AND (
--All Dim tables from All eligible schemas
(
@Schema = 'All'
AND (
SCHEMA_NAME(o.schema_id) = 'dim'
OR o.NAME LIKE 'Dim%'
)
AND SCHEMA_NAME(o.schema_id) <> 'ref'
)
--tables from a specific schema
OR (
SCHEMA_NAME(o.schema_id) = @Schema
AND (
-- A specific table
o.NAME = @DimTableName
-- All dim tables
OR (
@DimTableName = 'All'
AND (
o.NAME LIKE '%Dim%'
OR @Schema = 'dim'
)
)
)
)
OR (SCHEMA_NAME(o.schema_id) + '.' + o.NAME = @DimTableName) --For legacy Schema Qualified @DimTableName values
)
AND NOT o.NAME IN (
--Add excluded/protected tables here
'MasterPackageControl', 'MasterPackageControl_Archive', 'ETLConfiguration', 'Date', 'Time'
);
OPEN Table_Cursor;
FETCH NEXT
FROM Table_Cursor
INTO @SchemaNameCRSR,
@TableNameCRSR
DECLARE @SQLCommand VARCHAR(MAX) = '',
@ProcOrder CHAR(1);
WHILE @@Fetch_Status = 0
BEGIN
DECLARE Worker_Cursor CURSOR
--Cursor to hold all of the commands in the correct processing order;
--this ensures that data is modified after constraints are dropped and before they are re-created,
--and that no constraint definitions are lost
FOR
WITH SQLConstraints
AS (
SELECT SQLDrop = 'RAISERROR (N''Dropping CONSTRAINT ' + OBJECT_NAME(fkc.constraint_object_id) + ''' , 10, 1) WITH NOWAIT;
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = Object_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.constraint_object_id) + ']'') AND parent_object_id =OBJECT_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.parent_object_id) + ']'') ' + ')
BEGIN
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(OBJECT_NAME(fkc.constraint_object_id)) + '' + CHAR(13) + CHAR(10) + 'END
',
SQLDisable = 'RAISERROR (N''Disabling CONSTRAINT ' + OBJECT_NAME(fkc.constraint_object_id) + ''' , 10, 1) WITH NOWAIT;
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = Object_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.constraint_object_id) + ']'') AND parent_object_id =OBJECT_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.parent_object_id) + ']'') ' + ')
BEGIN
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' NOCHECK CONSTRAINT ' + QUOTENAME(OBJECT_NAME(fkc.constraint_object_id)) + '' + CHAR(13) + CHAR(10) + 'END
' --+ ' ON DELETE CASCADE'
,
SQLAdd = 'RAISERROR (N''Creating CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ ']'' , 10, 1) WITH NOWAIT;
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' WITH NOCHECK ADD CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ '] FOREIGN KEY(' + QUOTENAME(C.NAME) + ') REFERENCES ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.referenced_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) + '(' + QUOTENAME(RC.NAME) + ')
'
--+ ' ON DELETE CASCADE'
,
LenConstraintName = LEN('FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id)),
SQLEnable = 'RAISERROR (N''Enabling CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ ']'' , 10, 1) WITH NOWAIT;
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' WITH CHECK CHECK CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) + ']
',
NumRank = ROW_NUMBER() OVER (
ORDER BY OBJECT_SCHEMA_NAME(fkc.parent_object_id),
OBJECT_NAME(fkc.parent_object_id)
),
ReferencedTable = OBJECT_NAME(fkc.referenced_object_id),
ReferencedColumn = RC.NAME
FROM sys.foreign_key_columns AS FKC
INNER JOIN sys.columns AS C
ON fkc.parent_object_id = c.object_id
AND fkc.parent_column_id = c.column_id
INNER JOIN sys.columns AS RC
ON fkc.referenced_object_id = rc.object_id
AND fkc.referenced_column_id = rc.column_id
WHERE OBJECT_SCHEMA_NAME(fkc.referenced_object_id) = @SchemaNameCRSR
AND OBJECT_NAME(fkc.referenced_object_id) = @TableNameCRSR
),
SQLTables
AS (
SELECT SQLTruncate = '
RAISERROR (N''TRUNCATE TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
TRUNCATE TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + '
',
NumRank = ROW_NUMBER() OVER (
ORDER BY TABLE_SCHEMA,
TABLE_NAME
),
*
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_TYPE = 'Base Table'
AND TABLE_SCHEMA = @SchemaNameCRSR
AND TABLE_NAME = @TableNameCRSR
),
SQLInserts
AS (
SELECT DISTINCT SQLInsert = 'RAISERROR (N''Inserting ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
' + CASE
WHEN OBJECTPROPERTY(OBJECT_ID(QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME)), 'TableHasIdentity') = 1
THEN 'SET IDENTITY_INSERT ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ' ON
'
ELSE ''
END + '
INSERT INTO ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + '
(' + REPLACE(SUBSTRING((
SELECT ', ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
)', ', ', CHAR(13) + SPACE(10) + ', ') + '
VALUES
(
' + REPLACE(SUBSTRING((
SELECT ', ' + CASE
WHEN c2.column_name IN ('ModifiedDate', 'UpdateAuditKey')
THEN 'Null --' + c2.COLUMN_NAME
WHEN C2.COLUMN_NAME IN ('CreatedDate', 'EffectiveDate')
THEN '''' + CONVERT(VARCHAR(20), CURRENT_TIMESTAMP, 120) + ''' --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('InsertAuditKey')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('CurrentIndicator')
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('RowStamp')
THEN '''-1'' --' + c2.COLUMN_NAME
WHEN c2.data_type = 'bit'
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%char%'
OR c2.data_type = 'ntext'
THEN CASE
WHEN c2.character_maximum_length > 7
THEN '''Unknown'''
WHEN c2.character_maximum_length > 2
THEN '''Unk'''
ELSE '''U'''
END + ' --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%date%'
THEN '''19000101'' --' + c2.column_name
WHEN c2.data_type LIKE 'tinyint'
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%int%'
THEN '-1 --' + c2.COLUMN_NAME
WHEN c2.data_type IN ('numeric', 'decimal', 'float')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%binary%'
THEN 'cast(-1 as ' + DATA_TYPE + ISNULL('(' + CAST(Character_Maximum_length AS VARCHAR(5)) + '))', '') + ' --' + c2.COLUMN_NAME
END
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
),
', ', ', CHAR(13) + SPACE(10) + ', ') + '
(
' + REPLACE(SUBSTRING((
SELECT ', ' + CASE
WHEN c2.column_name IN ('ModifiedDate', 'UpdateAuditKey')
THEN 'Null --' + c2.COLUMN_NAME
WHEN C2.COLUMN_NAME IN ('CreatedDate', 'EffectiveDate')
THEN '''' + CONVERT(VARCHAR(20), CURRENT_TIMESTAMP, 120) + ''' --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('InsertAuditKey')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('CurrentIndicator')
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('RowStamp')
THEN '''-2'' --' + c2.COLUMN_NAME
WHEN c2.data_type = 'bit'
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%char%'
OR c2.data_type = 'ntext'
THEN CASE
WHEN c2.character_maximum_length > 13
THEN '''Not Applicable'''
WHEN c2.character_maximum_length > 2
THEN '''N/A'''
ELSE '''N'''
END + ' --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%date%'
THEN '''18991231'' --' + c2.column_name
WHEN c2.data_type LIKE 'tinyint'
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%int%'
THEN '-2 --' + c2.COLUMN_NAME
WHEN c2.data_type IN ('numeric', 'decimal', 'float')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%binary%'
THEN 'cast(-2 as ' + DATA_TYPE + ISNULL('(' + CAST(Character_Maximum_length AS VARCHAR(5)) + '))', '') + ' --' + c2.COLUMN_NAME
END
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
)
' + CASE
WHEN OBJECTPROPERTY(OBJECT_ID(QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME)), 'TableHasIdentity') = 1
THEN 'SET IDENTITY_INSERT ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ' OFF
'
ELSE ''
END + '
', ', ', CHAR(10) + CHAR(13) + SPACE(10) + ', ')
FROM INFORMATION_SCHEMA.COLUMNS AS C1
INNER JOIN INFORMATION_SCHEMA.TABLES AS T
ON C1.TABLE_CATALOG = T.TABLE_CATALOG
AND C1.TABLE_SCHEMA = T.TABLE_SCHEMA
AND C1.TABLE_NAME = T.TABLE_NAME
WHERE 1 = 1
AND t.TABLE_TYPE <> 'VIEW'
AND t.TABLE_SCHEMA = @SchemaNameCRSR
AND t.TABLE_NAME = @TableNameCRSR
),
SQLCleanKey
AS (
SELECT SQLCommand = 'RAISERROR (N''Delete keys from ' + QUOTENAME(tc.TABLE_SCHEMA) + '.' + QUOTENAME(tc.TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
DELETE FROM ' + QUOTENAME(TC.TABLE_SCHEMA) + '.' + QUOTENAME(TC.TABLE_NAME) + ' WHERE ' + QUOTENAME(ccu.COLUMN_NAME) + ' < 0'
FROM INFORMATION_SCHEMA.constraint_column_usage AS CCU
INNER JOIN INFORMATION_SCHEMA.table_constraints AS TC
ON CCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
AND CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
AND CCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.TABLE_SCHEMA = @SchemaNameCRSR
AND tc.TABLE_NAME = @TableNameCRSR
),
CommandsUnioned
AS (
SELECT SQLCommand = SQLDrop,
ProcOrder = 1
FROM SQLConstraints
WHERE @TruncateData = 'Y'
UNION ALL
SELECT SQLDisable,
ProcOrder = 2
FROM SQLConstraints
WHERE @TruncateData = 'N'
UNION ALL
SELECT SQLTruncate,
ProcOrder = 3
FROM SQLTables
WHERE @TruncateData = 'Y'
UNION ALL
SELECT SQLCommand,
ProcOrder = 4
FROM SQLCleanKey
WHERE @TruncateData = 'N'
UNION ALL
SELECT SQLInsert,
ProcOrder = 5
FROM SQLInserts
UNION ALL
SELECT SQLAdd,
ProcOrder = 6
FROM SQLConstraints
WHERE @TruncateData = 'Y'
UNION ALL
SELECT sqlenable,
procorder = 7
FROM sqlconstraints
)
SELECT SQLCommand,
ProcOrder
FROM CommandsUnioned
ORDER BY ProcOrder,
SQLCommand;
OPEN Worker_Cursor
FETCH NEXT
FROM Worker_Cursor
INTO @SQLCommand,
@ProcOrder
WHILE @@Fetch_Status = 0
BEGIN
BEGIN TRY
IF @ExecuteActions = 'Y'
BEGIN
EXECUTE (@SQLCommand);
END
INSERT INTO #ErrorLog (
TableObject,
StepNum,
StepCommand,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure
)
VALUES (
QUOTENAME(@SchemaNameCRSR) + '.' + QUOTENAME(@TableNameCRSR),
CAST(@ProcOrder AS INT),
@SQLCommand,
ISNULL(ERROR_MESSAGE(), '-'),
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), '-')
)
END TRY
BEGIN CATCH
INSERT INTO #ErrorLog (
TableObject,
StepNum,
StepCommand,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure
)
VALUES (
QUOTENAME(@SchemaNameCRSR) + '.' + QUOTENAME(@TableNameCRSR),
CAST(@ProcOrder AS INT),
@SQLCommand,
ERROR_MESSAGE(),
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), '-')
)
END CATCH
FETCH NEXT
FROM Worker_Cursor
INTO @SQLCommand,
@ProcOrder
END
CLOSE Worker_Cursor;
DEALLOCATE Worker_Cursor;
FETCH NEXT
FROM Table_Cursor
INTO @SchemaNameCRSR,
@TableNameCRSR
END
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;
DECLARE @ret_code INT;
SELECT @ret_code = MAX(ISNULL(ErrorNumber, 0))
FROM #ErrorLog;
IF @DisplayResults = 'Y'
OR @ret_code <> 0
BEGIN
SELECT TableObject,
StepNum,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure,
StepCommand
FROM #ErrorLog
WHERE (
(
@DisplayErrors = 'Y'
AND ErrorNumber IS NOT NULL
)
OR @DisplayResults = 'Y'
)
ORDER BY StepNum,
TableObject,
StepCommand
END
RETURN (@ret_code)
END
GO
Y at-il quelque chose que vous avez essayé? – SchmitzIT
Vous pouvez utiliser des valeurs nulles au lieu de mettre en place des valeurs de support qui représentent null, mais difficile à dire si cela fonctionnerait car vous n'avez fourni aucun schéma ou donnée d'échantillon – Tanner
@Tanner J'ai ajouté l'exemple de référence de plz. Je peux garder dans un fichier texte et un shell pour exécuter ce fichier. pouvez-vous suggérer un moyen facile d'automatiser. – Pirinthan