Sql-Server
獲取包含 INSERT 的儲存過程的“列表”而不命名所涉及的列
作為某些增強功能的一部分,已在 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%'
但它仍然錯過了很多。
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);
現在有兩個儲存過程,一個顯式引用列,另一個沒有。
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
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');
哪個返回這個
name is_insert_all ------------- ------------- p_named 0 p_named 0 p_not_named 1