Oracle Sql函数已编译(有错误)

时间:2019-03-18 07:53:23

标签: oracle oracle11g oracle-sqldeveloper oracle-apex

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

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已编译(有错误)

  

3 个答案:

答案 0 :(得分:1)

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

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中的编码标准。
  • 设置正确的变量类型。

答案 1 :(得分:1)

您遇到一些PL / SQL语法问题

models

答案 2 :(得分:0)

下面是一个示例,展示了如何执行此操作。

首先,测试用例。 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>

您应该使用程序修改密码,而不是功能,因为您无法在功能中执行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>