2017-06-06 163 views
0

我创建了一个用户定义的函数,计算库存数量对产品异常处理SQL

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; 

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

我用下面的anonyomus块测试功能:

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; 
+0

这不是SQL Server语法。你使用的是什么RDBMS? –

+0

这是纯粹的PL/SQL - Oracle。我不知道为什么你的问题最终在SQL Server领域。 –

回答

0

您可能忽略exec dbms_output.enable(10000),因此不会看到输出。

你应该扔掉使用

raise_application_error(-20000, 'Please check your data.'); 

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

+1

他在顶部有一个'set serveroutput',所以dbms_output应该可以。尽管同意处理异常。 –

0

如果我是你,我不会依赖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; 
/

你需要改变,虽然函数名,以反映它正在做的动作,因为它正在返回库存中的新数量......