次のようなストアドプロシージャがあります。
私(DB所有者)がこのプロシージャを実行すると、すべてが意図したとおりに機能します。 Active Directoryのロールを介してこのデータベースに対するDROP/CREATE権限を持つ同僚がそうする場合、いくつかの問題が発生します。私の心を揺さぶるのはこれです:
テーブルの作成では、名前の前に明示的に指定されたdbo
スキーマがありませんでした。その結果、domain\cowork_id.table_name_here
というテーブルが作成されました。彼の個人的なスキーマで作成されているそのテーブルに加えて、彼はデータベースにそのスキーマも持っています(プロシージャを実行する前は存在していませんでした)。
どうした?指定されていないのに、SQL Serverがdbo
ではなくユーザーのスキーマのテーブルを作成するのはなぜですか?
原則として、このスキーマにオブジェクトを作成する場合は、explicitelydbo
スキーマを指定する必要があります。
あなたはdb_owner
なので、デフォルトのスキーマはdbo
なので、オブジェクトの作成中にdboスキーマを指定しなくても問題はありません。しかし、他の(Windows)ユーザーにとっては同じではありません。
ユーザーは、デフォルトスキーマのないWindows group
のメンバーです。この場合、対応するユーザーとスキーマは、ユーザーがオブジェクトを作成するときに作成されます。これは、ここに記載されています。 CREATE SCHEMA(Transact-SQL)
暗黙的なスキーマとユーザーの作成
場合によっては、ユーザーはデータベースユーザーアカウント(データベース内のデータベースプリンシパル)がなくてもデータベースを使用できます。これは、次の状況で発生する可能性があります。
ログインにはCONTROL SERVER特権があります。
Windowsユーザーには個別のデータベースユーザーアカウント(データベース内のデータベースプリンシパル)はありませんが、データベースユーザーアカウント(データベースプリンシパル)を持つWindowsグループのメンバーとしてデータベースにアクセスしますWindowsグループの場合)
データベースユーザーアカウントのないユーザーが既存のスキーマを指定せずにオブジェクトを作成すると、そのユーザーのデータベースにデータベースプリンシパルと既定のスキーマが自動的に作成されます。作成されたデータベースプリンシパルとスキーマは、SQL Serverへの接続時にユーザーが使用した名前と同じ名前になります(SQL Server認証ログイン名またはWindowsユーザー名)。
この動作は、Windowsグループに基づくユーザーがオブジェクトを作成および所有できるようにするために必要です。ただし、スキーマとユーザーが意図せずに作成される可能性があります。暗黙的にユーザーとスキーマを作成しないようにするには、可能な限り、データベースプリンシパルを明示的に作成し、デフォルトのスキーマを割り当てます。または、2つまたは3つの部分からなるオブジェクト名を使用して、データベースにオブジェクトを作成するときに既存のスキーマを明示的に指定します。
この問題を解決するには、dbo
スキーマをdefault schema
としてすべてのユーザーまたはWindowsグループに割り当てるか、オブジェクトの作成時にスキーマを明示的に記述します。常に。