如果没有代码块,如何通过事务获取存储过程来执行?

问题描述 投票:0回答:1

我有采用多个参数的存储过程。根据参数值,将执行“插入”或“编辑”过程。在每个过程中,都有多个Update / Insert语句(更新或插入了多个表)。这是我的示例:

CREATE PROCEDURE dbo.stpAddStatus (
    @record_id  NUMERIC(8),
    @new_type_id NUMERIC(2),
    @current_type_id NUMERIC(2),
    @renew SMALLINT,
    @start_date DATETIME,
    @end_date DATETIME
)
AS
BEGIN
    DECLARE @new_end_dt DATETIME
    DECLARE @approve_end_date DATETIME

    IF @current_type_id != 2 AND @current_type_id != 6 
        SET @new_end_dt = @end_date
    ELSE
        SET @new_end_dt = NULL

    SET @approve_end_date = CONVERT(CHAR(10), DATEADD(dd, -1, @start_date), 101)    

    CREATE TABLE #tmpTbl (
        rec_id NUMERIC(8,0) NULL,
        type_id NUMERIC(3,0) NULL,
        active_status NUMERIC(10,0) NULL
    )

    INSERT INTO #tmpTbl (
        rec_id, 
        type_id, 
        status_id
    )
    SELECT 
        a.rec_id, 
        a.type_id, 
        a.active_status 
    FROM profile a 
    WHERE a.related = @record_id  
        AND type_id IN (10,12,13)

    BEGIN TRANSACTION
        IF (@new_type_id = @current_type_id) AND @renew = 0
            SELECT 'New Type ID is the same as Current Type ID and Renew is 0' AS Message
            /* In this block few different tables should be updated. */
        ELSE
            /* In this block record should be inserted in few different tables. */
            SELECT 'New Type ID is not the same as Current Type ID and Renew is 1' AS Message
        IF @@error !=0
        BEGIN 
            SELECT 1 AS Status, 'Error!' AS Message     
            ROLLBACK TRANSACTION
            RETURN 1
        END
    COMMIT TRANSACTION

    DROP TABLE #tmpTbl 
END

上面的代码将同时在If和Else语句中执行代码。我不确定为什么,即使在SP中传递的参数也是这样:

EXECUTE stpAddStatus 45645, 4, 4, 0, '04/23/2018', '06/22/2019'

我不确定我的if / else阻止语句是否正确,或者我错过了其他事情。如果您知道为什么代码失败并且无论在SP中传递了什么参数,都执行两个语句,请告诉我。

sql stored-procedures sybase sybase-ase
1个回答
0
投票

[如果您打算为if和/或else块执行多个命令,则必须将该命令集包装在BEGIN/END对中,例如:

if .... 
begin
    ... 'if' command #1
    ... 'if' command #2
    ...
    ... 'if' command #n
end
else
begin
    ... 'then' command #1
    ... 'then' command #2
    ...
    ... 'then' command #n
end

BEGIN/END是可选的,如果if和/或else块中只有一个命令;如有疑问,请包含BEGIN/END包装器。

同样,在每个命令之后,@@error变量被(重新)设置;我猜您想在任何命令出错的情况下回滚事务,这意味着您需要在each命令后添加更多逻辑以测试@@error;您是在第一个错误之后中止还是在if/then块结尾中止调用。

另一项,如果您的proc在更高级别的事务中被调用(例如,您以链接模式运行),那么您的rollback transaction实际上将回滚所有事务。 [嵌套事务管理是一个完整的'另一个主题。]

© www.soinside.com 2019 - 2024. All rights reserved.