我试图编写一个存储过程来转换它:
|----------|----------|----------|----------|----------|
| ID | ESD | TD | IS_DB | TEST_SET |
|----------|----------|----------|----------|----------|
| 1 | 10 | 20 | 1 | 2 |
| 2 | 30 | (null) | 1 | 2 |
| 3 | 40 | (null) | 1 | 2 |
| 4 | 50 | 60 | 0 | 2 |
| 5 | (null) | 70 | 1 | 2 |
| 6 | 75 | 100 | 1 | 2 |
| 7 | (null) | 80 | 1 | 2 |
|----------|----------|----------|----------|----------|
到此:
|----------|----------|
| DT | FLAG |
|----------|----------|
| 10 | E |
| 20 | H |
| 30 | E |
| 40 | E |
| 50 | E |
| 60 | S |
| 70 | H |
| 75 | E |
| 80 | H |
| 100 | H |
|----------|----------|
业务规则是:
对于TEST_DATA_SOVLP
中的每一行:
如果当前ESD
值不是null
,那么:
<ESD value>
,E
如果当前TD
值不是null
,那么:
IS_DB=0
=&gt;在TEMP中插入值:<TD value>
,S
IS_DB=1
=&gt;在TEMP中插入值:<TD value>
,H
但我没有得到任何接近我期待的东西:
控制台显示对我没用的值:
问题:
有人可以告诉我在我的过程中我做错了什么吗?
为什么没有数据存储在TEMP中?
什么是解决此问题的更简洁方法? 我尝试使用SQL查询(请参阅here)但没有成功。 注意:我有多个类似的proc写入,我希望从一个&#39; master&#39;总结逻辑的过程。
谢谢
1。存储一些数据的表
CREATE TABLE "TEST_DATA_SOVLP"
( "ID" NUMBER,
"ESD" NUMBER,
"TD" NUMBER,
"IS_DB" NUMBER(1,0) DEFAULT 0,
"TEST_SET" NUMBER
)
部分数据
INSERT INTO "TEST_DATA_SOVLP" (ID, ESD, TD, IS_DB, TEST_SET) VALUES ('1', '10', '20', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, ESD, IS_DB, TEST_SET) VALUES ('2', '30', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, ESD, IS_DB, TEST_SET) VALUES ('3', '40', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, ESD, TD, IS_DB, TEST_SET) VALUES ('4', '50', '60', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, TD, IS_DB, TEST_SET) VALUES ('5', '70', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, ESD, TD, IS_DB,TEST_SET) VALUES ('6', '75', '100', '1', '2');
INSERT INTO "TEST_DATA_SOVLP" (ID, TD, IS_DB, TEST_SET) VALUES ('7', '80', '1', '2');
2。用于存储结果的表
CREATE TABLE "TEMP"
( "DT" NUMBER,
"FLAG" VARCHAR2(1 BYTE)
)
第3。 PL / SQL操纵数据并存储结果
CREATE OR REPLACE PROCEDURE S_OVLP
AS
CURSOR cSH IS
SELECT ID, ESD, TD, IS_DB, TEST_SET
FROM TEST_DATA_SOVLP
WHERE TEST_SET = 2;
rec_csh cSH%ROWTYPE;
BEGIN
-- DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE TEMP');
OPEN cSH;
LOOP
FETCH cSH INTO rec_csh;
EXIT WHEN cSH%NOTFOUND;
IF rec_csh.esd IS NOT NULL THEN
INSERT INTO TEMP VALUES (rec_csh.esd, 'E');
dbms_output.put_line(rec_csh.esd || ' E');
END IF;
IF rec_csh.td IS NOT NULL THEN
IF rec_csh.is_db = 1 THEN
INSERT INTO TEMP VALUES (rec_csh.td, 'H');
dbms_output.put_line(rec_csh.td || ' H');
ELSE
INSERT INTO TEMP VALUES (rec_csh.td, 'S');
dbms_output.put_line(rec_csh.td || ' S');
END IF;
END IF;
END LOOP;
CLOSE cSH;
END S_OVLP;
答案 0 :(得分:1)
答案 1 :(得分:1)
根据您的业务规则,您似乎只需使用两个插件即可:
insert into temp
select esd, 'E' from TEST_DATA_SOVLP where test_set=2 and esd is not null;
insert into temp
select td, decode(is_db, 1, 'H', 'S') from TEST_DATA_SOVLP
where test_set=2 and td is not null;
除esd
和td
上的条件外,选项还会在test_set
上“嵌入”条件,由光标在过程中给出。
decode
将is_db
与1进行比较,如果匹配,则使用'H'
,否则使用'S'
(因此2会得到与0相同的结果;但我认为你需要检查你的数据,因为你已经定义了只给1或0的东西。
我已在https://livesql.oracle.com上对其进行了测试,输出看起来不错:
10 E
20 H
30 E
40 E
50 E
60 H
70 H
75 E
100 H
80 H
(该表格包含全部is_db = 1
,请参阅您在问题中提供的插页。)
此外,相应地填充了temp
表。因此,问题无法复制,您的原始程序似乎可以正常工作。
答案 2 :(得分:0)
好吧,我终于使用下面的代码,改变嵌套的IF语句。 但我对PL / SQL的工作方式感到非常失望。
CREATE OR REPLACE PROCEDURE S_OVLP
AS
CURSOR cSH IS
SELECT ID, ESD, TD, IS_DB, TEST_SET
FROM TEST_DATA_SOVLP
WHERE TEST_SET = 2;
rec_csh cSH%ROWTYPE;
BEGIN
DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE TEMP');
OPEN cSH;
LOOP
FETCH cSH INTO rec_csh;
EXIT WHEN cSH%NOTFOUND;
IF rec_csh.esd IS NOT NULL THEN
INSERT INTO TEMP VALUES (rec_csh.esd, 'E');
dbms_output.put_line(rec_csh.esd || ' E');
END IF;
IF rec_csh.td IS NULL THEN
CONTINUE;
END IF;
IF rec_csh.is_db = 1 THEN
INSERT INTO TEMP VALUES (rec_csh.td, 'H');
dbms_output.put_line(rec_csh.td || ' H');
ELSE
INSERT INTO TEMP VALUES (rec_csh.td, 'S');
dbms_output.put_line(rec_csh.td || ' S');
END IF;
END LOOP;
CLOSE cSH;
END S_OVLP;