SQLSERVER要求在調用函數時,只有返回表值的函數可以不加所有者,否則必須加所有者名稱,具體請參閱CREATE FUNCTION幫助.所以這又是一個我們要遵守的規則.
至於所有者是不是都是dbo,要看創建這個函數的用戶是誰,在這一點上函數與表或存儲過程沒有任何區別,也就是說所有者就是創建她的用戶.
我們常見的dbo是指以sa(SQLSERVER登錄方式)或windows administration(Windows集成驗證登錄方式)登錄的用戶,也就是說數據庫管理員在SQLSERVER中的用戶名就叫dbo,而不叫 sa,這一點看起來有點蹊跷,因為通常用戶名與登錄名相同(不是強制相同,但為了一目了然通常都在創建用戶名時使用與登錄名相同的名字),例如創建了一個 登錄,名稱為me,那麼可以為該登錄名me在指定的數據庫中添加一個同名用戶,使登錄名me能夠訪問該數據庫中的數據.當在數據庫中添加了一個用戶me 後,之後以me登錄名登錄時在該數據庫中創建的一切對象(表,函數,存儲過程等)的所有者都為me,如 db.me.table1,db.me.fn_test(),而不是dbo.
不管怎樣,只要記住了sa這個登錄名對應的用戶名是dbo而不是sa就行了.
另外,不要混淆登錄名與用戶名.登錄名只是具有連接到SQLSERVER的權限,而沒有訪問SQLSERVER上數據庫的權限,所以要為該登錄名在指定的 數據庫中創建用戶名,使其可以訪問那個數據庫中的數據.一個登錄名可以在多個數據庫中創建用戶名,以使這個登錄名能夠訪問多個數據庫(在登錄連接的字符串 中指定默認的數據庫名稱),但是一個登錄名在一個數據庫中只能創建一個對應的用戶名,也就是說me登錄名在pubs數據庫(舉例)只能創建一個用戶名.
比喻一下:SQLSERVER就象一棟大樓,裡面的每個房間都是一個數據庫.登錄名只是進入大樓的鑰匙,而用戶名則是進入房間的鑰匙.一個登錄名可以有多 個房間的鑰匙.SQLSERVER把登錄名與用戶名的關系稱為映射.
至於為什麼要使用所有者進行限定,是因為不同的用戶可能創建同名的對象,例如登錄名me和登錄名you在pubs數據庫中分別創建了用戶名me,和 you,這二個用戶都創建了testtable這個同名表,而這二個表雖然同名但結構或數據可能完全不同,為了避免調用錯誤,必須使用所有者名稱進行限 定.
還有,怎樣來調用別的用戶創建的對象呢?例如me用戶訪問you用戶創建的表或訪問dbo創建的表.此種情況,必須同時滿足二個條件:
1.將me用戶的數據庫角色設置為db_owner,否則無法訪問其他用戶(包括dbo用戶)創建的對象.(企業管理器-> 用戶,右鍵菜單 <屬性> 中設置)
2.使用所有者進行限定.
例如me訪問you創建的testtable:
select * from you.testtable
另外,dbo用戶作為管理員,系統賦予其所有的權限,可以調用任何用戶創建的對象.
如果具有db_owner角色的用戶在訪問對象時省略了所有者,則系統先查找該用戶的對象,若找不到則查找dbo用戶是否有同名對象.例如:
select * from testtable 或
select * from pubs..testtable