3

アプリケーションにいくつかのルールがあり、そのルールのビジネス ロジックを手順に記述しました。プロシージャの作成時に、CASE式が私のシナリオでは機能しないことがわかりました。そのため、以下に示すように、IF-ELSE-IFまたはを使用して同じ操作を実行する2つの方法を試しました。GOTO

方法 1 IF-ELSE-IF 条件を使用する:

DECLARE @V_RuleId SMALLINT;

IF (@V_RuleId = 1) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 2) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 3) 
BEGIN 
    /*My business logic*/
END
/* 
...
...
...
...*/
ELSE IF (@V_RuleId = 19) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 20) 
BEGIN 
    /*My business logic*/
END

方法 2 GOTO ステートメントを使用する:

DECLARE @V_RuleId SMALLINT, @V_Temp VARCHAR(100);

SET @V_Temp = 'GOTO RULE' + CONVERT(VARCHAR, @V_RuleId);
EXECUTE sp_executesql @V_Temp;

RULE1: 
BEGIN 
    /*My business logic*/
END

RULE2: 
BEGIN 
    /*My business logic*/
END

RULE3: 
BEGIN 
    /*My business logic*/
END

/* 
...
...
...
...*/

RULE19: 
BEGIN 
    /*My business logic*/
END

RULE20: 
BEGIN 
    /*My business logic*/
END

今日は20のルールがあります。将来的にはいくらでも増やすことができます。CASE式が使えれば性能的には問題ないのですが、出来ないので手続きの性能が心配です。

また、この手順はアプリケーションによって非常に頻繁に実行されることに注意してください。

私の質問は:

プロシージャで CASE 式を使用する方法はありますか? そうでない場合、コードのパフォーマンスを向上させるために手順で使用するのに最適な方法はどれですか?

4

3 に答える 3

3

これを試してみてください -

DECLARE @V_RuleId SMALLINT
SELECT @V_RuleId = 1;

DECLARE @temp TABLE
(
      RuleID INT
    , Query NVARCHAR(MAX)
)

INSERT INTO @temp (RuleID, Query)
VALUES 
    (1, 'EXEC dbo.usp_test1;'),
    (2, 'CREATE TABLE dbo.Table1 (ID INT);'),
    (3, 'DROP TABLE dbo.Table1;')

DECLARE @SQL NVARCHAR(MAX)

SELECT @SQL = Query 
FROM @temp
WHERE RuleID = @V_RuleId

PRINT @SQL

EXEC sys.sp_executesql @SQL
于 2013-07-01T05:07:59.563 に答える
1

CASEあなたが言ったように、ここでは表現がうまくいかないと思います。CASE1 つの値のみを返します。あなたの手順は複数の値を返すと思います。私はあなたのGOTOアプローチが好きです。数千のルールを試して、パフォーマンスが実際に問題になるかどうかを確認する必要があります。

また、別の提案があります。すべてのコードをテーブルに入れて、動的 SQL として実行できます。それらは常に同じであるため、実際には動的ではありません。そのため、SQL Server はこれらの実行計画を引き続きキャッシュできます。次に、ケース ルックアップは非常に高速なテーブル インデックスになります。GOTOただし、アプローチよりも速いかどうかはわかりません。

結論として、とんでもない数のルールで試してみて、結果を教えてください。

于 2013-06-29T16:22:00.753 に答える
0

可能であれば、ドメインレイヤー(またはアプリのビジネスレイヤー)でそのロジックを処理します。ルールの数が非常に多くなると、将来問題が発生するためです (誰もその大きな SQL ステートメントを読み取ることができなくなります)。

オブジェクト指向の SOLID 原則、特に OpenClose 原則を確認する必要があります。

理論的には、次のようなケースを使用できます (どのルールが実行されているかによって異なります)。

DECLARE @rule  int = 1;
SELECT CASE @rule
WHEN 1 THEN
@rule
WHEN 2 THEN 
@rule
END 

ただし、T-SQL は手続き型言語ではないため、可能であれば、(パフォーマンスを向上させるために) 手続き型ロジックを使用する代わりに、そのルールをテーブルに格納し、セットからルールを返すようにしてください。

于 2013-06-29T10:19:42.903 に答える