【发布时间】:2022-01-17 17:52:27
【问题描述】:
更新: 谢谢大家的回答。我很感激。 补充几点:
- 我将实际的包名替换为“%%”,因为我不想在 NDA 相关的东西上遇到麻烦,所以我选择格外小心。
- 我确实使用 select @sql 查看执行的查询,但感谢您注意到 :)
- 再次感谢大家的回答。
这是我的第一篇文章,所以可能有点令人印象深刻:D
我编写了这个脚本来帮助我一次删除所有依赖项的数据,但是我有两个问题:
declare @PackageId uniqueidentifier ;
set @PackageId = (select Id from SysPackage where name like '%%');
declare @tableName varchar(max);
declare @Columnname varchar(max);
declare @sql varchar(max);
declare dependent_tables Cursor
FOR SELECT
tab1.name,
col1.name
FROM sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
INNER JOIN sys.foreign_keys fk
ON fk.name = obj.name
where tab2.name ='SysPackage'
Open dependent_tables
Fetch NEXT from dependent_tables INTO
@tableName,
@columnName;
WHILE @@Fetch_Status = 0
Begin
if @tableName is null Break;
if @Columnname is null Break;
set @sql=CONCAT('delete from ',@tableName,' WHERE ',@columnName,' = ',@PackageId);
exec (@sql);
END;
Deallocate dependent_tables;
所以我基本上有两个问题。
-
循环是无限的,因为光标实际上并不循环遍历记录,而是始终停留在相同的@tableName 和@columName 上
-
@packageId 也有一个问题,它被插入到没有引号的查询中,所以查询看起来像这样:
从 Table1 中删除,其中 column1 = A5664658-26D5-4600-862A-86467FD59244
我想为联系人创建一个额外的参数,有点像这样:
set @sql=CONCAT('delete from ',@tableName,' WHERE ',@columnName,' = ', ''',@PackageId, ''');
但它不会让我逃脱 '. 任何想法如何找出解决它的方法将不胜感激。
谢谢。
【问题讨论】:
-
你没有获取下一个光标
-
正如@Nathan_Sav 所指出的,您需要在while 循环结束时,在
END关键字之前“从dependent_tables 中获取NEXT ......”。对于第二点,您需要将其输入为' = ','''' + @PackageId + '''');。最后评论:在开发动态 SQL 查询时,PRINT语句(例如PRINT @sql)是你最好的朋友。没有它,你就是聋子、哑巴和瞎子。始终“打印”生成的查询并尝试直接在 SSMS 中运行它以捕获琐碎的错误。 -
同时关闭光标。
标签: sql sql-server database-cursor