3

文字列を受け取り、新しいテキスト文字列を返すストアド プロシージャに取り組んでいます。入力パラメータは@OrderId@OrderText次のようにドル記号で囲まれた変数を持つ文字列です...$Order Name$ sent to $Customer$

有効な変数はVariablesテーブルにあります (注文名、顧客などの値で、合計 25 個あり、かなり静的なままである必要があります)。変数は、文字列内で 1 回だけ使用できます。

ストアド プロシージャは文字列を返す必要がありますが、変数はそれぞれの値に置き換えられます。

例1

入力:123, $Order Name$ sent to $Customer$

戻り値:Toolkit sent to StackCustomer Inc.

例2

入力:456, $Customer$ requests $delivery method$ for $order type$

戻り値:ABC Inc requests fast shipping for pallet orders.

各変数は、関数を使用して取得できます。

    DECLARE @OrderId int = 123
    DECLARE @InputText VARCHAR(500) = '$Order Name$ sent to $Customer$'
    select 
     @InputText = case when @InputText like '%$order name$%' 
             then replace(@InputText, '$Order Name$', getOrderName(id) else '' end,
     @InputText = case when @InputText like '%$customer$' 
             then replace(@InputText, '$Customer$', getCustomer(id) else '' end
      -- repeat 25 times

より良い方法はありますか?私の主な関心事は保守性です。変数が追加、名前変更、または削除された場合、このストアド プロシージャを変更する必要があります (ただし、その場合、年に数回しか発生しないと言われています)。この場合、動的SQLは役に立ちますか?

4

2 に答える 2

3

個人的には、それを維持するためにキーワード テーブルを作成します。このようなもの

CREATE TABLE [keywords] (
  key_value VARCHAR(100) NOT NULL,
  function_value VARCHAR(100) NOT NULL
  )
INSERT INTO [keywords]
VALUES
('$Customer$','getCustomer(id)'),
('$Order Name$' ,'getOrderName(id)'),
('$order type$','getOrderType(id)')

次に、動的 sql create REPLACE SQL を使用します。

DECLARE @OrderId int = 123
DECLARE @InputText VARCHAR(500) = '$Order Name$ sent to $Customer$'

DECLARE @sql VARCHAR(8000) = 'SELECT '

SELECT 
  @sql = @sql + 
  ' @InputText = replace(@InputText, ''' + key_value + ''', ' + function_value + ')'
    + ' ,'
FROM keywords
WHERE  @InputText LIKE '%' + key_value + '%'


SELECT @sql = LEFT(@sql, LEN(@sql) -1)
PRINT @sql

EXEC(@sql)

SQLフィドル

于 2013-04-05T18:21:45.817 に答える
0

プロシージャに入力変数を使用する場合、トークン化を行う必要がある理由がよくわかりません。

次の形式で、SQL Management Studio 用に既に使用可能なトークン テンプレートがあります。

<(tokenName),(datatype),(defaultvalue)>

CTRL + SHIFT + M、または 2012 年には ALT > Q > S を使用して SQL Managment Studio でデータを直接入力するか、環境内で値を検索するテキストによってデータを取得できます。

ADO.NET や C#/VB.NET の Entity Framework などの文字列を変更する外部の開発プラットフォームがアクセスする入力を入力しようとしている場合、入力変数を増やすだけではない理由がわかりません。

これは非常に簡単に実行できます。

Declare @OrderPlace varchar(128), @Customer varchar(64), @StringCombine varchar(512);

Select 
   @OrderPlace = 'Place I am at'
,  @Customer = 'Mr Customer';

Select @StringCombine = @Customer + ' order at ' + @OrderPlace

次に、別の言語が SQL サーバー プロシージャにアクセスする場合、@Customer と @OrderPlace の 2 つのパラメーターを入力するだけで済みます。@StringCombine を出力変数に設定することもできます。これは、テキストを文字に置き換えてから文字列を実行するよりもはるかに望ましい方法です。これにより、SQL インジェクション攻撃が可能になる可能性があるため、特に実行前に SQL を実行するために何かを変更している場合は、入力を浄化することがデータを返す大きな部分になります。

あなたは保守性について言及しましたが、ロジックをprocに変更しても変数名を変更しない場合、他に何も変更する必要がないため、これははるかに堅牢です。参照用に ADO.NET またはその他のライブラリを変更し、次に SQL コードを変更する必要がある場合は、さらに多くの作業が必要になります。一般的に、トークンを扱うときは、コードの一部がダウンしてその部分だけが損なわれる可能性があり、全体がダウンするのではなく、コードの再利用に努めています。

于 2013-04-05T18:21:47.860 に答える