Неверная ссылка на переменную PL / SQL - PullRequest
0 голосов
/ 14 ноября 2018

У меня проблемы с началом работы с PL / SQL Вот мой код:

SET SERVEROUTPUT ON;

DECLARE
    v_cname customers.customer_name%type := '&customer_name';
    v_cardno customers.card_number%type := '&card_number';
    v_lastcid customers.customer_id%type;

BEGIN 
    SELECT customer_id INTO v_lastcid from customers
    where customer_id = (select max(customer_id) from customers);
    dbms_output.put_line(v_lastcid);

    INSERT INTO customers(customer_id, customer_name, card_number)
    VALUES(v_lastcid.NEXTVAL, v_cname, v_cardno);
    COMMIT;
END;

Это возвращает ошибку:

ORA-06550: line 12, column 20:
PLS-00487: Invalid reference to variable 'V_LASTCID'
ORA-06550: line 12, column 20:
PL/SQL: ORA-02289: sequence does not exist
ORA-06550: line 11, column 13:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.

Любая помощь мне бы очень понравилась!

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Вы, вероятно, хотели сказать MAX + 1 (см. Строки 7 и 12), т.е.

SQL> create table customers
  2    (customer_id   number,
  3     customer_name varchar2(20),
  4     card_number   varchar2(20));

Table created.

SQL> DECLARE
  2      v_cname customers.customer_name%type := '&customer_name';
  3      v_cardno customers.card_number%type := '&card_number';
  4      v_lastcid customers.customer_id%type;
  5
  6  BEGIN
  7      SELECT nvl(max(customer_id), 0) INTO v_lastcid from customers
  8      where customer_id = (select max(customer_id) from customers);
  9      dbms_output.put_line(v_lastcid);
 10
 11      INSERT INTO customers(customer_id, customer_name, card_number)
 12      VALUES(v_lastcid + 1, v_cname, v_cardno);
 13      COMMIT;
 14  END;
 15  /
Enter value for customer_name: Little
Enter value for card_number: Foot
0

PL/SQL procedure successfully completed.

SQL> select * from customers;

CUSTOMER_ID CUSTOMER_NAME        CARD_NUMBER
----------- -------------------- --------------------
          1 Little               Foot

SQL>

Хотя он работает , он обречен на неудачу в многопользовательской среде, если два (или более) пользователя получают одно и то же значение MAX; вставка завершится с ошибкой DUP-VAL-ON-INDEX (если идентификатор должен быть уникальным).

Следовательно, используйте последовательность (именно это и предлагает NEXTVAL в вашем коде):

SQL> create sequence seq_cust;

Sequence created.

SQL> DECLARE
  2      v_cname customers.customer_name%type := '&customer_name';
  3      v_cardno customers.card_number%type := '&card_number';
  4      v_lastcid customers.customer_id%type;
  5  BEGIN
  6      INSERT INTO customers(customer_id, customer_name, card_number)
  7      VALUES(seq_cust.nextval, v_cname, v_cardno);
  8      COMMIT;
  9  END;
 10  /
Enter value for customer_name: Big
Enter value for card_number: Foot

PL/SQL procedure successfully completed.
0 голосов
/ 14 ноября 2018

nextval используется для получения следующего значения из последовательности. Обычно используется для создания псевдо-первичного ключа. Вы можете думать об этом как о специальной функции, которую можно вызывать только для последовательностей.

v_lastcid - это переменная того же типа, что и столбец customer_id в таблице клиентов. Так что если бы у вас был такой стол ...

CREATE TABLE CUSTOMERS ( CUSTOMER_ID INTEGER );

... тогда v_lastcid является целым числом;

Если вы пытаетесь сделать фиктивного покупателя со следующим наибольшим номером, возможно, вы имеете в виду что-то вроде ...

INSERT INTO customers(customer_id, customer_name, card_number)
VALUES(v_lastcid + 1, v_cname, v_cardno);

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...