【问题标题】:returning output parameter from Oracle stored proc从 Oracle 存储过程返回输出参数
【发布时间】:2011-03-01 21:02:35
【问题描述】:

我正在尝试设置输出参数thirdPartyId 的值,但在set thirdPartyId 语句中出现missing or invalid option 错误消息。

PROCEDURE usp_insert_user(  userType VARCHAR2,
                                logonId VARCHAR2,
                                title VARCHAR2,
                                firstName VARCHAR2,
                                middleName VARCHAR2,
                                lastName VARCHAR2,
                                comments VARCHAR2,
                                thirdPartyId OUT number) AS
      begin
        set thirdPartyId := select max(third_party_id) + 1 from third_party_user_temp;
        insert into THIRD_PARTY_USER_TEMP
            (Third_party_id,web_logon_id,prsn_type_cd,prsn_title_nm,
            prsn_first_nm,prsn_mdl_nm,prsn_last_nm,addtnl_third_party_txt)
            VALUES(thirdPartyId,logonId,upper(userType),title,
            firstName,middleName,lastName,comments)
        ;
    end usp_insert_user;

这样做的正确方法是什么?

谢谢!

更新:这样更安全吗?

insert into THIRD_PARTY_USER_TEMP
        (Third_party_id,web_logon_id,prsn_type_cd,prsn_title_nm,
        prsn_first_nm,prsn_mdl_nm,prsn_last_nm,addtnl_third_party_txt)
        VALUES((select max(third_party_id) + 1 from third_party_user_temp),logonId,upper(userType),title,
        firstName,middleName,lastName,comments)
        returning third_party_id into thirdPartyId

【问题讨论】:

    标签: sql oracle stored-procedures output-parameter


    【解决方案1】:

    你可以这样做:

    select max(third_party_id) + 1 into thirdPartyId from third_party_user_temp;
    

    如果两个人可以同时运行它,这可能会出现争用问题 - 两者都可能最终得到相同的新 thirdPartyId。您可以查看序列来避免这种情况。


    如果您定义了一个名为thirdPartyIdSeq 的序列,您可以这样做:
    PROCEDURE usp_insert_user(  userType VARCHAR2,
                                    logonId VARCHAR2,
                                    title VARCHAR2,
                                    firstName VARCHAR2,
                                    middleName VARCHAR2,
                                    lastName VARCHAR2,
                                    comments VARCHAR2,
                                    thirdPartyId OUT number) AS
          begin
            insert into THIRD_PARTY_USER_TEMP
                (Third_party_id,web_logon_id,prsn_type_cd,prsn_title_nm,
                prsn_first_nm,prsn_mdl_nm,prsn_last_nm,addtnl_third_party_txt)
                VALUES(third_party_id_seq.nextval,logonId,upper(userType),title,
                firstName,middleName,lastName,comments)
            returning third_party_id into thirdPartyId;
        end usp_insert_user;
    

    这使用序列生成下一个 ID,returning 子句填充您的 OUT 参数。

    您还可以避免该过程并在触发器中生成 ID,再次使用该序列。这种方法的例子很多,尤其是在这个网站上。

    CREATE OR REPLACE TRIGGER third_party_user_temp_bi
    BEFORE INSERT ON third_party_user_temp
    FOR EACH ROW
    BEGIN
        SELECT thirdPartyIdSeq.NEXTVAL
        INTO   :new.third_party_id
        FROM   dual;
    END;
    /
    

    然后您的插入不需要指定要使用的 ID。

    【讨论】:

    • 有没有办法可以在存储过程的开头锁定表并在最后解锁它以避免这种情况?我认为,即使我对 id 使用某种形式的标识,我也必须返回新的 ID,我可能会遇到同样的问题,如果两个人插入一条记录,然后它返回了两个人的 id,他们会得到相同的身份证...
    • 显式锁定可能不是您想深入研究的内容。序列是解决这个问题的方法。
    • 序列是预言机版本的身份?
    • 据我了解你所说的身份是什么意思,然后有点。 Oracle 没有内置列值的自动递增 ID。序列是一个递增的计数器,不会将相同的值返回给两个会话,因此它可用于生成等效于自动递增的 ID,但需要一些代码(通常在触发器中)将下一个值分配给列。
    • Oracle 让我很伤心 :(。无论如何,我正在更新我的问题。新方法更安全吗?
    猜你喜欢
    • 2012-12-24
    • 2015-08-18
    • 2022-08-07
    • 2018-07-28
    • 2019-07-12
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多