Oracle 对变量PL/SQL的引用无效

Oracle 对变量PL/SQL的引用无效,oracle,plsql,Oracle,Plsql,我在开始使用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 cus

我在开始使用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.

任何帮助我都将不胜感激

nextval用于从序列中获取下一个值。它通常用于创建伪主键。你可以把它想象成一个只能在序列上调用的特殊函数

v_lastcid是一个变量,其类型与customers表中的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);

希望这有帮助。

您可能想说的是
MAX+1
(参见第7行和第12行),即

虽然它可以工作,但如果两个(或更多)用户获取相同的
MAX
值,那么它在多用户环境中注定会失败;insert将失败,并出现
DUP-VAL-ON-INDEX
错误(如果ID应该是唯一的)

因此,使用序列(这是代码中的
NEXTVAL
所建议的):


为什么你认为v_lastcid是一个序列?事实并非如此。阅读Oracle文档是一个很好的开始。@OldProgrammer-为什么你认为OP认为
v_lastcid
是一个序列?OP甚至可能不知道序列是什么,或者
NEXTVAL
意味着什么。他(她?)。下面的一个答案中对序列的解释对这张海报来说非常有意义。
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>
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.