為什麼 DATABASEPROPERTYEX 的結果與 AdventureWorks 不一致?
我正在使用函式DATABASEPROPERTYEX來檢查數據庫的恢復屬性,但是數據庫的結果是錯誤的
AdventureWorks
(後來我注意到ReportServer
和ReportServerTempDB
數據庫的同樣奇怪的行為)。這是我嘗試過的簡化版本:
USE master; GO CREATE PROCEDURE [dbo].[sp_isSimpleRecovery] AS BEGIN PRINT DB_NAME() + CHAR(13); IF DATABASEPROPERTYEX(DB_NAME(), 'Recovery') = 'SIMPLE' PRINT '--Database in SIMPLE recovery model' + CHAR(13); ELSE PRINT '--Database in ANOTHER recovery model' + CHAR(13); END
我創建了
master
使用前綴 sp_的過程,以便可以從任何數據庫執行它。但是當我從AdventureWorks
結果中執行它時,與沒有該過程執行的相同程式碼不同:USE AdventureWorks2016; GO EXEC sp_isSimpleRecovery; PRINT DB_NAME() + CHAR(13); IF DATABASEPROPERTYEX(DB_NAME(), 'Recovery') = 'SIMPLE' PRINT '--Database in SIMPLE recovery model' + CHAR(13); ELSE PRINT '--Database in ANOTHER recovery model' + CHAR(13);
它適用於許多其他數據庫,但對於 AdventureWorks,輸出為:
AdventureWorks2016
–另一種恢復模式中的數據庫
AdventureWorks2016
–簡單恢復模型中的數據庫
是什麼導致了這種行為?
- AdventureWorks2014.bak
- AdventureWorks2016.bak
SQL Server 版本:
- Microsoft SQL Server 2016 (SP2-GDR) (KB4532097) - 13.0.5102.14 (X64) 2019 年 12 月 31 日
- Microsoft SQL Server 2014 (SP3-CU4-GDR) (KB4583462) - 12.0.6433.1 (X64) 2020 年 10 月 31 日
我將您的過程重新寫到下面:
CREATE OR ALTER PROCEDURE [dbo].[sp_isSimpleRecovery] AS BEGIN PRINT DB_NAME() + CHAR(13); PRINT CAST(DATABASEPROPERTYEX(DB_NAME(), 'Recovery') AS varchar(20)) IF CAST(DATABASEPROPERTYEX(DB_NAME(), 'Recovery') AS varchar(20)) = 'SIMPLE' PRINT '--Database in SIMPLE recovery model' + CHAR(13); IF CAST(DATABASEPROPERTYEX(DB_NAME(), 'Recovery') AS varchar(20)) = 'FULL' PRINT '--Database in FULL recovery model' + CHAR(13); END GO
請注意,我忽略了大容量日誌恢復模型。此過程在 SQL Server 2019 上對我有用。即,如果我在一個處於簡單模式的數據庫中,它會返回 SIMPLE,如果我在一個處於完整模式的數據庫中,它會返回 FULL。
如果上述方法在 2016 年對您不起作用,那麼可能在 2016 年和 2019 年之間發生了行為變化。
在某些情況下,僅將過程命名為 sp_ 並將其放在主數據庫中是不夠的。您還必須使用未記錄的 sp_MS_marksystemobject 將其標記為系統過程。請注意,這是未記錄的,因此使用風險自負!
兩者之間的區別在於,如果沒有 sp_MS_marksystemobject, 如果您在 Adventureworks 中,*則會找到該過程,但在主數據庫上下文中執行。*例如,如果您從 sys.tables 中選擇,您將看到主數據庫中的表。
使用 sp_MS_marksystemobject,您可以告訴 SQL Server 在執行過程中的程式碼時處於目前數據庫的上下文中。即,系統表、系統函式等現在將被解析為使用使用者數據庫而不是主數據庫。
那麼為什麼會在 2016 年和 2019 年之間發生行為變化呢?我們不能說,因為我們在無證地區。
一個簡單的事實是,沒有支持的方法來創建解析為您所在數據庫的“全域”系統儲存過程。