2017-05-19 74 views
0

我有一张临时表,其中的数据通过sqlldr加载。在临时表中的数据被添加如下:数据被插入到“临时”表未通过存储过程准确添加数据(Oracle 11g R2)

PHONE  ADDRESS  ORDER_ID 
9971410000 D-166 GF 1 
9910020000 H-12D  2 
9873120000 K-19C  3 
9811120000 J-200  4 
9873120000 K-19C  5 
9810320000 N-29B  6 
9810390000 J-235 GF 7 
9873500000 M-39  8 
8447910000 J-62 GF  9 
9873120000 K-19C  10 

之后,触发器调用的过程插入到其他表:

create or replace TRIGGER insert_customer 
AFTER INSERT ON temp 
FOR EACH ROW 
BEGIN 
    insert_address(:new.phno, :new.addr, :new.ord_id); 
END; 

的过程如下所示:

create or replace procedure INSERT_ADDRESS(
    p_cust_phone customer.cust_phone%type, 
    p_address address.address%type, 
    p_ord_id customer_order.order_id%type 
    ) 
    is 
    l_cust_id customer.cust_id%type; 
    l_address_id address.address_id%type; 
    begin 
    begin 
     select cust_id 
     into l_cust_id 
     from customer c 
     where c.cust_phone=p_cust_phone; 
    exception 
     when no_data_found then 
     insert into customer 
     values (cust_id_seq.nextval, 'No Name', p_cust_phone) 
     returning cust_id into l_cust_id; 
    end; 

     select address_id 
     into l_address_id 
     from address a 
     where a.address=p_address; 
    exception 
     when no_data_found then 
     insert into address 
     values (address_id_seq.nextval, UPPER(p_address), UPPER(p_area)) 
     returning address_id into l_address_id; 

    insert into customer_address 
    values (l_cust_id, l_address_id); 

    insert into customer_order (order_id, cust_id) 
    values (p_ord_id,l_cust_id); 

    end; 

插入到CUSTOMER_ORDER表中的数据不正确。结果我得到了下面的查询如下:

select * from customer_order; 

ord_id cust_id 
1   1 
2   2 
3   3 
4   4 
6   5 
7   6 
8   7 
9   8 

,因为他们来自同一个客户为ord_id = 3 ORDER_ID(5,10)都将丢失。 customer_order表中不添加同一客户的多个订单。我无法理解我犯了什么错误?

回答

1

问题是,只有在地址表中不存在被传入的地址时,才会将您插入到customer_order中 - 您已在insert_address过程的异常子句中找到它。

我会做的是创建一个包,然后让步骤将客户和地址细节作为单独的函数获取/存储。这样一来,你更容易理解的代码,这使得它更易于维护,调试等

喜欢的东西:

CREATE OR REPLACE PACKAGE BODY customer_pkg 
AS 
    FUNCTION get_customer_id (p_cust_phone customer.cust_phone%TYPE) 
    RETURN customer.cust_id%TYPE 
    IS 
    l_cust_id customer.cust_id%TYPE; 
    BEGIN 
    SELECT cust_id 
    INTO l_cust_id 
    FROM customer 
    WHERE cust_phone = p_cust_phone; 

    EXCEPTION 
    WHEN no_data_found THEN 
     INSERT INTO customer (cust_id, cust_name, cust_phone) 
     VALUES (cust_id_seq.nextval, 'No Name', p_cust_phone) 
     RETURNING cust_id INTO l_cust_id; 
    END get_customer_id; 

    FUNCTION get_address_id (p_address address.address%TYPE) 
    RETURN address.address_id%TYPE 
    IS 
    l_address_id address.address_id%TYPE; 
    BEGIN 
    SELECT address_id 
    INTO l_address_id 
    FROM address 
    WHERE address = p_address; 

    EXCEPTION 
    WHEN no_data_found THEN 
     INSERT INTO address (address_id, address) 
     VALUES (address_id_seq.nextval, p_address) 
     RETURNING address_id INTO l_address_id; 
    END get_address_id; 

    PROCEDURE insert_order(p_cust_phone customer.cust_phone%TYPE, 
         p_address address.address_i%TYPE, 
         p_ord_id  customer_order.order_id%TYPE) 
    IS 
    l_cust_id customer.cust_id%TYPE; 
    l_address_id address.address_id%TYPE; 
    BEGIN 
    l_cust_id := get_customer_id (p_cust_phone => p_cust_phone); 
    l_address_id := get_address_id (p_address => p_address); 

    INSERT INTO customer_order (order_id, cust_id) 
    VALUES (p_ord_id, l_cust_id); 
    END insert_order; 

END customer_pkg; 
/

那么你的触发会是什么样子:

create or replace TRIGGER insert_customer 
AFTER INSERT ON temp 
FOR EACH ROW 
BEGIN 
    customer_pkg.insert_order(p_cust_phone => :new.phno, 
          p_address => :new.addr, 
          p_ord_id => :new.ord_id); 
END insert_customer; 
+0

你的程序是正确但错过了一件事。你在哪里添加行到'CUSTOMER_ADDRESS'表中,它是'CUSTOMER'和'ADDRESS'之间的交接表。cust_id和address_id也将被插入到CUSTOMER_ADDRESS表中,以便连接它们。 –

+0

我相信你可以看看我的过程并找出需要添加额外插入的位置 – Boneist

+0

'l_cust_id'和'l_address_id'的值需要一起在CUSTOMER_ADDRESS上执行插入操作。由于两者在不同的函数中,因此如何使用他们?这是因为我使用相同的过程插入到所有表中的问题。我是相对较新的pl/sql。 –