首页 > 解决方案 > 如何对Oracle存储过程中特定数量的项目实现最小和最大验证?

问题描述

我想添加一些验证,以便在我的存储过程中,最小项目数大于或等于 2,最大项目数小于或等于 10。如果项目小于 2 或大于 10,我希望显示一条错误消息并且不执行该过程。如果项目在验证范围内,则存储过程应正常执行。

CREATE OR REPLACE PROCEDURE insert_new_order
(
    p_order_id    IN ORDERS.ORDER_ID%TYPE, 
    p_order_num   IN ORDERS.ORDER_NUMBER%TYPE,
    p_name        IN ORDERS.BILLING_NAME%TYPE,
    p_email       IN ORDERS.BILLING_EMAIL%TYPE,
    p_address     IN ORDERS.BILLING_ADDRESS%TYPE,
    p_city        IN ORDERS.BILLING_CITY%TYPE,
    p_province    IN ORDERS.BILLING_PROVINCE%TYPE,
    p_postcode    IN ORDERS.BILLING_POSTCODE%TYPE,
    p_telephone   IN ORDERS.BILLING_TELEPHONE%TYPE, 
    p_total       IN ORDERS.BILLING_TOTAL%TYPE,
    p_order_date  IN ORDERS.ORDER_DATE%TYPE,
    p_items       IN ORDERS.ITEMS%TYPE
)
AS
BEGIN
    DBMS_OUTPUT.PUT_LINE ('Insert attempted');

    INSERT INTO orders (
      order_id,
      order_number,
      billing_name,
      billing_email,
      billing_address,
      billing_city,
      billing_province,
      billing_postcode,
      billing_telephone,
      billing_total,
      order_date,
      items
    ) VALUES (
      p_order_id,
      p_order_num,
      p_name,
      p_email,
      p_address,
      p_city,
      p_province,
      p_postcode,
      p_telephone,
      p_total,
      p_order_date,
      p_items
    );

    DBMS_OUTPUT.PUT_LINE ('Insert succeeded');

    EXCEPTION
     WHEN others THEN   
        DBMS_OUTPUT.PUT_LINE ('Insert rejected');
      DBMS_OUTPUT.PUT_LINE ('SQL Error Code:  ' || SQLCODE);
      DBMS_OUTPUT.PUT_LINE ('SQL Error Message:  ' || SQLERRM); 
      ROLLBACK;
END;
/

CREATE OR REPLACE TYPE order_item AS object(
    order_id INT, 
    product_id INT,
    seller_id INT, 
    sub_order_number CHAR(10),
    quantity INT, 
    condition CHAR(10),
    unit_price NUMBER, 
    cost_charge NUMBER,
    total NUMBER
);
/

CREATE OR REPLACE TYPE order_items AS Table of order_item;
/

 CREATE TABLE orders (
    order_id INT CONSTRAINT PKEY_order PRIMARY KEY,
    order_number CHAR(10),
    billing_name CHAR(100),
    billing_email CHAR(100),
    billing_address VARCHAR2(100),
    billing_city VARCHAR2(100),
    billing_province VARCHAR2(100),
    billing_postcode VARCHAR2(100),
    billing_telephone CHAR(25),
    billing_total NUMBER,
    order_date DATE,
    Items order_items)
    Nested Table Items Store As Orders_Item
  /

标签: oracleplsqloracle11g

解决方案


我希望这是一个家庭作业问题。如果这是一个真实的系统,那么有几件事是没有意义的——在真实的系统中,为订单项目设置一个嵌套表将是一个很大的问题,不允许碰巧包含单个项目的订单是愚蠢的,等等.

在您的过程中,您可以检查集合中的元素数量作为过程的第一步并引发自定义错误

IF NOT( p_items.count BETWEEN 2 and 10 )
THEN
  RAISE_APPLICATION_ERROR( -20001, 'Orders must have between 2 and 10 items.  This order has ' || p_items.count );
END IF;

您几乎肯定想删除异常处理程序。正如@MT0 指出的那样,when others仅调用的异常处理程序存在dbms_output.put_line很大问题。你不能假设任何人都会看到写入dbms_output缓冲区的消息——绝大多数真实系统不会对该文本做任何事情。如果引发异常,事务将自动回滚。


推荐阅读