2016-03-23 7 views
4

あなたはSQL Serverの中で次のように実行した場合... スキーマのルックアップ(バグ?)

CREATE SCHEMA [cp] 
GO 

CREATE TABLE [cp].[TestIt](
    [ID] [int] NULL 
) ON [PRIMARY] 
GO 

CREATE PROCEDURE cp.ProcSub 
AS 
BEGIN 
    Print 'Proc Sub' 
END 
GO 

CREATE PROCEDURE cp.ProcMain 
AS 
BEGIN 
    Print 'Proc Main' 
    EXEC ProcSub 
END 
GO 

CREATE PROCEDURE cp.ProcMain2 
AS 
BEGIN 
    Print 'Proc Main2' 
    SELECT * FROM TestIt 
END 
GO 

exec cp.ProcMain2 
GO 

exec cp.ProcMain 
GO 

は、あなたがエラーを取得する

ストアドプロシージャ「ProcSubが見つかりませんでした'

実行コールにスキーマをハードコードしないで、プロシージャをスキーマにコンパイルすることは不可能です。これは、設計上またはバグで、プロシージャー・スキーマ内の表を最初に選択することです。

私はそれを聞いてみたいと思っていますが、開発者にお互いを呼び出す2つのストアドプロシージャを与えることができます。同じデータベース内の別のスキーマのオブジェクトを参照するユーティリティであるために実行できます。

シノニムでラウンドさせることができるかどうかを確認しましたが、同じ問題が発生しているようです。

+1

スキーマを作成した後、CPにユーザーのデフォルトのスキーマを変更しましたか?実行中、コンテキストはユーザのデフォルトスキーマから取得されます。この場合、あなたはまだdboとして設定されています。つまり、このエラーをgettignする理由です。ですから、 "exec cp.prodsub"を使用するか、またはユーザーを更新してください。 –

+0

それは要点ですが、私はユーザーのデフォルトのスキーマを変更したくありません。これらは、異なるスキーマ内の異なるセットのオブジェクトである必要があります。異なるスキーマ内のテーブルと同じように動作する必要があります。 – Hoots

+0

あなたがユーザーを持っている場合、「cp」スキーマにアクセスできるJayeshと言えば、宣言の直後にEXECUTE AS Jayeshを試してこの問題を解決することができます。しかし、もちろん、なりすましを許可する必要があります。それについての詳細とDBAがそれを使用する前に配置した特定の制限事項については、DBAに相談してください。参照 - https://msdn.microsoft.com/en-us/library/ms181362.aspx –

答えて

2

これは、プロシージャを呼び出すユーザーにデフォルトのスキーマが設定されていないためです。

クエリでスキーマが指定されていない場合、SQL Serverはデフォルトのスキーマを最初に試行し、次にdbo(異なる場合)スキーマを試行します。したがって、完全修飾名を使用してデフォルトスキーマを設定するか、プロシージャを作成する必要があります。

チェックアウト:

をSQL Server 2005に始まり、各ユーザーは、既定のスキーマを持っています。 デフォルトスキーマは、CREATE USERまたはALTER USERのDEFAULT_SCHEMA オプションを使用して設定および変更できます。 DEFAULT_SCHEMAを のままにすると、データベースユーザーはdboをデフォルトスキーマとして使用します。

https://technet.microsoft.com/en-us/library/ms190387%28v=sql.105%29.aspx

+0

異なる構造および/またはデータ(dboおよびcpスキーマ内の1つ)で 'TestIt'という2つの同等のテーブルを作成すると、 Exec ProcSubを*からTestItを選択するように変更すると、最初にcpスキーマのスキーマが選択されます。もし存在しなければ、dbo.TestItバージョンがデフォルトになりますので、ユーザーはデフォルトのスキーマを持っています。意図的に。 – Hoots

+0

あなたが指摘している記事では、オブジェクトのセット全体を別のスキーマに区画化し、各オブジェクトに異なる権限を設定できるようにする必要があります。既定のスキーマを持つだけでは、これらのオブジェクトを強制的に使用するのではなく、使用しているスキーマを明示的に示す必要があるということではなく、使用するオブジェクトの既定のセットであると、現在のコンテキストを確実に確認する必要があります。 – Hoots

+0

さて、2007年からは "修正されません"との接続があります。したがって、プロシージャとテーブルのデフォルトのスキーマ検索の間の不一致は知られていますが、これまで変更されていません。 https://connect.microsoft.com/SQLServer/feedback/details/272964/using-default-schema-in-stored-procedures実際に矛盾がある場所では、ストアドプロシージャのデフォルトスキーマがどのように動作するかの方法論が文書化されています最初にユーザーのデフォルトスキーマをとり、dboを使用します。 –