動的テーブルに値を挿入するストアド プロシージャを作成できるかどうか疑問に思っていました。
私は試した
create procedure asd
(@table varchar(10), @id int)
as
begin
insert into @table values (@id)
end
@table
テーブル変数としても定義
ご協力いただきありがとうございます!
動的テーブルに値を挿入するストアド プロシージャを作成できるかどうか疑問に思っていました。
私は試した
create procedure asd
(@table varchar(10), @id int)
as
begin
insert into @table values (@id)
end
@table
テーブル変数としても定義
ご協力いただきありがとうございます!
これはあなたのために働くかもしれません。
CREATE PROCEDURE asd
(@table nvarchar(10), @id int)
AS
BEGIN
DECLARE @sql nvarchar(max)
SET @sql = 'INSERT INTO ' + @table + ' (id) VALUES (' + CAST(@id AS nvarchar(max)) + ')'
EXEC sp_executesql @sql
END
詳細はこちら: http: //msdn.microsoft.com/de-de/library/ms188001.aspx
動的 SQL を使用する必要があります。
動的 SQL を作成するには、クエリを文字列として構築する必要があります。ステートメントやその他のロジックを使用しIF
て変数を追加するなど。
テキスト変数を宣言し、これを使用して目的の SQL を連結します。
EXEC
次に、コマンドを使用してこのコードを実行できます
例:
DECLARE @SQL VARCHAR(100)
DECLARE @TableOne VARCHAR(20) = 'TableOne'
DECLARE @TableTwo VARCHAR(20) = 'TableTwo'
DECLARE @SomeInt INT
SET @SQL = 'INSERT INTO '
IF (@SomeInt = 1)
SET @SQL = @SQL + @TableOne
IF (@SomeInt = 2)
SET @SQL = @SQL + @TableTwo
SET @SQL = @SQL + ' VALUES....etc'
EXEC (@SQL)
ただし、この方法を使用する際に特に注意する必要があるのは、SQL インジェクションと呼ばれるセキュリティ上の問題です。
あなたはそれについてここで読むことができます.
SQL インジェクションを防ぐ 1 つの方法は、変数を SQL-Server に渡す前に、コード内でそれに対して検証することです。
別の方法 (またはおそらく推測で最もよく使用される) は、EXEC
コマンドを使用する代わりに、組み込みのストアド プロシージャを使用することsp_executesql
です。
SQL を少し異なる方法で作成し、パラメータを引数としてストアド プロシージャに渡すだけでなく、@SQL も渡す必要があります。
はい、これを直接実装するには、他の人が示唆しているように、動的 SQL が必要です。ただし、この種の普遍性を試みると、コードの安全性や効率が低下する可能性があるという@Tomalakのコメントにも同意します。
このレベルの動的性が必要だと思われる場合は、次のアプローチを試すことができます。これは、単純な動的 SQL よりも多くの労力が必要ですが、後者とほぼ同じですが、前述の欠点はありません。
アイデアは、最初に必要なすべての挿入手順を作成することです。この種類の多くの値を挿入するテーブルごとに 1 つです (つまり、例のように、int
値は 1 つだけです)。たとえば、次のテンプレートを使用して、これらのプロシージャに一貫した名前を付けることが重要ですTablenameInsert
。Tablename
はターゲット テーブルの名前です。
次に、この汎用挿入プロシージャを次のように作成します。
CREATE PROCEDURE InsertIntValue (
@TableName sysname,
@Value int
)
AS
BEGIN
DECLARE @SPName sysname;
SET @SPName = @TableName + 'Insert';
EXECUTE @SPName @Value;
END;
マニュアル からわかるように、コマンドでモジュールを呼び出すときにEXECUTE
、実際のモジュール名の代わりに変数を指定できます。この場合の変数は文字列型である必要があり、実行するモジュールの名前が含まれていると想定されています。構文が異なるため、これは動的 SQL ではありません。(これを動的 SQL にするためには、変数を括弧で囲む必要があります。) 代わりに、これは基本的にモジュール名のパラメーター化であり、おそらく (Transact-)SQL でネイティブにサポートされている唯一の名前のパラメーター化です。
前述したように、これには動的 SQL よりも多くの労力が必要です。これは、このユニバーサル SP が呼び出すことができる多くのストアド プロシージャをすべて作成する必要があるためです。それにもかかわらず、結果として、セキュア (サーバーは変数を SQL の任意のスニペットとしてではなく@SPName
、名前としてのみ見る) かつ効率的 (呼び出される実際のストアド プロシージャが既に存在する、つまり、既に存在する)の両方を備えたコードを取得します。コンパイルされ、クエリ プランがあります)。