简体   繁体   中英

Insert into a table using a stored procedure

I have this simple stored procedure, where it would add a column to my Orders table

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;

It is saying the the declare part is not at the correct place (I think), and also it should not end there. Here is what it is saying at the error screen:

Error(6,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following:
begin function pragma procedure subtype type current cursor delete exists prior external language The symbol "begin was inserted before "DECLARE" to continue.

Error(11,1): PLS-00103: Encountered the symbol "END" when expecting one of the following: , ; return returning

Can anyone tell me what is going wrong here?

As has been mentioned, it is a bad idea to select the maximum order number and then use that to insert a row. If two processes do this at the same time, they try to insert rows with the same order number.

Better use Oracle's built-in features SEQUENCE or IDENTITY .

Here is how you could create the table:

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
);

And this is what your procedure would look like then:

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;

Demo: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=4b49723c15eb810c01077286e171bc95

There is a syntax error in your code.

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

Use below code

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;

Few things need to be correct.

If you're expecting to write a PROCEDURE or a FUNCTION you don't have to use the DECLARE keyword. In writing a test script or something, you should use the DECLARE keyword to declare variables. When writing a procedure,

  1. All the parameters should be inside the brackets.
  2. Variables should define between AS and BEGIN keywords and should give the datatype.

If you need to fetch the MAX number of ORDERS TAB you have to write a SQL query for that. Because the MAX function only can be used inside a SQL . Additionally, if you interest there is an in-built feature call SEQUENCE in ORACLE which can use for NEW_ORDER_ID . You can check with the link below. adding a sequence for oracle plsql

I did some changes to your code. Hope it's working fine now. Please take a visit here.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM