Sql-Server

為什麼 OBJECT_ID 在計算列中返回 NULL?

  • January 9, 2018

我正在嘗試為我的數據庫中的一些儲存過程生成使用情況報告。視圖視圖sys.dm_exec_procedure_stats包含我需要的一些內容,所以我決定從這裡開始。

SQL Server 按對象 ID 鍵控過程元數據。我只知道過程名稱,所以首先我必須使用OBJECT_ID函式將名稱映射到 ID 。

有幾個程序要檢查,所以我想在處理它們之前把它們的名字放在一個臨時表中。

我認為從臨時表中的計算列中獲取對象 id 會很可愛,所以我創建了一個這樣的表:

USE msdb;
GO

CREATE TABLE #procs (
 name SYSNAME,
 [object_id] AS OBJECT_ID(name)
);

INSERT INTO #procs (name) VALUES ('dbo.sp_send_dbmail');
INSERT INTO #procs (name) VALUES ('dbo.sp_add_job');
INSERT INTO #procs (name) VALUES ('dbo.sp_start_job');

有了該表,獲取執行計數的明顯方法如下所示:

SELECT #procs.name, execution_count
FROM sys.dm_exec_procedure_stats AS procstats
INNER JOIN #procs ON #procs.[object_id] = procstats.[object_id]
ORDER BY execution_count DESC;

但它返回一個空的結果集!

此查詢顯示結果集為空的原因:

SELECT name, [object_id]
FROM #procs;

object_id 列是 NULL,所以內連接不會產生任何行:

name                 object_id
-------------------- -----------
dbo.sp_send_dbmail   NULL
dbo.sp_add_job       NULL
dbo.sp_start_job     NULL

這並不是臨時表的計算列被破壞。如果我添加一個計算列來反轉名稱,當我從中選擇時它會產生正確的值:

ALTER TABLE #procs ADD reverse_name AS REVERSE(name);

SELECT name, [object_id], reverse_name
FROM #procs;

結果:

name                 object_id   reverse_name
-------------------- ----------- ---------------------
dbo.sp_send_dbmail   NULL        liambd_dnes_ps.obd
dbo.sp_add_job       NULL        boj_dda_ps.obd
dbo.sp_start_job     NULL        boj_trats_ps.obd

為什麼 OBJECT_ID 在這裡返回 NULL?

表中計算列中提到的元數據函式#temp將引用tempdb.sys.objects,而不是yourdatabase.sys.objects,因為表是在tempdb. 嘗試將數據庫前綴添加到插入中,這將使OBJECT_IDgo 在正確的位置找到它:

CREATE TABLE #procs (
 name SYSNAME,
 [object_id] AS OBJECT_ID(name)
);

INSERT INTO #procs (name) VALUES ('dbo.sp_send_dbmail');
INSERT INTO #procs (name) VALUES ('msdb.dbo.sp_send_dbmail');

SELECT name, [object_id] FROM #procs;

結果:

dbo.sp_send_dbmail          NULL
msdb.dbo.sp_send_dbmail     283148054

引用自:https://dba.stackexchange.com/questions/51317