为什么drop和create synonym不断重复

时间:2014-07-18 16:32:51

标签: sql sql-server tsql

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周围的大括号以及所有内容,看看它是否有效并且仍然存在同样的问题。

我迷失了它为什么会这样做以及如何修复它所以它只经过一次然后停止。

1 个答案:

答案 0 :(得分:3)

您在循环中所做的更改会影响光标正在读取的系统视图。你的光标也会看到&#34;并反映出来。这是默认行为,可以通过STATIC选项更改:

DECLARE Syns CURSOR STATIC FOR
   SELECT
   ...

游标声明中的STATIC选项使游标创建并使用从基础表/视图获取的数据的临时副本。这样,对这些数据集的任何更改都不会反映在游标中。

有关此选项和其他光标选项的更多信息,请参见手册页: