我们有很多C#程序和SQL存储过程调用一个可怕写的SQL存储过程(320多行包含许多类似的IF已被复制和粘贴多年),我需要最终清理和加速起来。
注意:
我们有一个具有这种结构的表:
(即:递增的客户#123456,以及非递增的结算周期#1001)
执行时:
我的老板希望只有一个命令能够击中表格。我已经设法用这个片段完成了这个:
DECLARE
@return_value INT,
@parmtype VARCHAR(10),
SET @parmtype = 'CUSTOMER'
UPDATE [system_numbers] -- 1 hit
SET @return_value = current_number = current_number + auto_increment,
last_updated_on =
CASE auto_increment
WHEN 1 THEN GETDATE()
ELSE last_updated_on
END
WHERE [type] = @parmtype
我的问题是,对于非递增的[type],我的命令不必要地更新表,写入日志,并且比SELECT慢。
我的问题是...... 我可以使用哪个命令删除此示例的两个匹配到桌面?
DECLARE
@return_value INT, -- actually an OUTPUT param in my SP
@autoincrement INT,
@parmtype VARCHAR(10)
SET @parmtype = 'CUSTOMER'
SELECT @autoincrement = auto_increment -- 1st hit
FROM [system_numbers]
WHERE [type] = @parmtype
IF (@autoincrement = 1)
BEGIN
UPDATE [system_numbers] -- 2nd hit here - or -
SET @return_value = current_number = current_number + auto_increment,
last_updated_on = GETDATE()
WHERE [type] = @parmtype
END
ELSE
BEGIN
SELECT @return_value = current_number -- 2nd hit here
FROM [system_numbers]
WHERE [type] = @parmtype
END
答案 0 :(得分:1)
我认为这会简化一些事情
DECLARE
@return_value INT, -- actually an OUTPUT param in my SP
@autoincrement INT,
@parmtype VARCHAR(10)
SET @parmtype = 'CUSTOMER'
SELECT @autoincrement = auto_increment, @return_value = auto_increment + current_number -- 1st hit
FROM [system_numbers]
WHERE [type] = UPPER(@parmtype)
IF (@autoincrement = 1)
BEGIN
UPDATE [system_numbers] -- 2nd hit here - or -
SET current_number = @return_value,
last_updated_on = GETDATE()
WHERE [type] = UPPER(@parmtype)
END
答案 1 :(得分:1)
我可能会考虑以下方法:
...
UPDATE dbo.system_numbers
SET @return_value = current_number = current_number + auto_increment,
last_updated_on = GETDATE()
WHERE [type] = @parmtype
AND auto_increment = 1
;
IF @@ROWCOUNT = 0
SELECT @return_value = current_number
FROM dbo.system_numbers
WHERE [type] = @parmtype
;
第一个语句仅在恰好是递增值时更新值,并且还将更新后的值存储在@return_value
中。
如果第一个语句没有更新任何行,则仅执行第二个语句。它只是将(当前)值分配给@return_value
。
所以,只有当值是递增值时才会出现这种情况。当它不递增时,涉及第二次命中,但在这种情况下也没有任何更新,只读。
答案 2 :(得分:0)
我们认为IF EXISTS()命令很快,可以满足我们的需求。
奖励是,如果它返回true,我们知道@parmtype是自动递增的,我们不再需要变量@autoincrement,这样可以使代码更清晰。
DECLARE
@return_value INT, -- OUTPUT param
@parmtype VARCHAR(10)
SET @parmtype = 'CUSTOMER'
IF EXISTS ( SELECT * FROM [table] WHERE [type]=@parmtype AND auto_increment=1 )
BEGIN
UPDATE [table]
SET @return_value = current_number = current_number + auto_increment,
last_updated_on = GETDATE()
WHERE [type] = @parmtype
END
ELSE
BEGIN
SELECT @return_value = current_number
FROM [table]
WHERE [type] = @parmtype
END