sql - 为什么删除和创建同义词不断重复

标签 sql sql-server t-sql

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/

相关文章:

mysql - 使用公共(public)字段将记录从一个表追加到另一个表

sql - 在 Oracle SQL 中全选...

sql-server-2008 - 如何在 SQL 中选择行作为 View 的列?

sql - 对带有 Case 语句的Where进行矛盾条件检查

php - 用于从单个数据库中的多个表中进行选择的 SQL 查询

sql - Oracle Pro*C -- 段错误(核心已转储)

sql - SQL查询将列数据拆分为行

sql-server - T-SQL:AS 关键字在这种情况下意味着什么?

sql - 如何使 SQL Server 查询足够高效而不会超时?

SQL检查插入的数据周期