使用存储过程插入到表中



我有这个简单的存储过程,它将向我的Orders表添加一列

create or replace PROCEDURE ADD_ORDER 
(
CUSTOMER_ID IN NUMBER 
, NEW_ORDER_ID OUT NUMBER 
) AS 
DECLARE
NEW_ORDER_ID := MAX(ORDERS.ORDER_NO) + 1;
BEGIN
INSERT INTO ORDERS(ORDER_NO, REP_NO, CUST_NO, ORDER_DT, STATUS)
VALUES( NEW_ORDER_ID, 36, CUSTOMER_ID, CURDATE(), 'C')
END ADD_ORDER;

它说声明部分不在正确的位置(我认为),也不应该在那里结束。下面是它在错误屏幕上显示的内容:

Error(6,1): PLS-00103: encounter the symbol "DECLARE">
begin函数pragma过程子类型类型当前游标delete存在先前的外部语言符号"begin被插入在"DECLARE"之前继续。

错误(11,1):PLS-00103:遇到符号"END"当期待下列情况之一时:,;返回返回

谁能告诉我这里出了什么问题?

如前所述,选择最大订单号然后使用它来插入一行是一个坏主意。如果两个进程同时执行此操作,它们将尝试插入具有相同顺序号的行。

最好使用Oracle的内置功能SEQUENCEIDENTITY

下面是创建表的方法:
CREATE TABLE orders 
(
order_no  NUMBER(8) GENERATED ALWAYS AS IDENTITY,
rep_no    NUMBER(3)    DEFAULT 36       NOT NULL,
cust_no   NUMBER(8)                     NOT NULL,
order_dt  DATE         DEFAULT SYSDATE  NOT NULL,
status    VARCHAR2(1)  DEFAULT 'C'      NOT NULL
);

你的程序应该是这样的:

CREATE OR REPLACE PROCEDURE add_order 
(
in_cust_no   IN  NUMBER,
out_order_no OUT NUMBER 
) AS
BEGIN
INSERT INTO ORDERS(cust_no) VALUES (in_cust_no)
RETURNING order_no INTO out_order_no;
END add_order;

演示:https://dbfiddle.uk/?rdbms=oracle_18&小提琴= 4 b49723c15eb810c01077286e171bc95

你的代码有语法错误。

NEW_ORDER_ID := MAX(ORDERS.ORDER_NO) + 1; --not be used liked it.

使用以下代码

create or replace PROCEDURE ADD_ORDER 
(
CUSTOMER_ID IN NUMBER 
, NEW_ORDER_ID OUT NUMBER 
) AS 
V_NEW_ORDER_ID NUMBER;
BEGIN
SELECT NVL(MAX(ORDER_NO),0)+1 INTO V_NEW_ORDER_ID FROM ORDERS;

INSERT INTO ORDERS(ORDER_NO, REP_NO, CUST_NO, ORDER_DT, STATUS)
VALUES( V_NEW_ORDER_ID, 36, CUSTOMER_ID, CURDATE(), 'C');

NEW_ORDER_ID:=V_NEW_ORDER_ID;

/* 
* CURDATE() -> I am assuming it is user defined function. You can also use SYSDATE, CURRENT_DATE istead of CURDATE()
* OUT Parameter is a write-only parameter. You cannot read value from OUT Parameter
*/

END ADD_ORDER;

一些事情需要正确。

如果您希望编写PROCEDUREFUNCTION,则不必使用DECLARE关键字。在编写测试脚本或其他东西时,您应该使用DECLARE关键字来声明变量。在编写过程时,

  1. 所有参数都应该在括号内。
  2. 变量应该定义在ASBEGIN关键字之间,并给出数据类型。

如果您需要获取订单选项卡的最大数量,您必须为此编写SQL查询。因为MAX函数只能在SQL内部使用。另外,如果你感兴趣的话,在ORACLE中有一个内置的特性叫做SEQUENCE,它可以用于NEW_ORDER_ID。你可以点击下面的链接查看。添加oracle plsql

的序列我对你的代码做了一些修改。希望现在一切正常。请到这里来看看。

CREATE or REPLACE PROCEDURE ADD_ORDER (
CUSTOMER_ID     IN NUMBER 
NEW_ORDER_ID    OUT NUMBER
) AS
CURSOR get_max_order_no IS
SELECT MAX(order_no)
FROM ORDERS;
rec_ NUMBER := 0;  
BEGIN
OPEN get_max_order_no;
FETCH get_max_order_no INTO rec_;
CLOSE get_max_order_no;
NEW_ORDER_ID := rec_ + 1;
INSERT INTO ORDERS
(ORDER_NO, REP_NO, CUST_NO, ORDER_DT, STATUS)
VALUES 
(NEW_ORDER_ID, 36, CUSTOMER_ID, SYSDATE, 'C');
END ADD_ORDER;