2012-05-30 1 views
3

다음 삽입 작업을 수행하는 가장 좋은 방법은 무엇입니까? 나는 주변을 둘러 보았고, 나는 막혔다.Pl/PgSQL, 헤더 행이있는 테이블 두 개를 삽입하십시오.

내가 현재 가지고있는 테이블 (삽입) 나는 다음과 같은 두 개의 테이블에 이러한 항목을 삽입해야

| id | order_id | item_id | type | group | 
| 1 | 1  | 1  | 2 | 1  | <- type 2 represents a "header" item, or a "kit" 
| 2 | 1  | 2  | 1 | 1  | <- type 1 represents a member of the "kit" 
| 3 | 1  | 3  | 1 | 1  | 
| 4 | 1  | 4  | 2 | 2  | <- New group means new kit 
| 5 | 1  | 2  | 1 | 2  | 
| 6 | 1  | 5  | 1 | 2  | 

:
1) item_entry이

| id | mode | tmplt_id | item_id | parent_item_entry_id | 
| 1 | 1 | 1  | NULL | NULL     | <- This is a header line, mode 1 
| 2 | 2 | NULL  | 2  | 1     | <- This is a sub line, mode 2 
| 3 | 2 | NULL  | 3  | 1     | <- parent_item_entry_id references the header it belongs to 
| 4 | 1 | 4  | NULL | NULL     | 
| 5 | 2 | NULL  | 2  | 4     | 
| 6 | 2 | NULL  | 5  | 4     | 

2)

| id | item_entry_id | order_id | group | 
| 1 | 1    | 1  | 1  | 
| 2 | 4    | 1  | 2  | <- only header information is necessary 
을 item_entry_details

물론 item_entry.id가 구동됩니다. f의 시퀀스 (item_entry_id_seq). 이 방법을 사용할 수있는 우아한 방법이 있습니까? 나는 현재 각 그룹을 반복하며, 먼저 변수에 nextval()을 할당 한 다음 그룹의 각 항목을 반복하여 테이블에 기록합니다.

FOR recGroup IN SELECT DISTINCT group FROM insert LOOP 
    intParentItemEntryID := nextval('item_entry_id_seq'); 
    FOR recLine IN SELECT * FROM insert LOOP 
    INSERT INTO item_entry VALUES (CASE intParentItemEntryID/DEFAULT, CASE 1/2, CASE recLine.item_id/NULL, CASE NULL/recLine.item_id, CASE NULL/intParentItemEntryID) 
    INSERT INTO item_entry_details VALUES (DEFAULT, intParentItemEntryID, recLine.order_id, recLine.group); 
    END LOOP; 
END LOOP; 

더 좋은 방법이 있습니까, 아니면 위와 같은 방법으로 삽입 할 수 있습니까?

답변

4

"row-at-a-time"절차 코드가 필요 없으며 일반 SQL 만 있으면 충분합니다.

-- create the tables that the OP did not provide 
DROP TABLE the_input; 
CREATE TABLE the_input 
    (id INTEGER NOT NULL PRIMARY KEY 
    , order_id INTEGER NOT NULL 
    , item_id INTEGER NOT NULL 
    , ztype INTEGER NOT NULL 
    , zgroup INTEGER NOT NULL 
    ); 
DROP TABLE target1 ; 
CREATE TABLE target1 
    (id INTEGER NOT NULL 
    , zmode INTEGER NOT NULL 
    , tmplt_id INTEGER  
    , item_id INTEGER  
    , parent_item_entry_id INTEGER 
    ); 
DROP TABLE target2 ; 
CREATE TABLE target2 
    (id SERIAL NOT NULL 
    , item_entry_id INTEGER NOT NULL 
    , order_id INTEGER NOT NULL 
    , zgroup INTEGER NOT NULL 
    ); 

-- fil it up ... 
INSERT INTO the_input  
(id, order_id, item_id, ztype, zgroup) VALUES 
(1 , 1  , 1  , 2 , 1 ) -- <- type 2 represents a "header" item, or a "kit" 
,(2 , 1  , 2  , 1 , 1 ) -- <- type 1 represents a member of the "kit" 
,(3 , 1  , 3  , 1 , 1 ) -- 
,(4 , 1  , 4  , 2 , 2 ) -- <- New group means new kit 
,(5 , 1  , 2  , 1 , 2 ) -- 
,(6 , 1  , 5  , 1 , 2 ) -- 
    ; 

-- Do the inserts. 
INSERT INTO target1(id,zmode,tmplt_id,item_id,parent_item_entry_id) 
SELECT i1.id, 1, i1.id, NULL, NULL 
FROM the_input i1 
WHERE i1.ztype=2 
UNION ALL 
SELECT i2.id, 2, NULL, i2.id, ip.item_id 
FROM the_input i2 
JOIN the_input ip ON ip.zgroup = i2.zgroup AND ip.ztype=2 
WHERE i2.ztype=1 
    ; 
INSERT INTO target2(item_entry_id,order_id,zgroup) 
SELECT DISTINCT MIN(item_id),order_id, zgroup 
FROM the_input i1 
WHERE i1.ztype=2 
GROUP BY order_id,zgroup 
    ; 
SELECT * FROM target1 
ORDER BY id; 

SELECT * FROM target2 
ORDER BY id; 

결과 : 도움

NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "the_input_pkey" for table "the_input" 
CREATE TABLE 
INSERT 0 6 
DROP TABLE 
CREATE TABLE 
INSERT 0 6 
id | zmode | tmplt_id | item_id | parent_item_entry_id 
----+-------+----------+---------+---------------------- 
    1 |  1 |  1 |   |      
    2 |  2 |   |  2 |     1 
    3 |  2 |   |  3 |     1 
    4 |  1 |  4 |   |      
    5 |  2 |   |  5 |     4 
    6 |  2 |   |  6 |     4 
(6 rows) 

DROP TABLE 
NOTICE: CREATE TABLE will create implicit sequence "target2_id_seq" for serial column "target2.id" 
CREATE TABLE 
INSERT 0 2 
id | item_entry_id | order_id | zgroup 
----+---------------+----------+-------- 
    1 |    4 |  1 |  2 
    2 |    1 |  1 |  1 
(2 rows) 
+0

감사합니다! 나는 방법이 있어야한다는 것을 알았고, 나는 그것을 알아낼 수 없었다. – BedderDanu

관련 문제