SQL Server 什麼是 dbo (What is dbo)

2021-03-08

筆記 SQL Server 常見到的關鍵字 dbo 到底是什麼?

SQL Server Logo

說明

如果曾經使用過 SQL Server 你一定對它不陌生,就是 「dbo」,但到底什麼是 dbo ?

dbo 是使用者 (dbo is user)

正確的說法是 dbo 是 SQL Server 所有的資料庫一定都具備的「使用者(user)」,同時這個使用者為資料庫的 db_owner 角色,並且不得調整該使用者所屬於的角色,想要多賦予 dbo datareader 或者 denydatareader 都不行,所以 dbo 的權限範圍是不可撼動的。

特別的一點是具有伺服器角色 sysadmin 的登入,在存取任何資料庫的時候都是使用 dbo 使用者。

這一點可以在 Query 中使用下列指令來確認:

SELECT USER

誰是資料庫的 dbo 使用者

SQL Server 資料庫中的使用者會對應到一個資料庫伺服器上的登入(Login),否則就會稱此使用者為孤立使用者(Orphand)

而要檢視資料庫 dbo 使用者的方法,可以從資料庫 → 安全性 → 使用者,選擇 dbo 來確認。

截圖中的資料庫因為是從其他位置還原過來,所以沒有對應到登入,這也表示 dbo 是可以沒有對照到登入、資料庫是可以沒有擁有者的。

如何調整 dbo 對應的 login

從下列步驟進行調找,資料庫 → 資料庫名稱點選右鍵 → 屬性 → 檔案

藉由變更擁有者的方式來調整,資料庫的擁有者就會是資料庫 dbo 使用者所對應的登入

也可以使用 T-SQL 來作業

USE [DatabaseName]
GO
ALTER AUTHORIZATION ON DATABASE::[DatabaseName] TO [loginName]

如何檢視所有資料庫的 dbo 對應 login

USE [master]

-- Create a temporary table to store the results
CREATE TABLE #DBO_Mapping (DatabaseName NVARCHAR(100), DboLogin NVARCHAR(100));

-- Declare variables for cursor
DECLARE @DatabaseName NVARCHAR(100);

-- Create a cursor to iterate through databases
DECLARE db_cursor CURSOR FOR
SELECT name
FROM sys.databases
WHERE state_desc = 'ONLINE';

-- Initialize the cursor
OPEN db_cursor;

-- Loop through each database
FETCH NEXT FROM db_cursor INTO @DatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
    -- Dynamic SQL to get dbo mapping for each database
    DECLARE @sql NVARCHAR(MAX);
    SET @sql = N'USE [' + @DatabaseName + '];
                 INSERT INTO #DBO_Mapping (DatabaseName, DboLogin)
                 SELECT ''' + @DatabaseName + ''', sp.name AS DboLogin
                 FROM sys.database_principals dp
                 INNER JOIN sys.server_principals sp ON dp.sid = sp.sid
                 WHERE dp.name = ''dbo'';';
    
    -- Execute the dynamic SQL
    EXEC sp_executesql @sql;
    
    -- Fetch the next database
    FETCH NEXT FROM db_cursor INTO @DatabaseName;
END;

-- Close and deallocate the cursor
CLOSE db_cursor;
DEALLOCATE db_cursor;

-- Select the results from the temporary table
SELECT * FROM #DBO_Mapping;

-- Drop the temporary table
DROP TABLE #DBO_Mapping;

dbo 是結構描述 (dbo is schema)

此外常常也會看見 dbo.各種物件,例如 dbo.table、dbo.view、dbo.function 等等,這是因為資料庫中的預設描述結構(schema)就是 dbo,而資料庫新建立的使用者都會具有 dbo 作為預設的描述結構。

dbo schema (描述結構) 與 dbo user (使用者) 是不同的概念。

結構描述的擁有者

結構描述有其擁有者,可以從 資料庫 → 安全性 → 描述結構 選擇描述結構來確認。

而結構描述僅能擁有單一擁有者,可能是使用者, 資料庫角色或應用程式角色的其中之一類,同時也僅能是該類中的唯一成員所擁有。

要注意的是使用者不會因為擁有 dbo 描述結構,就具備 dbo 使用者的 db_owner 權限擁有結構描述僅會擁有該結構描述下的資料庫物件。

如何調整結構描述的擁有者

可以從 資料庫 → 安全性 → 描述結構 選擇描述結構來進行調整

參考資料

SQL Server 中的擁有權和使用者結構描述分離

資料庫層級角色

相關連結

SQL Server 閃電般快速查詢指南⚡

SQL Server 周邊工具彙整筆記

SQL Server 學習資源筆記