Sql-Server

預設模式允許選擇 dbo 表而不使用模式前綴

  • March 15, 2018

我在我的伺服器上創建了一個登錄名和一個數據庫使用者,如下所示:

USE master
GO
CREATE LOGIN MyLogin WITH PASSWORD=N'Password123!'
GO
USE AdventureWorks2014
GO
CREATE USER MyLogin FOR LOGIN MyLogin
GO
ALTER USER MyLogin WITH DEFAULT_SCHEMA=HumanResources
GO
GRANT SELECT ON SCHEMA :: Production TO MyLogin
GO
GRANT SELECT ON SCHEMA :: HumanResources TO MyLogin
GO
GRANT SELECT ON SCHEMA :: dbo TO MyLogin

當我以 MyLogin 身份登錄時,我現在可以在 HumanResources 架構中選擇對象,而無需使用四部分名稱(因為 HumanResources 是該使用者的預設架構)

SELECT * FROM HumanResources.Department

現在可以在沒有架構名稱的情況下執行:

SELECT * FROM Department

這可以。如果我然後嘗試從生產模式中的表中選擇而不使用模式前綴:

SELECT * FROM ProductDescription

我收到了預期的錯誤。這可以通過使用來解決:

SELECT * FROM Production.ProductDescription

因此,基於此,我需要在從預設架構之外的任何表中進行選擇時指定架構名稱。

那麼為什麼當我從 dbo 模式中的表中選擇時,我仍然不需要使用模式前綴?

SELECT * FROM DatabaseLog

返回結果

我很困惑。我認為如果模式名稱沒有在 SELECT 語句中為表添加前綴,則使用預設模式,並且從任何其他模式中的表中選擇將需要模式前綴。

dbo 模式是此規則的例外嗎?

當某些對象位於預設架構中時,您不需要前綴,因為 SQL Server 首先會檢查預設架構中的非架構前綴對象。然後它將檢查dbo架構,因此您實際上可以通過兩種不同的方式擺脫這種懶惰。

文件中

當使用單部分名稱引用數據庫對象時,SQL Server 首先查找使用者的預設架構。如果在此處找不到對象,SQL Server 將在dbo架構中查找下一個。如果對像不在dbo模式中,則返回錯誤。

他們說“單部分名稱”,但這也適用於您引用具有以下模式的對象時:

[server].[database]..[name]

或者

[database]..[name]

這只是確認您應該始終指定模式名稱總是。

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