1

我有数百个程序安装到数据库中,带引号的标识符设置为关闭,我需要将它们设置为打开。我可以使用以下命令查看这些程序的列表

SELECT name = OBJECT_NAME([object_id]), uses_quoted_identifier
FROM sys.sql_modules
WHERE uses_quoted_identifier <> 1 AND OBJECT_NAME([object_id]) LIKE '%%'
ORDER BY OBJECT_NAME([object_id])

现在我知道我不能直接对 sys.sql_modules 进行更新来设置 uses_quoted_identifier。我可以手动打开所有脚本并重新安装,但这很耗时。我也可以制作一个批处理文件来运行相同的过程,但这仍然很耗时,尽管稍微少了一点。

有没有更简单的方法可以更新这些?

更新 在做更多研究时,我发现这篇文章让我意识到,引用标识符的东西都是我自己做的,因为我已经有一个批处理命令正在从特定目录安装程序:插入时 SET QUOTED IDENTIFIER 应该是 ON记录

我意识到使用这篇文章我可以将 -I 添加到我的 sqlcmd 以启用引用标识符:https ://sqlsailor.com/2014/11/14/sqlcmdoptions/

我将暂时保留这个问题,以防任何人有技巧以编程方式更新过程中的引用标识符,但这应该暂时解决我的问题。

4

1 回答 1

1

不久前我遇到了一个类似的问题,我不得不quoted identifier在几个数据库中的数百个程序中找到并修复不正确的设置以及许多其他问题。任务的一部分是查找并删除任何显式设置选项,例如quoted_identifer,以及许多其他常见问题,包括在许多使用动态 sql 并设置为 off的遗留过程中ansi_nulls transaction isolation level删除引号的使用。"quoted_identifer

这是我的解决方案的核心,您可能希望根据自己的要求进行修改。

我将所有相关对象的 sql 文本 - 过程、函数等放入临时表中,然后进行各种字符串替换以解决特定问题。然后我遍历并使用动态 sql 来重新创建对象,这自然会得到正确的 default set options。任何失败的都在表中列出,然后我手动处理。

select m.definition, Cast(o.name as varchar(1000)) [name], m.object_id, 0 Done, 0 Success , o.type
--into #working
from sys.sql_modules m join sys.objects o on o.object_id=m.object_id and o.type in ('FN', 'P', 'V', 'TR')
where m.uses_quoted_identifier=0

update #working set definition=Replace(definition, 'create function', 'create or alter function')
update #working set definition=Replace(definition, 'create view', 'create or alter view')
update #working set definition=Replace(definition, 'create trigger', 'create or alter trigger')
update #working set definition=Replace(definition, 'create proc', 'create or alter proc')
update #working set definition=Replace(definition, 'create  proc', 'create or alter proc')
update #working set definition=Replace(definition, 'create proc', 'create or alter proc')
/*
update #working set definition=Replace(definition, 'set ansi_nulls off', '')
update #working set definition=Replace(definition, 'set ansi_warnings off', '')
update #working set definition=Replace(definition, 'set quoted_identifier off', '')
update #working set definition=Replace(definition, '(nolock)', '')
update #working set definition=Replace(definition, 'set transaction isolation level read uncommitted', '')
*/

select * from #working 


declare @Sql nvarchar(max), @Id int

while exists (select * from #working where Done=0)
begin
    select top (1) @Sql=definition, @Id=object_id from #working where Done=0

    update #working set Done=1, Success=1 where object_id=@Id
    begin try
        exec (@Sql)
    end try
    begin catch
        update #working set Success=Error_Number(), name=Error_Message() where object_id=@Id
    end catch
end
于 2021-04-24T08:34:49.123 回答