2

共通テーブルからデータを返し、そのテーブルを特定のテーブルと結合してインベントリを取得する 15 のストアド プロシージャがあります。

例:

Common: tblCommon
Specific: tblSpecific

次のように、「tblSpecific」という名前を単一のストアド プロシージャに変数として渡す方法はありますか?

SELECT ....
FROM tblCommon c
INNER JOIN @TABLE s on c.primaryKey = s.foreignKey
4

6 に答える 6

11

これを行う方法は、sp_executesql()ストアドプロシージャを介して実行される動的に生成されたSQLを使用することです。

通常、必要なテーブル名をマスタープロシージャに渡し、実行するSQLのncharvar文字列を作成して、それをsp_executesqlに渡します。

動的SQLの呪いと祝福は、すべてのインとアウトを説明するために私が見た中で最高のページです。

最大の落とし穴の1つは、動的SQLを使用する場合、ストアドプロシージャを呼び出すユーザーは、そのプロシージャに対する実行権限を持っているだけでなく、基になるテーブルにアクセスするための権限も持っている必要があることです。私が提供したリンクには、その問題を回避する方法も記載されています。

于 2008-11-04T23:10:05.173 に答える
3

はい、SQLステートメントを動的に生成して実行できます。

例えば、

DECLARE @specificTableName nvarchar(50)
DECLARE @specificColumnName nvarchar(50)

SET @specificTableName = 'tblSpecific'
SET @specificColumnName = 'colSpecific'

DECLARE @sql nvarchar(4000)

set @sql = 'SELECT ... FROM tblCommon c INNER JOIN ' +
@specificTableName + ' s ON c.PrimaryKey = s.' + @specificColumnName


exec (@sql)
于 2008-11-04T23:08:58.220 に答える
1

動的 SQL は危険です。渡された値を SQL 文字列に直接代入したくありません。幸いなことに、あなたはすでにそれを知っているようです。

残念ながら、この場合、テーブル名に SQL パラメーターを使用できないという問題を発見しました。じゃあ何をすればいいの?動的に生成された SQL で渡された値を使用したくないが、通常の安全な方法でクエリに入れることはできません。

答えはルックアップ テーブルです。特定の各テーブルの名前を保持する「テーブル」テーブルを作成します。次のようになります。

CREATE TABLE [tables] (table_name sysname)

次に、次のようなクエリを作成できます。

SELECT @tblSpecific = table_name FROM [tables] WHERE table_name = @tblSpecific

かどうかを確認する必要@tblSpecificがありNULLます。そうでない場合は、動的 SQL ステートメントで安全に使用できます (動的 SQL は最終的にここでの唯一のオプションです。ユーザー定義関数でさえ、あるレベルでそれを行う必要があります)。

ああ、もう 1 つ、ルックアップ テーブルの名前と型を選んだのは偶然ではありません。SQL 標準には、このようなテーブルが既にあります (とにかくビューです)。を使用するだけINFORMATION_SCHEMA.Tablesです。

于 2008-11-05T03:20:24.997 に答える
0

別の方法として、データ量がそれほど多くない場合は、結合に使用できるテーブル変数を返すことができるユーザー定義関数を検討することをお勧めします。

SELECT ....
FROM tblCommon c
INNER JOIN dbo.SomeFuntionThatReturnsData(@someparam) s on c.primaryKey = s.foreignKey
于 2008-11-04T23:11:55.920 に答える
0

それぞれを個別のストアド プロシージャとして保存します。

可能な限り、ストアド プロシージャをそのままにしてシンプルに保ちたいと思っています。一見しただけで理解するのは難しいです。なぜなら、とにかく式が非常に長く伸びており、宣言型コードの断片と混ざり合った一連の手続き型コードを追加すると、さらに難しくなるからです。

パラメータを持つより複雑なストアド プロシージャの 15 回の呼び出しのリストで終わるか、より単純なストアド プロシージャの同等のリストで終わるかのいずれかになります。また、パラメーターがテーブル名である場合、効率的に実行される種類のパラメーター化された sp にはなりません。テーブル駆動型のアプローチに関しては、依然として効率が低く、より危険な動的ストアド プロシージャです。テーブル エントリは、テーブルを除いて入力ミスの可能性が高く、テーブル名のエラーはさらに目立たなくなります。そして、カップリングが上がり、粘着性が下がりました (両方とも間違った方向に向かっています)。

于 2008-11-05T05:23:16.840 に答える