我有一个表 inv_dtl ,其序列为主键。 我需要一个insert语句来按照以下要求插入值:
如果表中已存在该行(主键值除外),我需要插入值为“I”的最后一列( status_flag )的值。
如果它不存在,我需要插入带有 status_flag 列值'A'的值。
答案 0 :(得分:3)
据我所知,您正在使用某种语言来处理数据库。
有两种方法:
select 1 from inv_dtl where col1 = val1 and col2 = val2 etc
。然后插入带有不同标志的新记录。您要在哪种标志中决定使用您的语言的源代码。insert into inv_dtl(col1, col2, etc.) values(val1, val2, etc., case (select 'X' from inv_dtl where col1 = val1 and col2 = val2, etc.) when 'X' then 'I' else 'A' end)
答案 1 :(得分:1)
假设表" inv_dtl"包含字段(" ID"," status_flag")。一个名为" inv_dtl_seq"。
的序列首先,你必须创建一个函数,如下所示
CREATE OR REPLACE FUNCTION inv_dtl_seq_fnc
RETURN NUMBER
IS
v_seq_val NUMBER;
BEGIN
EXECUTE IMMEDIATE 'select inv_dtl_seq.nextval from dual'
INTO v_seq_val;
RETURN v_seq_val;
END inv_dtl_seq_fnc;
现在,尝试以下SQL块,对您有用。
merge into inv_dtl i
using (select inv_dtl_seq_fnc new_id from dual) d
on (i.id = d.new_id)
when matched then
update set status = 'I'
when not matched then
insert values(d.new_id,'A');
答案 2 :(得分:1)
从这个问题来看,似乎所有匹配的记录只有一行,其中status_flag将是'A',假设这样,您可以使用左外连接在新值上编写查询,然后使用case语句,用于标识status_code的值。
INSERT INTO inv_dtl
SELECT a.p_id,
a.col1,
a.col2,
CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
FROM (SELECT 1 p_id, -- new values goes here
100 col1,
'new 2' col2,
'A' status_flag
FROM dual) a
LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
ON b.col1 = a.col1 -- all columns list goes here
AND b.col2 = a.col2
AND b.status_flag = 'A'; -- Status 'A' is fixed.
测试代码:
SQL> create table inv_dtl(p_key number, col1 number, col2 varchar2(10), status_flag varchar2(1));
Table created
SQL> INSERT INTO inv_dtl
2 SELECT a.p_id,
3 a.col1,
4 a.col2,
5 CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
6 FROM (SELECT 1 p_id,
7 100 col1,
8 'new' col2,
9 'A' status_flag
10 FROM dual) a
11 LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
12 ON b.col1 = a.col1
13 AND b.col2 = a.col2
14 AND b.status_flag = 'A';
1 row inserted
SQL>
SQL> INSERT INTO inv_dtl
2 SELECT a.p_id,
3 a.col1,
4 a.col2,
5 CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
6 FROM (SELECT 2 p_id,
7 100 col1,
8 'new' col2,
9 'A' status_flag
10 FROM dual) a
11 LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
12 ON b.col1 = a.col1
13 AND b.col2 = a.col2
14 AND b.status_flag = 'A';
1 row inserted
SQL>
SQL> INSERT INTO inv_dtl
2 SELECT a.p_id,
3 a.col1,
4 a.col2,
5 CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
6 FROM (SELECT 3 p_id,
7 100 col1,
8 'new' col2,
9 'A' status_flag
10 FROM dual) a
11 LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
12 ON b.col1 = a.col1
13 AND b.col2 = a.col2
14 AND b.status_flag = 'A';
1 row inserted
SQL>
SQL> INSERT INTO inv_dtl
2 SELECT a.p_id,
3 a.col1,
4 a.col2,
5 CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
6 FROM (SELECT 4 p_id,
7 200 col1,
8 'new 2' col2,
9 'A' status_flag
10 FROM dual) a
11 LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
12 ON b.col1 = a.col1
13 AND b.col2 = a.col2
14 AND b.status_flag = 'A';
1 row inserted
SQL>
SQL> INSERT INTO inv_dtl
2 SELECT a.p_id,
3 a.col1,
4 a.col2,
5 CASE WHEN b.status_flag IS NULL THEN 'A' ELSE 'I' END AS status_flag
6 FROM (SELECT 5 p_id,
7 200 col1,
8 'new 2' col2,
9 'A' status_flag
10 FROM dual) a
11 LEFT OUTER JOIN (SELECT * FROM inv_dtl) b
12 ON b.col1 = a.col1
13 AND b.col2 = a.col2
14 AND b.status_flag = 'A';
1 row inserted
SQL> select * from inv_dtl;
P_KEY COL1 COL2 STATUS_FLAG
---------- ---------- ---------- -----------
1 100 new A
2 100 new I
3 100 new I
4 200 new 2 A
5 200 new 2 I
SQL>
答案 3 :(得分:0)
以下是您的解决方案的一步一步。退房可能对您有用。
创建功能
CREATE OR REPLACE FUNCTION inv_dtl_seq_fnc(p1 number)
RETURN NUMBER
IS
v_seq_val NUMBER;
BEGIN
if p1 = 0 then
EXECUTE IMMEDIATE 'select inv_dtl_seq.nextval from dual'
INTO v_seq_val;
elsif p1=1 then
EXECUTE IMMEDIATE 'select inv_dtl_seq.currval from dual'
INTO v_seq_val;
end if;
RETURN v_seq_val;
END inv_dtl_seq_fnc;
实际使用案例:
create table inv_dtl(id number, status varchar2(200));
create sequence inv_dtl_seq
start with 1
increment by 1
nocache
nocycle;
insert into inv_dtl values(1,'A');
select * from inv_dtl;
ID STATUS
1 A
insert into inv_dtl(id,status)
values (inv_dtl_seq_fnc(0),case when (select count(1) from inv_dtl where id = inv_dtl_seq_fnc(1)) > 0 then 'I' else 'A' end);
select * from inv_dtl;
ID STATUS
1 A
1 I
insert into inv_dtl(id,status)
values (inv_dtl_seq_fnc(0),case when (select count(1) from inv_dtl where id = inv_dtl_seq_fnc(1)) > 0 then 'I' else 'A' end);
ID STATUS
1 A
1 I
2 A