4

動的テーブルに値を挿入するストアド プロシージャを作成できるかどうか疑問に思っていました。

私は試した

create procedure asd
(@table varchar(10), @id int)
as
begin
    insert into @table values (@id)
end

@tableテーブル変数としても定義

ご協力いただきありがとうございます!

4

3 に答える 3

2

これはあなたのために働くかもしれません。

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

于 2013-03-23T12:45:00.867 に答える
1

動的 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 も渡す必要があります。

于 2013-03-23T13:35:41.503 に答える
1

はい、これを直接実装するには、他の人が示唆しているように、動的 SQL が必要です。ただし、この種の普遍性を試みると、コードの安全性や効率が低下する可能性があるという@Tomalakのコメントにも同意します。

このレベルの動的性が必要だと思われる場合は、次のアプローチを試すことができます。これは、単純な動的 SQL よりも多くの労力が必要ですが、後者とほぼ同じですが、前述の欠点はありません。

アイデアは、最初に必要なすべての挿入手順を作成することです。この種類の多くの値を挿入するテーブルごとに 1 つです (つまり、例のように、int値は 1 つだけです)。たとえば、次のテンプレートを使用して、これらのプロシージャに一貫した名前を付けることが重要ですTablenameInsertTablenameはターゲット テーブルの名前です。

次に、この汎用挿入プロシージャを次のように作成します。

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、名前としてのみ見る) かつ効率的 (呼び出される実際のストアド プロシージャが既に存在する、つまり、既に存在する)の両方を備えたコードを取得します。コンパイルされ、クエリ プランがあります)。

于 2013-03-27T15:52:23.807 に答える