サーバーにログインとデータベースユーザーを次のように作成しました。
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としてログインすると、4つの部分の名前を使用せずに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
スキーマをチェックするので、この怠惰を実際に回避するには2つの方法があります。
ドキュメント から:
データベースオブジェクトが1部構成の名前を使用して参照されると、SQL Serverは最初にユーザーの既定のスキーマを調べます。オブジェクトがそこに見つからない場合、SQL Serverは次に
dbo
スキーマを探します。オブジェクトがdbo
スキーマにない場合、エラーが返されます。
「1部構成の名前」と言いますが、次のようなパターンでオブジェクトを参照する場合も同様です。
[server].[database]..[name]
または
[database]..[name]
これは、常にスキーマ名を指定する必要があることの確認にすぎません。 常に。