简体   繁体   English

使用存储过程插入表中

[英]Insert into a table using a stored procedure

I have this simple stored procedure, where it would add a column to my Orders table我有这个简单的存储过程,它会在我的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;

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:错误(6,1):PLS-00103:在预期以下情况之一时遇到符号“DECLARE”:
begin function pragma procedure subtype type current cursor delete exists prior external language The symbol "begin was inserted before "DECLARE" to continue. begin function pragma procedure subtype type current cursor 删除存在先前的外部语言 在“DECLARE”之前插入符号“begin”以继续。

Error(11,1): PLS-00103: Encountered the symbol "END" when expecting one of the following: , ;错误(11,1):PLS-00103:在预期以下之一时遇到符号“END”:,; 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.正如已经提到的,select 的最大订单号然后使用它来插入一行是一个坏主意。 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 .更好地使用 Oracle 的内置特性SEQUENCEIDENTITY

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演示: 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.如果您希望编写PROCEDUREFUNCTION ,则不必使用DECLARE关键字。 In writing a test script or something, you should use the DECLARE keyword to declare variables.在编写测试脚本或其他东西时,您应该使用DECLARE关键字来声明变量。 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.变量应该在ASBEGIN关键字之间定义,并且应该给出数据类型。

If you need to fetch the MAX number of ORDERS TAB you have to write a SQL query for that.如果您需要获取 ORDERS TAB 的最大数量,您必须为此编写一个 SQL 查询。 Because the MAX function only can be used inside a SQL .因为MAX function 只能在SQL内部使用。 Additionally, if you interest there is an in-built feature call SEQUENCE in ORACLE which can use for NEW_ORDER_ID .此外,如果您有兴趣,在 ORACLE 中有一个内置功能调用SEQUENCE可用于NEW_ORDER_ID You can check with the link below.您可以通过下面的链接进行检查。 adding a sequence for oracle plsql为 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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