繁体   English   中英

在PL SQL中的FOR循环语句中的表中插入值

[英]Inserting values in a table in FOR loop statement in pl sql

我想运行从i = 1到i = 12的循环,然后将M_1,M_2的每个值插入M_Maintenance表中的M_12等。我试过了,但是没有用。请帮帮我。 我尝试过的代码是:

BEGIN
   FOR i IN 1 .. 12
   LOOP
      DECLARE
         M_i               NUMBER;
         MONTH_i_COUNT     NUMBER;
         M_i_Maintenance   NUMBER;
         MONTH_i_SUM       NUMBER;
      BEGIN
         SELECT   ROUND (
                     ( ( (SELECT   SUM (MONTH_i_COUNT)
                            FROM   XXBAXY.XXBAXY_BREAKDOWN_TAB
                           WHERE   LOSS_CAT = 'Maintenance Related Losses')
                        + (SELECT   MONTH_i_COUNT
                             FROM   XXBAXY.XXBAXY_BREAKDOWN_TAB
                            WHERE   LOSS_CAT = 'Maintenance Related Losses'
                                    AND description = 'SAFTY SHEET PRO. ')
                        - (SELECT   MONTH_i_COUNT
                             FROM   XXBAXY.XXBAXY_BREAKDOWN_TAB
                            WHERE   LOSS_CAT = 'Maintenance Related Losses'
                                    AND description =
                                          'PREVENTIVE MAINTENANCE '))
                      / (SELECT   MONTH_i_SUM FROM XXBAXY.XXBAXY_ATTR_SUM_TAB))
                     * 100,
                     3
                  )
           INTO   M_i
           FROM   DUAL;
      EXCEPTION
         WHEN ZERO_DIVIDE
         THEN
            M_i := 0;
      END;
      INSERT INTO M_Maintenance (M_i_Maintenance)
        VALUES   (M_i);
   END LOOP;
END;

首先,让您的查询更易于阅读和更好地执行,如果我没记错的话,应该是这样的查询:

SELECT ROUND(
    SUM(CASE description
    WHEN 'SAFTY SHEET PRO. ' THEN 2*MONTH_i_COUNT
    WHEN 'PREVENTIVE MAINTENANCE ' THEN -MONTH_i_COUNT
    ELSE MONTH_i_COUNT
    END) / MIN(MONTH_i_SUM) *100, 3)
FROM XXBAXY.XXBAXY_BREAKDOWN_TAB
    CROSS JOIN XXBAXY.XXBAXY_ATTR_SUM_TAB 
WHERE LOSS_CAT = 'Maintenance Related Losses'

在这种情况下,您的PL / SQL代码如下所示(跳过异常处理程序):

DECLARE
    m NUMBER;
    sqlstr VARCHAR2(1000);

BEGIN
    FOR i IN 1..12 LOOP           
        sqlstr := 
        'SELECT ROUND( '
        '   SUM(CASE description '
        '   WHEN ''SAFTY SHEET PRO. '' THEN 2*MONTH_'||i||'_COUNT '
        '   WHEN ''PREVENTIVE MAINTENANCE '' THEN -MONTH_'||i||'_COUNT '
        '   ELSE MONTH_'||i||'_COUNT '
        '   END) / MIN(MONTH_'||i||'_SUM) *100, 3) '
        'FROM XXBAXY.XXBAXY_BREAKDOWN_TAB '
        '   CROSS JOIN XXBAXY.XXBAXY_ATTR_SUM_TAB ' 
        'WHERE LOSS_CAT = ''Maintenance Related Losses''';

        EXECUTE IMMEDIATE sqlstr INTO m;
        EXECUTE IMMEDIATE 'INSERT INTO M_Maintenance (M_'||i||'_Maintenance) VALUES (:m)' USING m;
    END LOOP;
END;

您是说表XXBAXY.XXBAXY_BREAKDOWN_TAB包含字段MONTH_1_COUNT,MONTH_2_COUNT,MONTH_3_COUNT等? 如果是这样,由于违反1NF ,第一步应该是重新设计该表。 这是糟糕的设计,是一成不变的痛苦方式。 如果不是,则不清楚为什么您尝试在没有任何字段引用的SQL语句中使用未初始化的本地变量。

通常看来,您应该避免使用FOR LOOP和PL / SQL,而是编写一条插入/选择语句,该语句将产生所需的所有行。

详细说明:您的来源具有以下共同结构:

begin
  for i in MIN..MAX loop
    select something into value 
      from table1 
      where some_condition 
      and id = i;
    insert into table2 values (value);
  end loop;
end;

几乎总是更好的方法是这样做

insert into table2
  select something
  from table1
  where some_condition
  and id in (MIN..MAX);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM