【问题标题】:Exception Handling SQL异常处理 SQL
【发布时间】:2017-06-06 13:25:47
【问题描述】:

我创建了一个用户定义的函数来计算产品的库存数量

CREATE OR REPLACE FUNCTION function_quantityInStock(
    oldProductQuantity IN INTEGER,
    orderedQuan IN INTEGER)
    RETURN INTEGER
IS
    v_newQuantity INTEGER;
    v_oldQuantity INTEGER;
    v_orderedQuan INTEGER;
BEGIN
    v_newquantity := oldProductQuantity - orderedQuan;
    RETURN v_newquantity;
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('Please check your data.');
END function_quantityInstock;

然后我创建一个触发器,通过调用函数来更新表

CREATE OR REPLACE TRIGGER TRIGGER_QUANTITY AFTER INSERT ON ordered_product
FOR EACH ROW
DECLARE
    v_oldQuantity INTEGER;
BEGIN
    SELECT PRODUCT_QUANTITYINSTOCK INTO v_oldQuantity
    FROM   product
    WHERE  product_id = :NEW.product_id;

    UPDATE PRODUCT
    SET    product_quantityinstock =
             function_quantityINSTOCK(v_oldQuantity, :NEW.ORDERED_PRODUCTQUANTITY)
    WHERE product_id = :NEW.product_id;
END;

我想在用户输入无效数据时显示一条消息,但我的异常块没有这样做。

我使用以下匿名块来测试功能:

SET SERVEROUTPUT ON;

DECLARE
    v_productID    ordered_product.product_id%TYPE:= &ProductID;
    v_orderID      ordered_product.order_id%TYPE:=&OrderID;
    v_orderedQuan  ordered_product.ordered_productQuantity%TYPE := &OrderedProductQuantity;
    v_totalCost    ordered_product.ordered_productTotalCost%TYPE := '&TotalCost';
BEGIN
    INSERT INTO ordered_product VALUES
    (v_orderID, v_productID, v_orderedQuan, v_totalCost);

    dbms_output.put_line('A new record has been inserted.');
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        dbms_output.put_line('Invalid data!');
    WHEN VALUE_ERROR THEN
        dbms_output.put_line('Error! Please check your values.'|| SQLERRM);
END;

【问题讨论】:

  • 这不是 SQL Server 语法。你用的是什么关系型数据库?
  • 这是纯 PL/SQL - Oracle。我不知道为什么你的问题最终出现在 SQL Server 区域。

标签: oracle plsql exception-handling user-defined-functions


【解决方案1】:

您可能缺少exec dbms_output.enable(10000),因此看不到输出。

你应该使用

抛出异常
raise_application_error(-20000, 'Please check your data.');

使用when others 捕获所有异常然后忽略它们也是不好的做法。

【讨论】:

  • 他在顶部有一个set serveroutput on,所以 dbms_output 应该没问题。不过同意异常处理。
【解决方案2】:

如果我是你,我不会依赖 dbms_output.put_line 来传递信息。相反,依靠标准的异常处理,例如RAISE 或 RAISE_APPLICATION_ERROR。另外,鉴于您正在尝试查找新数量,我会将产品表上的选择移到函数中,例如:

CREATE OR REPLACE FUNCTION function_quantityinstock(p_product_id IN product.product_product_id p_orderedquan IN INTEGER)
  RETURN INTEGER IS
  v_newquantity INTEGER;

  e_not_enough_stock EXCEPTION;
  e_not_enough_stock_num INTEGER := -20001;

  e_no_product_exists_num INTEGER := -20002;

  PRAGMA EXCEPTION_INIT(e_not_enough_stock, -20001);
BEGIN
  SELECT product_quantityinstock - orderedquan
  INTO   v_newquantity
  FROM   product
  WHERE  product_id = :new.product_id;

  IF v_newquantity < 0
  THEN
    RAISE e_not_enough_stock;
  END IF;

  RETURN v_newquantity;

EXCEPTION
  WHEN no_data_found THEN
    raise_application_error(-e_no_product_exists_num,
                    'No product exists for product_id = ' || product_id);

  -- no need to check for TOO_MANY_ROWS if product_id is the primary/unique key on the product table.
  WHEN e_not_enough_stock THEN
    raise_application_error(e_not_enough_stock_num,
                    'Not enough stock present to fulfil the order for product_id = ' ||
                    product_id);

  WHEN OTHERS THEN
    raise_application_error(SQLCODE,
                    'Unexpected error occurred whilst finding new quantity for product_id = ' ||
                    product_id || ': ' || SQLERRM);

END function_quantityinstock;
/

不过,您需要更改函数名称,以反映它正在执行的操作,因为它会返回新的库存数量...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多