Функция Oracle Sql скомпилирована (с ошибками) - PullRequest
0 голосов
/ 18 марта 2019

Я использую функцию ниже, чтобы изменить пароль, это дает мне ошибку компиляции после компиляции

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 ]

1 голос
/ 18 марта 2019

У вас есть некоторые проблемы с синтаксисом 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;
/
1 голос
/ 18 марта 2019

У вас небольшая синтаксическая ошибка.Код должен выглядеть примерно так:

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.
  • Установите правильные типы переменных.
0 голосов
/ 18 марта 2019

Вот пример, который показывает, как это сделать.

Во-первых, контрольный пример. Функция 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 в функции (ОК, вы можете , но не должны. Я покажу вам шоу, чтобы сделать это позже).

Процедура возвращает количество обновленных строк; при желании вы можете вернуть 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>
...