有没有动态脚本可以
最近我生成了以下脚本,它帮助我将数据从生产环境重新加载(改造)到非生产环境:
DECLARE @linkedServerName NVARCHAR(255) = 'ProductionLinkedServer'
DECLARE @DatabaseName NVARCHAR(255) = 'DeliveryPromiseGlobal'
DECLARE @Schema NVARCHAR(255) = 'dbo'
DECLARE @DropForeignKeyTemplate NVARCHAR(MAX) = 'ALTER TABLE %s DROP CONSTRAINT %s;';
DECLARE @CreateForeignKeyTemplate NVARCHAR(MAX) = 'ALTER TABLE %s WITH CHECK ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);';
DECLARE @TruncateTemplate NVARCHAR(MAX) = 'TRUNCATE TABLE %s;';
DECLARE @InsertDataTemplate NVARCHAR(MAX) = 'SET IDENTITY_INSERT %s ON; INSERT INTO %s SELECT * FROM %s.%s.%s.%s; SET IDENTITY_INSERT %s OFF;';
DECLARE @DprTables TABLE (
TableName NVARCHAR(MAX),
ForeignKeyTableName NVARCHAR(MAX),
ForeignKeyConstraintName NVARCHAR(MAX),
DropForeignKeyScript NVARCHAR(MAX),
CreateForeignKeyScript NVARCHAR(MAX),
TruncateScript NVARCHAR(MAX),
HasForeignKey BIT,
InsertDataScript NVARCHAR(MAX) -- New column for insert data script
);
INSERT INTO @DprTables (TableName, ForeignKeyTableName, ForeignKeyConstraintName, DropForeignKeyScript, CreateForeignKeyScript, TruncateScript, HasForeignKey, InsertDataScript)
SELECT t.name AS TableName,
OBJECT_NAME(fk.referenced_object_id) AS ForeignKeyTableName,
fk.name AS ForeignKeyConstraintName,
IIF(fk.name is not null, FORMATMESSAGE(@DropForeignKeyTemplate, QUOTENAME(t.name),QUOTENAME(fk.name)),'') AS DropForeignKeyScript,
IIF(fk.name IS NOT NULL, FORMATMESSAGE(@CreateForeignKeyTemplate,QUOTENAME(t.name),QUOTENAME(fk.name),STRING_AGG(QUOTENAME(c.COLUMN_NAME), ', ') WITHIN GROUP (ORDER BY ic.ORDINAL_POSITION) ,QUOTENAME(OBJECT_NAME(fk.referenced_object_id)),STRING_AGG(QUOTENAME(c.COLUMN_NAME), ', ')
WITHIN GROUP (ORDER BY ic.ORDINAL_POSITION)),
''
) AS CreateForeignKeyScript,
FORMATMESSAGE(@TruncateTemplate, QUOTENAME(t.name)) AS TruncateScript,
IIF(fk.name IS NOT NULL, 1, 0) AS HasForeignKey,
FORMATMESSAGE(@InsertDataTemplate,
QUOTENAME(t.name),
QUOTENAME(t.name),
QUOTENAME(@linkedServerName),
QUOTENAME(@DatabaseName),
QUOTENAME(@Schema),
QUOTENAME(t.name),
QUOTENAME(t.name)) AS InsertDataScript -- Insert data script from linked server
FROM sys.tables t
LEFT JOIN sys.foreign_keys fk ON fk.parent_object_id = t.object_id
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ic ON fk.name = ic.CONSTRAINT_NAME
LEFT JOIN INFORMATION_SCHEMA.COLUMNS AS c ON ic.TABLE_NAME = c.TABLE_NAME AND ic.COLUMN_NAME = c.COLUMN_NAME
where isnull(fk.name,'') <> 'FK_DprAdvanceScoring_RuleId'
GROUP BY t.name, fk.name, fk.referenced_object_id
ORDER BY fk.name DESC, t.name;
--CREATE LINKED SERVER IF NOT ALREADY EXISTS
-- Check if the linked server already exists
DECLARE @existingLinkedServer NVARCHAR(255)
SELECT @existingLinkedServer = name
FROM sys.servers
WHERE name = @linkedServerName
IF @existingLinkedServer IS NULL
BEGIN
EXEC sp_addlinkedserver
@server = @linkedServerName, -- Name of the linked server
@srvproduct = '',
@provider = 'SQLNCLI', -- Provider for SQL Server
@datasrc = 'serveraddress,port', -- IP address and port of the server
@provstr = 'UID=userId;PWD=password'; -- SQL Server authentication credentials
PRINT 'Linked server created successfully.'
END
ELSE
BEGIN
PRINT 'Linked server already exists.'
END
--执行脚本 声明 @SqlCommand NVARCHAR(MAX); DECLARE @Commands TABLE(命令 NVARCHAR(MAX));
-- Populate the @Commands table with all commands
INSERT INTO @Commands (Command)
SELECT DropForeignKeyScript FROM @DprTables where DropForeignKeyScript <> '' GROUP BY DropForeignKeyScript
UNION ALL
SELECT TruncateScript FROM @DprTables where TruncateScript <> '' GROUP BY TruncateScript
UNION ALL
SELECT InsertDataScript FROM @DprTables where InsertDataScript <> '' GROUP BY InsertDataScript
UNION ALL
SELECT CreateForeignKeyScript FROM @DprTables where CreateForeignKeyScript <> '' GROUP BY CreateForeignKeyScript
-- Initialize loop variables
DECLARE @RowCount INT = (SELECT COUNT(*) FROM @Commands)
DECLARE @Counter INT = 1
--SELECT * FROM @COMMANDS
-- Loop through each command and execute it
WHILE @Counter <= @RowCount
BEGIN
SELECT @SqlCommand = Command
FROM @Commands
WHERE (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) = @Counter
-- Execute the command
EXEC sp_executesql @SqlCommand
SET @Counter = @Counter + 1
END