DECLARE @synName VARCHAR(100), @synTarget VARCHAR(150), @synSchemaName VARCHAR (110)
DECLARE Syns CURSOR FOR
SELECT
s.name, base_object_name, sc.name AS synSchemaName
FROM
sys.synonyms s
INNER JOIN
sys.schemas sc ON s.schema_id = sc.schema_id
WHERE
s.name in ('test1')
OPEN Syns
FETCH NEXT FROM Syns INTO @synName, @synTarget, @synSchemaName
WHILE @@FETCH_STATUS <> -1
BEGIN
PRINT 'DROP SYNONYM guest.' + @synName
EXEC ('DROP SYNONYM guest.' + @synName)
SET @synTarget = CASE
WHEN @synTarget LIKE '%test2%' THEN REPLACE(@synTarget,'[test2]','[test3]')
WHEN @synTarget LIKE '%test3%' THEN REPLACE(@synTarget,'[test3]','[test4]')
WHEN @synTarget LIKE '%test4%' THEN REPLACE(@synTarget,'[test4]','[test2]')
END
PRINT 'CREATE SYNONYM guest.' + @synName + ' FOR ' +@synTarget
EXEC ('CREATE SYNONYM guest.' + @synName + ' FOR ' +@synTarget)
PRINT 'TRUNCATE TABLE'+@syntarget
--EXEC ('TRUNCATE TABLE'+@syntarget)
FETCH NEXT FROM Syns INTO @synName, @synTarget, @synSchemaName
END
CLOSE Syns
DEALLOCATE Syns
我正在使用另一篇文章中的上述代码。运行查询后我遇到了一个新问题。而不是只执行一次。
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
它会这样做
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test2]
TRUNCATE TABLE[master].[dbo].[test2]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test3]
TRUNCATE TABLE[master].[dbo].[test3]
DROP SYNONYM guest.test1
CREATE SYNONYM guest.test1 FOR [master].[dbo].[test4]
TRUNCATE TABLE[master].[dbo].[test4]
..... and so on ......
当我从 drop 中取出两个 EXEC
命令并创建它时,它只显示一次。但实际上什么也没做。当我仅使用 EXEC
进行 DROP 并注释掉其他内容时,它会删除同义词并显示一次。但是,一旦我包含用于创建的 EXEC,它就会开始疯狂地重复并清除所有表。
我已经删除了 test2 周围的大括号和所有内容,看看是否有效,但仍然遇到同样的问题。
我不知道为什么会这样做以及如何修复它,因此它只经历一次然后停止。
最佳答案
您在循环中所做的更改会影响光标正在读取的系统 View 。您的光标也会“看到”并反射(reflect)它们。这是默认行为,可以通过 STATIC 选项更改:
DECLARE Syns CURSOR <b>STATIC</b> FOR
SELECT
...
游标声明中的STATIC
选项使游标创建并使用从基础表/ View 获取的数据的临时副本。这样,对这些数据集的任何更改都不会反射(reflect)在光标中。
有关此光标选项和其他光标选项的更多信息可以在手册页中找到:
关于sql - 为什么删除和创建同义词不断重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24829875/