2014-03-25 147 views
0
CREATE OR REPLACE PROCEDURE update_item_cost (iItemId INTEGER, fNewcost NUMBER) AS 
    fCurCost NUMBER(10,2); 
    missing_cost EXCEPTION; 
BEGIN 
    SELECT item_cost 
    INTO fCurCost 
    FROM pitem 
    WHERE item_id = iItemId; 

    IF fCurCost IS NULL THEN 
    RAISE missing_cost; 
    ELSE 
    UPDATE pitem 
    SET item_cost = fNewCost 
    WHERE item_id = iItemId; 
    END IF; 

    COMMIT; 

EXCEPTION 
    WHEN no_data_found THEN 
    INSERT INTO pitem_audit 
    VALUES (iItemId, 'Invalid Item identifier.'); 
COMMIT; 
    WHEN missing_cost THEN 
    INSERT INTO pitem_audit 
    VALUES (iItemId, 'Null value replaced by original cost of '||TO_CHAR(fCurCost)); 
    COMMIT; 
    WHEN too_many_rows THEN 
    INSERT INTO pitem_audit 
    VALUES (iItemId, 'More than one row for this item: both rows deleted, new row inserted'); 
    COMMIT; 
    WHEN OTHERS THEN 
    ROLLBACK; 
    INSERT INTO pitem_audit 
    VALUES (iItemId, 'Miscellaneous error.'); 
    COMMIT; 
END update_item_cost; 
/

- 我的问题是处理missing_cost异常的块的语法。 我的消息字符串只显示'空值被原始代价替换'...我需要它包含fCurCost,但由于某种原因它不显示...我不断收到一个警告说:用编译错误创建的过程。 -插入值语句的语法错误

- 也是TOO_MANY_ROWS异常处理程序...我将如何编写代码以删除多行???我已经试过:

DELETE FROM pitem 
WHERE item_id NOT IN(SELECT MAX(item_id) 
        FROM pitem 
        GROUP BY item_id, item_cost); 

- 但无济于事...--

回答

0

values声明希望常量。使用insert . . . select代替:

WHEN missing_cost THEN 
    INSERT INTO pitem_audit 
     select iItemId, 'Null value replaced by original cost of '||TO_CHAR(fCurCost)); 
    COMMIT; 

对于第二个问题:

如果要删除所有,但该行的最高价格:

DELETE FROM pitem 
where cost < (select Max(item_cost) 
       FROM pitem 
       group by item_id 
      ); 
0

1)异常MISSING_COST引发每当fCurCost因此,当您将其值插入pitem_audit时,它将始终为NULL。

2)如果你想删除所有的行,但具有最高ITEM_ID,你应该尝试这样的事:

DELETE FROM pitem 
WHERE item_id NOT IN(SELECT MAX(item_id) 
        FROM pitem); 

你被ITEM_ID分组和ITEM_COST,这意味着你在具有相同item_id和item_cost的行中选择最高的item_id。如果item_id是唯一标识符,则子查询将返回表中的所有行,因为每个item_id都是其组中最高的值。