use*_*979 1 sql-server stored-procedures t-sql sql-server-2016
作为某些增强功能的一部分,750 多个表中添加了一个新列。现在我的问题是在将近 3000 多个存储过程中,一些旧的 INSERT 没有命名列。
有什么办法可以得到所有没有列名插入的存储过程的“列表”?
我试过了:
SELECT OBJECT_NAME(object_id)
FROM sys.sql_modules
WHERE definition LIKE '%insert into%'
AND definition NOT LIKE '%) value%'
AND definition NOT LIKE '%)%' + CHAR(10) + '%value%'
AND definition NOT LIKE '%)%' + CHAR(13) + '%value%'
AND definition LIKE '%value%'
Run Code Online (Sandbox Code Playgroud)
但它仍然错过了很多。
PS - 上面的查询也返回 Insert Into (ColumnNames) SELECT 场景,这是我不想要的。
有一个名为sys.dm_sql_referenced_entities的 DMV 。它返回is_insert_all
这样记录的列
1 = 对象在没有列列表的 INSERT 语句中使用(仅限对象级别)。
这似乎就是你要找的。
下面是它在实践中的一个例子。首先我们将创建一个简单的单列表
drop table if exists dbo.T1;
go
create table dbo.T1(c int);
Run Code Online (Sandbox Code Playgroud)
现在有两个存储过程,一个显式引用列,另一个没有。
create or alter procedure dbo.p_named
as
begin
insert dbo.T1(c) -- columns are listed
select 1;
end
go
create or alter procedure dbo.p_not_named
as
begin
insert dbo.T1 -- no column list
select 2;
end
go
Run Code Online (Sandbox Code Playgroud)
DMV 是一个表值函数。因此,可以使用CROSS APPLY语法调用它。传递给该函数的过程名称可以从目录视图sys.procedures 中获得。此 DMV 的文档说明
当引用类为 OBJECT 时,需要 schema_name。
我们可以使用名为SCHEMA_NAME()的内置元数据函数轻松获取模式名称。把它们放在一起,我们得到
select
p.name, is_insert_all -- other columns exist
from sys.procedures as p
cross apply sys.dm_sql_referenced_entities(CONCAT(SCHEMA_NAME(p.schema_id), '.', p.name), 'OBJECT');
Run Code Online (Sandbox Code Playgroud)
哪个返回这个
name is_insert_all
------------- -------------
p_named 0
p_named 0
p_not_named 1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
245 次 |
最近记录: |