我的应用程序中有一些规则,我在程序中编写了规则的业务逻辑。在创建过程时,我发现CASE
语句在我的场景中不起作用。所以我尝试了两种方法来执行相同的操作(使用IF-ELSE-IF
或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语句?如果没有,在我的程序中最好使用哪种方法来提高代码的性能?
答案 0 :(得分: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
答案 1 :(得分:1)
就像你说的那样,我不认为CASE声明会在这里发挥作用。 CASE只返回一个值。我假设您的过程将返回多个值。我喜欢你的GOTO方法。你应该尝试几千个规则,看看性能是否确实是一个问题。
我还有另一个建议。您可以将所有代码放在表中,并将它们作为动态SQL运行。它们不会真正动态,因为它们始终是相同的,因此SQL Server仍然可以缓存这些执行计划。然后案例查找将是您的表索引,这非常快。我不确定它是否比GOTO方法更快。
总之,请尝试使用荒谬的规则,并告诉我们您的结果是什么!
答案 2 :(得分:0)
如果我能在那里处理域层(或应用程序中的Buisness层)中的逻辑,如果可能的话!。因为如果规则数量增加到很多,你将在将来遇到问题(没有人会是能够读取那个大的sql语句:))。 您应该检查面向对象的SOLID原则,特别是OpenClose原则。
从理论上讲,你可以使用这样的案例(取决于规则是什么):
DECLARE @rule int = 1;
SELECT CASE @rule
WHEN 1 THEN
@rule
WHEN 2 THEN
@rule
END
但是,因为sql server不是过程语言,所以你应该尝试将这些规则存储在表中并从set返回规则而不是使用过程逻辑(为了更好的性能)是可能的。