Почему я продолжаю получать эту ошибку? (8,5): PL/SQL: заявление игнорируется

avatar
Andrea Gomez
1 июля 2021 в 17:23
72
2
0

Я создаю хранимую процедуру с PL/SQL для создания автоматического пароля в нужном формате. Нужный формат берется из таблицы сотрудников и оттуда берутся разные данные.

Я продолжал получать эту ошибку, Ошибка (8,5): PL/SQL: Заявление игнорируется. Мой код таков:

CREATE OR REPLACE PROCEDURE sp_password(e_id NUMBER)
IS
    nuevo_password employees.password%TYPE; 

begin
    nuevo_password := lower(SUBSTR(FIRST_NAME, 1, 1)) || lower(LAST_NAME) ||  employee_id || SUBSTR(PHONE_NUMBER, 1, 3);

    select nuevo_password into password from employees; 
    UPDATE employees SET password = nuevo_password WHERE employee_id = e_id;
    
    DBMS_OUTPUT.PUT_LINE('El password para el empleado' || e_id || 'se ha generado exitosamente');
    DBMS_OUTPUT.PUT_LINE('El nuevo password es: ' || nuevo_password);
END;

Я хочу, чтобы хранимая процедура использовалась только после создания пользователя в таблице сотрудников.

Источник

Ответы (2)

avatar
William Robertson
1 июля 2021 в 18:47
0

Во-первых, ошибки, которые я получаю (после создания таблицы employees), не просто "Ошибка(8,5): PL/SQL: Заявление игнорируется", а

LINE/COL   ERROR
---------- ---------------------------------------------------------
6/5        PL/SQL: Statement ignored
6/36       PLS-00201: identifier 'FIRST_NAME' must be declared
9/5        PL/SQL: SQL Statement ignored
9/32       PLS-00201: identifier 'PASSWORD' must be declared
9/41       PL/SQL: ORA-00904: : invalid identifier

так что было бы полезно выяснить, как сообщать об ошибках компиляции в любом инструменте, который вы используете.

Ошибки сообщают вам, что FIRST_NAME и PASSWORD не объявлены как переменные.

После того как вы объявили отсутствующие переменные, вам необходимо заполнить их, используя конструкцию select into, указав employee_id. Лично я бы извлек всю строку сотрудника в запись, а не управлял несколькими отдельными переменными.

create or replace procedure set_password(e_id number)
is
    emp employees%rowtype;
begin
    select * into emp
    from   employees e
    where  e.employee_id = e_id; 

    emp.password :=
        lower(substr(emp.first_name, 1, 1)) ||
        lower(emp.last_name) ||
        emp.employee_id ||
        substr(emp.phone_number, 1, 3);

    update employees e
    set    password = emp.password
    where  employee_id = e_id;
    
    dbms_output.put_line('El password para el empleado ' || e_id || ' se ha generado exitosamente');
    dbms_output.put_line('El nuevo password es: ' || emp.password);
end set_password;

Тестовые значения:

create table employees
( employee_id
, first_name
, last_name
, phone_number
, password )
as
select 123
     , 'Karl'
     , 'Marx'
     , '07345678910'
     , cast('' as varchar2(50))
from dual;
call set_password(123);

El password para el empleado 123 se ha generado exitosamente
El nuevo password es: kmarx123073

С точки зрения безопасности, вы уверены, что хотите сгенерировать предсказуемый пароль? Если бы это был я, я бы предпочел просто установить его на dbms_random.string('a',10).

Andrea Gomez
1 июля 2021 в 19:58
1

Большое спасибо, с этим объяснением я вижу, где была моя ошибка. Я рассмотрю ваш вклад, но он уже работает с форматом, который я искал.

avatar
Atif
1 июля 2021 в 17:31
0

Проблема в строке ниже:

nuevo_password := lower(SUBSTR(FIRST_NAME, 1, 1)) || lower(FIRST_NAME) ||  employee_id || SUBSTR(PHONE_NUMBER, 1, 3);

У вас есть два варианта: либо выбрать значения FIRST_NAME, FIRST_NAME, PHONE_NUMBER в переменной с помощью запроса выбора, а затем объединить, либо записать выбор в запрос и сохранить это объединение в переменной nuevo_password.

Andrea Gomez
1 июля 2021 в 20:01
0

Спасибо, да, теперь я вижу, где была моя ошибка. Мне нужно было иметь значения в переменной. Поэтому я внесу несколько изменений в свой код.