Stored procedures 未通过存储过程准确添加数据(Oracle 11g R2)

Stored procedures 未通过存储过程准确添加数据(Oracle 11g R2),stored-procedures,oracle11g,Stored Procedures,Oracle11g,我有一个临时表,其中的数据是通过sqlldr加载的。临时表中的数据添加如下: 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

我有一个临时表,其中的数据是通过sqlldr加载的。临时表中的数据添加如下:

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 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;
将数据插入“temp”表后,触发器调用一个过程以插入其他表:

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

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 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;
客户订单表中插入的数据不正确。我在以下查询中得到的结果如下所示:

select * from customer_order;

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

订单id 5,10丢失,因为它们与订单id=3来自同一客户。同一客户的多个订单不会添加到客户订单表中。我无法理解我在哪里犯了错误?

问题是,只有当传入的地址在地址表中不存在时,才会将其插入到客户订单中-插入地址过程的例外条款中有

我要做的是创建一个包,然后将获取/存储客户和地址详细信息的步骤作为单独的函数。这样,您就更容易理解代码,从而更容易维护、调试等

比如:

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;

你的程序是正确的,但它遗漏了一件事。“客户地址表”是“客户”和“地址”之间的连接表,在哪里添加行。cust_id和address_id也将被插入CUSTOMER_address表中,以便将它们链接起来。我相信您可以查看我的过程,并确定需要在何处添加额外的insert。需要将'l_cust_id'和'l_address_id'的值一起对CUSTOMER_address进行插入。由于两者的功能不同,我如何使用它们?这就是问题所在,因为我使用相同的过程插入到所有表中。我对pl/sql比较陌生,所以我猜插入客户地址需要在get\u address\u id函数中进行。提示:在函数或过程中添加另一个参数很容易…哦,好的,明白了。谢谢:D