这个oracle函数代码中有没有表达式错误?

nue99wik  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(143)
CREATE OR REPLACE FUNCTION id_generator(userType VARCHAR2) RETURN NUMBER IS
    new_id NUMBER;
BEGIN
    SELECT
        CASE
            WHEN userType = 'original' THEN original_user
            ELSE guest_user
        END
    INTO new_id
    FROM next_pk
    WHERE ROWNUM = 1;

    FOR UPDATE OF original_user, guest_user;

    IF userType = 'original' THEN
        UPDATE next_pk SET original = original + 256;
    ELSIF userType = 'guest' THEN
        UPDATE next_pk SET guest = guest + 256;
    END IF;

    COMMIT;

    RETURN new_id;
END id_generator;

字符串
这是一个简单的oracle函数,根据输入值“userType”返回original_user列的值或guest_user的值。该函数还将列值更新为value + 256
我使用“select for update”是因为我不想让任何人读到这个函数处理的行。
但是我经常在“CASE”行遇到编译错误。因为我不熟悉plsql,我不知道问题是什么。问题是什么??

kzmpq1sx

kzmpq1sx1#

是的;你发布的代码中有一些问题,比如

  • for update子句 * 在空间中丢失 *
  • 函数应该是autonomous transaction(因为如果你试图在不能使用commitselect语句中使用它,你会得到错误)
  • 不清楚next_pk表中包含哪些列(4列?2列?它们包含什么)?有多少行(在我看来应该只有一行)?

下面是一个例子,看看它是否有帮助。

SQL> CREATE TABLE next_pk
  2  (
  3     original   NUMBER,
  4     guest      NUMBER
  5  );

Table created.

字符串
初始 * 空 * 行(只是为了避免函数中的异常处理):

SQL> INSERT INTO next_pk (original, guest)
  2       VALUES (NULL, NULL);

1 row created.

SQL> COMMIT;

Commit complete.


函数本身:

SQL> CREATE OR REPLACE FUNCTION id_generator (usertype IN VARCHAR2)
  2     RETURN NUMBER
  3  IS
  4     PRAGMA AUTONOMOUS_TRANSACTION;
  5     new_id  NUMBER;
  6  BEGIN
  7     LOCK TABLE next_pk IN EXCLUSIVE MODE;
  8
  9     IF usertype = 'original'
 10     THEN
 11        SELECT NVL (original, 1) + 256 INTO new_id FROM next_pk;
 12
 13        UPDATE next_pk
 14           SET original = new_id;
 15     ELSIF usertype = 'guest'
 16     THEN
 17        SELECT NVL (guest, 1) + 256 INTO new_id FROM next_pk;
 18
 19        UPDATE next_pk
 20           SET guest = new_id;
 21     END IF;
 22
 23     COMMIT;
 24     RETURN new_id;
 25  END;
 26  /

Function created.


测试:

SQL> SELECT * FROM next_pk;

  ORIGINAL      GUEST
---------- ----------

SQL> SELECT id_generator ('original') FROM DUAL;

ID_GENERATOR('ORIGINAL')
------------------------
                     257

SQL> SELECT * FROM next_pk;

  ORIGINAL      GUEST
---------- ----------
       257

SQL> SELECT id_generator ('original') FROM DUAL;

ID_GENERATOR('ORIGINAL')
------------------------
                     513

SQL> SELECT * FROM next_pk;

  ORIGINAL      GUEST
---------- ----------
       513

SQL> SELECT id_generator ('guest') FROM DUAL;

ID_GENERATOR('GUEST')
---------------------
                  257

SQL> SELECT * FROM next_pk;

  ORIGINAL      GUEST
---------- ----------
       513        257

SQL>


如果我是你,我会建议你(不是 * 你 * 个人,而是你工作的公司)接受Erich的建议,切换到identity column(如果你的数据库版本支持它)或sequence,因为看起来你只是在创建没有任何意义的数值。
如果你必须将每年的next_id值或子组织或类似的东西分开,使用你自己的函数可能是有意义的。除此之外,最有可能的是而不是

相关问题