IF THEN ELSE for Procedure出错

时间:2015-11-11 14:35:26

标签: sql oracle if-statement sequence

我试图在我的pl sql代码中创建一个if then else但是下面收到一个错误。我目前使用代码创建一个自动序列,但是当我尝试插入下面的代码时会导致错误,因为O_ID是Orders中的一个整数。如何声明序列

 set serveroutput ON;
 DECLARE
O_ID orders.o_id%type;
Order_Date orders.order_date%type;
Shipment_Date orders.shipment_date%type;
Delivery_Date orders.delivery_date%type;
Shipping_Method orders.Shipping_Method%type;
Shipping_days shipping.shipping_days%type;
Delivery_days shipping.delivery_days%type;

Regular number := 3;
Express_shipping number := 2;

   Begin
   O_ID := 'orders_seq.NEXTVAL';
   Order_Date := SYSDATE;
   Shipment_Date := SYSDATE;
Delivery_Date := SYSDATE;
   Shipping_Method := 'Regular';

Shipping_days := 3;
Delivery_days := 5;

    IF Shipping_Method = Regular THEN 
        Shipping_Days := 3;
        Delivery_days := 5;

    ELSIF Shipping_Method = Express_shipping THEN 
        Shipping_Days := 1;
        Delivery_days := 2;
    END IF;

   Insert into Orders(O_ID,Order_Date,Shipping_method,Shipment_date,Delivery_date,Shipping_method)
   Values(O_ID,Order_Date,O_ID,Order_Date,Shipping_method,Shipment_date,Delivery_date,Shipping_method);
  COMMIT;   
  dbms_output.put_line('Order ID: ' || O_ID);
END;

错误:

ERROR at line 1: 
 ORA-06502: PL/SQL: numeric or value error: character to number conversion error 
 ORA-06512: at line 26 

4 个答案:

答案 0 :(得分:1)

此问题是SHIPPING_METHOD中的变量。如果它们是字符串,则无法进行此比较

IF Shipping_Method = Regular THEN

this should be 

IF Shipping_Method = 'Regular' THEN

您可以声明CONSTANT VARCHAR2(20)来表示送货方式,这样可以减少出错的可能性。

DECLARE
c_shipping_regular CONSTANT VARCHAR2(20) := 'Regular';

BEGIN
IF Shipping_Method = c_shipping_regular THEN
....

答案 1 :(得分:1)

您的代码中有几处错误:

DECLARE
O_ID orders.o_id%type;
Order_Date orders.order_date%type;
Shipment_Date orders.shipment_date%type;
Delivery_Date orders.delivery_date%type;
Shipping_Method orders.Shipping_Method%type;
Shipping_days shipping.shipping_days%type;
Delivery_days shipping.delivery_days%type;

Regular number := 3;
Express_shipping number := 2;

Begin
   --O_ID := 'orders_seq.NEXTVAL';
   -- Must be
   O_ID := orders_seq.NEXTVAL;
   Order_Date := SYSDATE;
   Shipment_Date := SYSDATE;
   Delivery_Date := SYSDATE;
   --Shipping_Method := 'Regular';
   -- Either use the number or define constants and use them
   Shipping_Method := 3;

   Shipping_days := 3;
   Delivery_days := 5;

    IF Shipping_Method = Regular THEN 
        Shipping_Days := 3;
        Delivery_days := 5;

    ELSIF Shipping_Method = Express_shipping THEN 
        Shipping_Days := 1;
        Delivery_days := 2;
    END IF;

   Insert into Orders(
      O_ID, 
      Order_Date,
      Shipping_method,
      Shipment_date,
      Delivery_date,
      Shipping_method)
   Values(
      O_ID,
      Order_Date,
      --O_ID,
      --Order_Date,
      Shipping_method,
      Shipment_date,
      Delivery_date,
      Shipping_method);
  COMMIT;   
  dbms_output.put_line('Order ID: ' || O_ID);
END;

答案 2 :(得分:0)

错误消息表明您正在尝试将非数值赋给数字字段。看看你的插入语句看起来有些不对劲。你将o_id,order_date放在values()中两次。

insert into orders
   (o_id
   ,order_date
   ,shipping_method
   ,shipment_date
   ,delivery_date
   ,shipping_method)
values
   (o_id
   ,order_date
   ,o_id
   ,order_date
   ,shipping_method
   ,shipment_date
   ,delivery_date
   ,shipping_method);

答案 3 :(得分:0)

您尝试使用字符串文字设置应该是数字的变量。看起来在您的实验中,您尝试通过shipping_method变量将regular变量的值设置为3;但由于您已将其用单引号括起来,因此您需要分配字符串文字('Regular')而不是数字(Regular没有引号,或只是3)。您对O_ID执行相同的操作,指定字符串文字而不是序列nextval调用的结果。我想你的意思是:

O_ID := orders_seq.NEXTVAL;
Shipping_Method := Regular;

但您在评论中说shipping_method列实际上是一个字符串,因此将regularexpress_shipping声明为数字,并将它们设置为2和3 ,没有意义。如果它们应该是字符串值,那么使用您在该列中实际拥有的任何值来适当地声明和设置它们:

l_Regular orders.Shipping_Method%type := 'REGULAR';
l_Express_shipping orders.Shipping_Method%type := 'EXPRESS';

分配和比较会更有意义,但是当你在看似多余的时候使用固定值时 - 可能shipping_method最终会来自其他地方。

DECLARE
  l_O_ID orders.o_id%type;
  l_Order_Date orders.order_date%type;
  l_Shipment_Date orders.shipment_date%type;
  l_Delivery_Date orders.delivery_date%type;
  l_Shipping_Method orders.Shipping_Method%type;
  l_Shipping_days shipping.shipping_days%type;
  l_Delivery_days shipping.delivery_days%type;

  l_Regular orders.Shipping_Method%type := 'REGULAR';
  l_Express_shipping orders.Shipping_Method%type := 'EXPRESS';

Begin
  l_O_ID := orders_seq.NEXTVAL;
  l_Order_Date := SYSDATE;
  l_Shipment_Date := SYSDATE;
  l_Delivery_Date := SYSDATE;
  l_Shipping_Method := l_Regular;

  l_Shipping_days := 3;
  l_Delivery_days := 5;

  IF l_Shipping_Method = l_Regular THEN 
    l_Shipping_Days := 3;
    l_Delivery_days := 5;
  ELSIF l_Shipping_Method = l_Express_shipping THEN 
    l_Shipping_Days := 1;
    l_Delivery_days := 2;
  END IF;

  Insert into Orders(O_ID,Order_Date,Shipping_method,Shipment_date,
     Delivery_date)
  Values(l_O_ID,l_Order_Date,l_Shipping_method,l_Shipment_date,
     l_Delivery_date);

  dbms_output.put_line('Order ID: ' || l_O_ID);
END;

您还试图在表中插入太多值,因为您重复了O_IDOrder_DateShipping_method;所以我删除了额外的引用。

使用列名作为变量名可能会导致混淆和错误(特别是更新),所以我用l_为它们加上前缀 - 任何惯例都可以。你真的不需要它们;您可以直接在插入中使用序列和sysdate引用:

  Insert into Orders(O_ID,Order_Date,Shipping_method,Shipment_date,
     Delivery_date)
  Values(orders_seq.NEXTVAL,SYSDATE,l_Shipping_method,SYSDATE,
     SYSDATE);

  dbms_output.put_line('Order ID: ' || orders_seq.CURRVAL);