在PL/SQL(oracle)中,如果行不存在,最简单的方法是什么?
我想要的东西:
IF NOT EXISTS (SELECT * FROM table WHERE name = 'jonny') THEN
INSERT INTO table VALUES ("jonny", null);
END IF;
Run Code Online (Sandbox Code Playgroud)
但它不起作用.
注意:此表有2个字段,例如姓名和年龄.但只有名字是PK.
Ben*_*oit 69
INSERT INTO table
SELECT 'jonny', NULL
FROM dual -- Not Oracle? No need for dual, drop that line
WHERE NOT EXISTS (SELECT NULL -- canonical way, but you can select
-- anything as EXISTS only checks existence
FROM table
WHERE name = 'jonny'
)
Run Code Online (Sandbox Code Playgroud)
Jus*_*ave 35
假设你使用10g,你也可以使用MERGE语句.这允许您插入行(如果它不存在)并忽略该行(如果它存在).当人们想要进行"upsert"时,人们倾向于考虑MERGE(如果行不存在则为INSERT,如果行存在则为UPDATE),但UPDATE部分现在是可选的,因此也可以在此处使用.
SQL> create table foo (
2 name varchar2(10) primary key,
3 age number
4 );
Table created.
SQL> ed
Wrote file afiedt.buf
1 merge into foo a
2 using (select 'johnny' name, null age from dual) b
3 on (a.name = b.name)
4 when not matched then
5 insert( name, age)
6* values( b.name, b.age)
SQL> /
1 row merged.
SQL> /
0 rows merged.
SQL> select * from foo;
NAME AGE
---------- ----------
johnny
Run Code Online (Sandbox Code Playgroud)
Lou*_*nco 17
如果name是PK,那么只需插入并捕获错误.这样做而不是任何检查的原因是它甚至可以在多个客户端同时插入时工作.如果您检查然后插入,则必须在此期间保持锁定,或者无论如何都要预期错误.
这个代码就是这样的
BEGIN
INSERT INTO table( name, age )
VALUES( 'johnny', null );
EXCEPTION
WHEN dup_val_on_index
THEN
NULL; -- Intentionally ignore duplicates
END;
Run Code Online (Sandbox Code Playgroud)
使用@benoit的部分答案,我将使用:
DECLARE
varTmp NUMBER:=0;
BEGIN
-- checks
SELECT nvl((SELECT 1 FROM table WHERE name = 'john'), 0) INTO varTmp FROM dual;
-- insert
IF (varTmp = 1) THEN
INSERT INTO table (john, null)
END IF;
END;
Run Code Online (Sandbox Code Playgroud)
很抱歉我没有使用任何完整的给定答案,但我需要IF
检查,因为我的代码比具有名称和年龄字段的示例表复杂得多.我需要一个非常清晰的代码.谢谢,我学到了很多东西!我会接受@benoit的回答.
我发现在你希望确保目标表中存在一行的情况下,这些例子有点棘手(特别是当你有两列作为主键时),但主键可能根本不存在,所以没有什么选择.
这对我有用:
MERGE INTO table1 D
USING (
-- These are the row(s) you want to insert.
SELECT
'val1' AS FIELD_A,
'val2' AS FIELD_B
FROM DUAL
) S ON (
-- This is the criteria to find the above row(s) in the
-- destination table. S refers to the rows in the SELECT
-- statement above, D refers to the destination table.
D.FIELD_A = S.FIELD_A
AND D.FIELD_B = S.FIELD_B
)
-- This is the INSERT statement to run for each row that
-- doesn't exist in the destination table.
WHEN NOT MATCHED THEN INSERT (
FIELD_A,
FIELD_B,
FIELD_C
) VALUES (
S.FIELD_A,
S.FIELD_B,
'val3'
)
Run Code Online (Sandbox Code Playgroud)
关键点是:
SELECT
内部语句USING
块必须总是返回行.如果此查询没有返回任何行,则不会插入或更新任何行.在这里我选择,DUAL
所以总会有一行.ON
条件是什么套用于匹配行的条件.如果ON
没有匹配,则运行INSERT语句.WHEN MATCHED THEN UPDATE
如果您想要更多地控制更新,也可以添加子句. 归档时间: |
|
查看次数: |
110107 次 |
最近记录: |