web-dev-qa-db-ja.com

デフォルトスキーマでは、スキーマプレフィックスを使用せずにdboテーブルを選択できます

サーバーにログインとデータベースユーザーを次のように作成しました。

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スキーマはこのルールの例外ですか?

3
SEarle1986

SQL Serverは最初にデフォルトスキーマのスキーマ接頭辞のないオブジェクトをチェックするため、一部のオブジェクトがデフォルトスキーマにある場合、接頭辞は必要ありません。次に、dboスキーマをチェックするので、この怠惰を実際に回避するには2つの方法があります。

ドキュメント から:

データベースオブジェクトが1部構成の名前を使用して参照されると、SQL Serverは最初にユーザーの既定のスキーマを調べます。オブジェクトがそこに見つからない場合、SQL Serverは次にdboスキーマを探します。オブジェクトがdboスキーマにない場合、エラーが返されます。

「1部構成の名前」と言いますが、次のようなパターンでオブジェクトを参照する場合も同様です。

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

または

[database]..[name]

これは、常にスキーマ名を指定する必要があることの確認にすぎません常に。

6
Aaron Bertrand