我有生產數據庫(例如,PROD1
)。它對另一個數據庫有很多同義詞(例如,PROD2
)。將所有同義詞更改爲另一個數據庫
我已經創建PROD2_TEST
(截至PROD2
完全複製),也PROD1_TEST
(截至PROD1
完整副本)。但結果我有PROD2
的同義詞,而不是PROD2_TEST
。
如何,我可以自動重新創建測試數據庫的所有同義詞?
我有生產數據庫(例如,PROD1
)。它對另一個數據庫有很多同義詞(例如,PROD2
)。將所有同義詞更改爲另一個數據庫
我已經創建PROD2_TEST
(截至PROD2
完全複製),也PROD1_TEST
(截至PROD1
完整副本)。但結果我有PROD2
的同義詞,而不是PROD2_TEST
。
如何,我可以自動重新創建測試數據庫的所有同義詞?
無法更改同義詞,您必須刪除並創建它們。以下文章包含用於爲一系列表創建同義詞的腳本。希望你可以修改它以滿足您的需求:
Use synonyms to abstract SQL Server objects
您可以使用sys.synonyms
視圖中查看所有現有的同義詞。在僞代碼,你想要做的是:
name
和base_object_name
PROD2
到PROD2_TEST
這裏的東西我用於重新映射所有同義詞在同一臺服務器上的一個新的數據庫(基於Tobsey的建議)
SET NOCOUNT ON;
DECLARE @db_name SYSNAME
DECLARE @schema_name SYSNAME
DECLARE @cmd NVARCHAR(256)
SET @schema_name = N'dbo'
SET @db_name = N'[newdb]'
DECLARE @schema_id INT
SELECT @schema_id = schema_id
FROM sys.schemas
WHERE NAME = @schema_name;
DECLARE @table_list TABLE (table_name SYSNAME,dest_table_name sysname,dest_schema_name sysname)
DECLARE @table_name SYSNAME
declare @dest_table_name sysname
declare @dest_schema_name sysname
DECLARE @prefix NVARCHAR(50)
DECLARE @synonym SYSNAME
DECLARE @linked_server SYSNAME
SET @linked_server = N'SERVER'
-- create a synonym for these tables (insert each table)
INSERT INTO @table_list (table_name,dest_table_name,dest_schema_name)
SELECT name
,'['+SUBSTRING(name,CHARINDEX('.',name,CHARINDEX('.',name,0)+1)+1,LEN(name)-CHARINDEX('.',name,CHARINDEX('.',name,0)+1))+']'
,SUBSTRING(name,CHARINDEX('.',name,0)+1,CHARINDEX('.',name,CHARINDEX('.',name,0)+1)-CHARINDEX('.',name,0)-1)
FROM sys.synonyms
WHERE base_object_name LIKE '![SERVER!].![olddb!]%' ESCAPE ('!')
ORDER BY name
IF EXISTS (
SELECT *
FROM sys.servers
WHERE NAME = @linked_server
)
-- 4 part name
SET @prefix = @linked_server + N'.' + @db_name
ELSE
-- 3 part name
SET @prefix = @db_name
SELECT TOP 1 @table_name = table_name,@dest_table_name = dest_table_name,@dest_schema_name=dest_schema_name
FROM @table_list
WHILE @table_name IS NOT NULL
BEGIN
-- set the schema and name for the synonym
SET @synonym = @schema_name+ N'.' + '['[email protected]_name+']'
-- delete the synonym if it exists
IF EXISTS (
SELECT *
FROM sys.synonyms
WHERE NAME = @table_name
AND schema_id = @schema_id
)
BEGIN
SET @cmd = N'drop synonym ' + @synonym
PRINT @cmd
--EXEC sp_executesql @cmd
END
-- create the synonym
SET @cmd = N'create synonym ' + @synonym + N' for ' + @prefix + N'.'+ @dest_schema_name + N'.'+ @dest_table_name
PRINT @cmd
--EXEC sp_executesql @cmd
PRINT 'GO'
DELETE TOP (1)
FROM @table_list
SET @table_name = NULL
SELECT TOP 1 @table_name = table_name,@dest_table_name = dest_table_name,@dest_schema_name=dest_schema_name
FROM @table_list
END
GO
我不得不爲同樣的原因,做到這一點,這是查詢我用過的。運行查詢,將結果複製粘貼到新服務器(PROD_Test)並運行生成的查詢。它可以處理不同的模式名稱和多個數據庫的情況下,你使用它們:
SELECT 'Drop Synonym [' + SCHEMA_NAME(schema_id) + '].[' + PARSENAME(base_object_name,1) + '];CREATE SYNONYM [' +
SCHEMA_NAME(schema_id) + '].[' + PARSENAME(base_object_name,1) + '] FOR [' + COALESCE(PARSENAME(base_object_name,3),DB_NAME(DB_ID())) + '_Test].['
+ COALESCE(PARSENAME(base_object_name,2),SCHEMA_NAME(SCHEMA_ID())) + '].[' + PARSENAME(base_object_name,1) + '];'
FROM sys.synonyms
我使用參數使它更通用一些。我在下面添加了它。感謝@artm的建議 – kuklei
基於@artm建議我擴大它只是一點點,包括參數,使之更加通用。這裏是代碼
DECLARE @newDB VARCHAR(MAX) = 'finbaza', --newDB to point the synonym to
@linkedSrv VARCHAR(MAX) = null --if the synonym points to a linked server than specify it here like (including the (dot) in the end [LinkedSrv].
SELECT 'Drop Synonym [' + SCHEMA_NAME(schema_id) + '].[' + PARSENAME(base_object_name, 1) + '];' AS dropSynonym,
' CREATE SYNONYM [' + SCHEMA_NAME(schema_id) + '].[' + UPPER(PARSENAME(base_object_name, 1)) + '] FOR '
+ COALESCE(@linkedSrv, '') + '[' + @newDB + '].[' + COALESCE(PARSENAME(base_object_name, 2),
SCHEMA_NAME(SCHEMA_ID())) + '].['
+ UPPER(PARSENAME(base_object_name, 1)) + '];' AS createSynonym
FROM sys.synonyms`
當它創建臨時表時插入到@table_list中。在我的情況下,它變成空的 – kuklei
看起來像我懶惰的變量...你試着編輯'![服務器!]。[[olddb!]%'來匹配你的環境? – Lukek