通过在PL / SQL中使用FOR LOOP在表中添加多个记录

时间:2017-09-08 14:33:19

标签: sql oracle for-loop plsql

这是我创建的表格:

   CREATE TABLE Screening
  (
   screening_id NUMBER(6) PRIMARY KEY,
   CONSTRAINT check_screening_id CHECK(screening_id > 0),
   plan_id NUMBER(4) NOT NULL,
   theatre_id NUMBER(1) NOT NULL,
   screening_date DATE NOT NULL,
   screening_start_hh24 NUMBER(2) NOT NULL,
   CONSTRAINT check_start_hh24 CHECK(screening_start_hh24 BETWEEN 9 AND 22),
   screening_start_mm60 NUMBER(2) NOT NULL,
   CONSTRAINT check_start_mm60 CHECK(screening_start_mm60 BETWEEN 0 AND 59)
  );

然后我创建了一个序列,我将用它在Screening表的screening_id列中插入:

    CREATE SEQUENCE screening_seq 
    START WITH 1 
    INCREMENT BY 1 
    NOCACHE 
    NOCYCLE;

然后我在屏幕表中插入了19行:

INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),11,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,2,TO_DATE('11/9/2017','DD/MM/YYYY'),13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,TO_DATE('11/9/2017','DD/MM/YYYY'),17,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,1,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,2,TO_DATE('11/9/2017','DD/MM/YYYY'),18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,3,TO_DATE('11/9/2017','DD/MM/YYYY'),19,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,4,TO_DATE('11/9/2017','DD/MM/YYYY'),21,0);

现在我有以下任务问题:

第一天 (11/9/2017 (即screening_date列的值),已经手动添加了19条记录在之前已经演示的筛选表中。同样,我们还需要在第二天(12/9/2017)(即screening_date列的值)添加相同的19条记录。换句话说,我们不断重复在屏幕表中插入相同的19条记录的过程,直到第28天(2017年10月8日)(即screening_date列的值)。因此,28天我们需要插入总共(28 X 19)= 532条记录。但是,我们不是手动添加所有532条记录,而是在PL / SQL中使用FOR LOOP插入它们。

已经给出了提示:

DECLARE
first_date DATE := TO_DATE('11/09/2017','DD/MM/YYYY');
last_date  DATE := TO_DATE('08/10/2017','DD/MM/YYYY');
(no_of_days_var) NUMBER;

BEGIN

SELECT last_date - first_date 
INTO no_of_days 
FROM DUAL;

FOR j in 1.. no_of_days
LOOP

-- your 19 insert statements with screening_date being (your first date var) + j

END LOOP;
END;

我对于在FOR LOOP体内添加什么代码感到困惑和困惑。这是我唯一需要得到的东西。 如果提供了FOR LOOP主体中的解决方案代码,那将非常有用。

2 个答案:

答案 0 :(得分:2)

不要使用PL / SL循环,只需运行一个简单的INSERT ... SELECT
并在SELECT表达式列表中替换“动态”一些值(id和日期) 这只是一天的例子:

INSERT INTO Screening( 
    screening_id, plan_id,theatre_id,screening_date,
    screening_start_hh24, screening_start_mm60
)
SELECT screening_seq.NEXTVAL As screening_id,
       plan_id,
       theatre_id,
       date '2017-09-12' As screening_date,
       screening_start_hh24,
       screening_start_mm60
FROM Screening
where screening_date = date '2017-09-11'
;

这是所有28天(9月11日+次日27天)的例子

INSERT INTO Screening( 
    screening_id, plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60
)
SELECT screening_seq.NEXTVAL As screening_id,
       s.plan_id,
       s.theatre_id,
       rows_generator.new_date As screening_date,
       s.screening_start_hh24,
       s.screening_start_mm60
FROM Screening s
CROSS JOIN (
    select date '2017-09-11' + level as new_date
    from dual
    connect by level <=  date '2017-10-08' - date '2017-09-11'
) rows_generator
where s.screening_date = date '2017-09-11'
;

PL / SQL版本1:

BEGIN
  FOR i IN  1 .. date '2017-10-08' - date '2017-09-12' + 1 LOOP
     INSERT INTO Screening( 
            screening_id, plan_id,theatre_id,screening_date,
            screening_start_hh24, screening_start_mm60
     )
     SELECT screening_seq.NEXTVAL As screening_id,
           plan_id,
           theatre_id,
           date '2017-09-12' + i As screening_date,
           screening_start_hh24,
           screening_start_mm60
     FROM Screening
     WHERE screening_date = date '2017-09-12' ;
  END LOOP;
END;
/

使用批量收集和forall的PL / SQL版本2

DECLARE 
   TYPE my_row_t IS TABLE OF Screening%rowtype;
   my_rows my_row_t;
BEGIN
   -- store rows in the collection
   SELECT * 
   BULK COLLECT INTO my_rows
   FROM Screening
   WHERE screening_date = date '2017-09-12' ;

  FOR i IN  1 .. date '2017-10-08' - date '2017-09-12' + 1 LOOP

      -- update some values in the collection
      FOR j IN 1 .. my_rows.count LOOP
          my_rows( j ).screening_id := screening_seq.NEXTVAL;
          my_rows( j ).screening_date := date '2017-09-12' + j;
      END LOOP;

      -- insert rows from the collection to the table
      FORALL j IN 1 .. my_rows.count 
      INSERT INTO Screening VALUES my_rows( j );

  END LOOP;
END;
/

答案 1 :(得分:1)

顺便说一句,我已经解决了这个问题并且成功了。这就是我接触它的方式:

DECLARE
first_date DATE := TO_DATE('11/09/2017','DD/MM/YYYY');
last_date  DATE := TO_DATE('09/10/2017','DD/MM/YYYY');
no_of_days NUMBER;

BEGIN

SELECT last_date - first_date 
INTO no_of_days 
FROM DUAL;

FOR j in 1.. no_of_days
LOOP
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,first_date + j,9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,first_date + j,11,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,first_date + j,13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,2,first_date + j,13,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,first_date + j,15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,1,3,first_date + j,17,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,first_date + j,9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,first_date + j,12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,1,first_date + j,15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,first_date + j,9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,2,2,first_date + j,15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,first_date + j,9,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,first_date + j,12,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,first_date + j,15,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,3,4,first_date + j,18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,1,first_date + j,18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,2,first_date + j,18,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,3,first_date + j,19,0);
INSERT INTO Screening (screening_id,plan_id,theatre_id,screening_date,screening_start_hh24,screening_start_mm60)
VALUES (screening_seq.NEXTVAL,4,4,first_date + j,21,0);
END LOOP;

END;