【问题标题】:Oracle Sql Function Compiled (with errors)Oracle Sql 函数已编译(有错误)
【发布时间】:2019-08-08 13:10:18
【问题描述】:

我正在使用以下功能更改密码, 一旦我编译它就会给我编译错误

CREATE or replace FUNCTION updatePassword(CurrentP VARCHAR2,NewPwd VARCHAR2,StudentId VARCHAR2) RETURN VARCHAR2
    is
        getCount integer :=0;
    BEGIN
        Select count(*) into getCount from users where student_id=StudentId and Password=md5(CurrentP);
        if getCount == 1
        then 
        update users set Password=md5(NewPwd) where student_id=StudentId and Password=md5(CurrentP);        
        else
        getCount = 0
    RETURN getCount;
    END;
/

我想在成功更新密码时返回 getCount 值,否则返回 0 下面是错误提示

UPDATEPASSWORD 已编译(有错误)

【问题讨论】:

    标签: oracle oracle11g oracle-sqldeveloper oracle-apex


    【解决方案1】:

    您有一些 PL/SQL 语法问题

    CREATE or replace FUNCTION updatePassword(CurrentP VARCHAR2,NewPwd VARCHAR2,StudentId VARCHAR2) RETURN VARCHAR2
        is
            getCount integer :=0;
        BEGIN
            Select count(*) into getCount from users where student_id=StudentId and Password=md5(CurrentP);
            if getCount = 1
            then 
            update users set Password=md5(NewPwd) where student_id=StudentId and Password=md5(CurrentP);        
            else
            getCount := 0;
            end if;
        RETURN getCount;
        END;
    /
    

    【讨论】:

      【解决方案2】:

      您有一点语法错误。代码应如下所示:

      CREATE or replace FUNCTION updatePassword(
        CurrentP in VARCHAR2,
        NewPwd in VARCHAR2,
        StudentId in number) RETURN number
      is
          getCount number:=0;
      BEGIN
          Select count(*) into getCount from users where student_id=StudentId and Password=md5(CurrentP);
          if getCount = 1
          then 
          update users set Password=md5(NewPwd) where student_id=StudentId and Password=md5(CurrentP);     
          end if;
      RETURN getCount;
      END;
      

      更新: 仔细一看,语法问题很多^^修改了代码。

      建议:

      • 避免使用独立的函数/过程。使用 Oracle 的优势 - 包。有助于避免无效对象的情况;
      • 当您使用 PL/SQL 时 - 尽量遵守 PL/SQL 中的编码标准。
      • 设置正确的变量类型。

      【讨论】:

      • 那还有一个双==,在PL/SQL中没有应用
      【解决方案3】:

      这是一个展示如何做到这一点的示例。

      首先,测试用例。 MD5 函数什么都不做;它只是返回 IN 参数的值。

      SQL> CREATE TABLE users
        2  (
        3     student_id  VARCHAR2 (10),
        4     password    VARCHAR2 (20)
        5  );
      
      Table created.
      
      SQL> INSERT INTO users (student_id, password)
        2       VALUES ('100', 'Stack');
      
      1 row created.
      
      SQL> CREATE OR REPLACE FUNCTION md5 (par_password IN VARCHAR2)
        2     RETURN VARCHAR2
        3  IS
        4  BEGIN
        5     RETURN par_password;
        6  END;
        7  /
      
      Function created.
      
      SQL>
      

      您应该使用 procedure 来修改密码,而不是函数,因为您不能在函数中执行 DML(好吧,你可以,但你不应该' t. 稍后我会告诉你这样做)。

      该过程返回更新的行数;如果你愿意,你可以返回getcount(这是选择行的数量)。

      SQL> CREATE OR REPLACE PROCEDURE updatepassword (p_currentp   IN     VARCHAR2,
        2                                              p_newpwd     IN     VARCHAR2,
        3                                              p_studentid  IN     VARCHAR2,
        4                                              retval          OUT NUMBER)
        5  IS
        6     getcount  INTEGER := 0;
        7  BEGIN
        8     SELECT COUNT (*)
        9       INTO getcount
       10       FROM users
       11      WHERE     student_id = p_studentid
       12            AND password = md5 (p_currentp);
       13
       14     IF getcount = 1
       15     THEN
       16        UPDATE users
       17           SET password = md5 (p_newpwd)
       18         WHERE     student_id = p_studentid
       19               AND password = md5 (p_currentp);
       20
       21        retval := SQL%ROWCOUNT;
       22     END IF;
       23  END;
       24  /
      
      Procedure created.
      
      SQL>
      

      测试:将密码从“堆栈”更改为“溢出”:

      SQL> SET SERVEROUTPUT ON;
      SQL>
      SQL> DECLARE
        2     l_retval  NUMBER;
        3  BEGIN
        4     updatepassword ('Stack',
        5                     'Overflow',
        6                     '100',
        7                     l_retval);
        8     DBMS_OUTPUT.put_line ('retval = ' || l_retval);
        9  END;
       10  /
      retval = 1
      
      PL/SQL procedure successfully completed.
      
      SQL> SELECT * FROM users;
      
      STUDENT_ID PASSWORD
      ---------- --------------------
      100        Overflow
      
      SQL>
      

      似乎还可以。


      这就是你不能使用函数的原因:

      SQL> DROP PROCEDURE updatepassword;
      
      Procedure dropped.
      
      SQL> CREATE OR REPLACE FUNCTION updatepassword (p_currentp   IN VARCHAR2,
        2                                             p_newpwd     IN VARCHAR2,
        3                                             p_studentid  IN VARCHAR2)
        4     RETURN NUMBER
        5  IS
        6     getcount  INTEGER := 0;
        7  BEGIN
        8     SELECT COUNT (*)
        9       INTO getcount
       10       FROM users
       11      WHERE     student_id = p_studentid
       12            AND password = md5 (p_currentp);
       13
       14     IF getcount = 1
       15     THEN
       16        UPDATE users
       17           SET password = md5 (p_newpwd)
       18         WHERE     student_id = p_studentid
       19               AND password = md5 (p_currentp);
       20     END IF;
       21
       22     RETURN getcount;
       23  END;
       24  /
      
      Function created.
      
      SQL> SELECT updatepassword ('Overflow', 'Littlefoot', '100') FROM DUAL;
      SELECT updatepassword ('Overflow', 'Littlefoot', '100') FROM DUAL
             *
      ERROR at line 1:
      ORA-14551: cannot perform a DML operation inside a query
      ORA-06512: at "SCOTT.UPDATEPASSWORD", line 16
      
      
      SQL>
      

      最后,一个 函数 表明您可以执行 DML(但您真的不想这样做) - 使用 pragma autonomous_transaction 指示 Oracle 在该函数中执行代码 与外部交易分开。它要求您提交(或回滚)。

      SQL> CREATE OR REPLACE FUNCTION updatepassword (p_currentp   IN VARCHAR2,
        2                                             p_newpwd     IN VARCHAR2,
        3                                             p_studentid  IN VARCHAR2)
        4     RETURN NUMBER
        5  IS
        6     PRAGMA AUTONOMOUS_TRANSACTION;
        7     getcount  INTEGER := 0;
        8  BEGIN
        9     SELECT COUNT (*)
       10       INTO getcount
       11       FROM users
       12      WHERE     student_id = p_studentid
       13            AND password = md5 (p_currentp);
       14
       15     IF getcount = 1
       16     THEN
       17        UPDATE users
       18           SET password = md5 (p_newpwd)
       19         WHERE     student_id = p_studentid
       20               AND password = md5 (p_currentp);
       21     END IF;
       22
       23     COMMIT;
       24
       25     RETURN getcount;
       26  END;
       27  /
      
      Function created.
      
      SQL> SELECT updatepassword ('Overflow', 'Littlefoot', '100') FROM DUAL;
      
      UPDATEPASSWORD('OVERFLOW','LITTLEFOOT','100')
      ---------------------------------------------
                                                  1
      
      SQL> select * from users;
      
      STUDENT_ID PASSWORD
      ---------- --------------------
      100        Littlefoot
      
      SQL>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-09
        • 1970-01-01
        • 2023-02-21
        • 1970-01-01
        相关资源
        最近更新 更多