null怎么insert oracle,Oracle:如果行不存在,如何INSERT

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' )

假设你在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

如果名字是一个PK,那么插入并捕获错误。 这样做而不是任何检查的原因是即使多个客户端同时插入,它也可以工作。 如果您检查并插入,那么您必须在此期间持有锁,或者预期错误。

这个代码会是这样的

BEGIN INSERT INTO table( name, age ) VALUES( 'johnny', null ); EXCEPTION WHEN dup_val_on_index THEN NULL; -- Intentionally ignore duplicates END;

使用@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;

对不起,我没有使用任何完整的给定的答案,但我需要IF检查,因为我的代码比这个名称和年龄字段的示例表复杂得多。 我需要一个非常明确的代码。 非常感谢,我学到了很多! 我会接受@benoit的答案。

我发现这些例子有点棘手,需要确保目标表中存在一行(特别是当您有两列作为主键时),但主键可能根本就不存在,所以没有任何东西select。

这对我来说是有效的:

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' )

关键是:

USING块内的SELECT语句必须总是返回行。 如果没有从此查询返回的行,则不会插入或更新行。 在这里,我从DUALselect,总是只有一行。

ON条件是设置匹配行的条件。 如果ON没有匹配,则运行INSERT语句。

如果您还想更多地控制更新,也可以添加WHEN MATCHED THEN UPDATE子句。

除了迄今给出的完美和有效的答案之外,还有您可能想要使用的ignore_row_on_dupkey_index提示:

create table tq84_a ( name varchar2 (20) primary key, age number ); insert /*+ ignore_row_on_dupkey_index(tq84_a(name)) */ into tq84_a values ('Johnny', 77); insert /*+ ignore_row_on_dupkey_index(tq84_a(name)) */ into tq84_a values ('Pete' , 28); insert /*+ ignore_row_on_dupkey_index(tq84_a(name)) */ into tq84_a values ('Sue' , 35); insert /*+ ignore_row_on_dupkey_index(tq84_a(name)) */ into tq84_a values ('Johnny', null); select * from tq84_a;

提示在大溪地描述。

你可以使用这个语法:

INSERT INTO table_name ( name, age ) select 'jonny', 18 from dual where not exists(select 1 from table_name where name = 'jonny');

如果它打开一个popup询问为“input替代variables”,然后在上述查询之前使用此:

set define off; INSERT INTO table_name ( name, age ) select 'jonny', 18 from dual where not exists(select 1 from table_name where name = 'jonny');

CTE和只有CTE 🙂

只是扔掉额外的东西。 对于所有的生活情况来说,这几乎是完整而冗长的forms。 你可以使用任何简洁的forms。

INSERT INTO reports r (r.id, r.name, r.key, r.param)

-- Invoke this script from "WITH" to the end (";") -- to debug and see prepared values. WITH -- Some new data to add. newData AS( SELECT 'Name 1' name, 'key_new_1' key FROM DUAL UNION SELECT 'Name 2' NAME, 'key_new_2' key FROM DUAL UNION SELECT 'Name 3' NAME, 'key_new_3' key FROM DUAL ), -- Any single row for copying with each new row from "newData", -- if you will of course. copyData AS( SELECT r.* FROM reports r WHERE r.key = 'key_existing' -- ! Prevent more than one row to return. AND FALSE -- do something here for than! ), -- Last used ID from the "reports" table (it depends on your case). -- (not going to work with concurrent transactions) maxId AS (SELECT MAX(id) AS id FROM reports),

-- Some construction of all data for insertion. SELECT maxId.id + ROWNUM, newData.name, newData.key, copyData.param FROM copyData -- matrix multiplication :) -- (or a recursion if you're imperative coder) CROSS JOIN newData CROSS JOIN maxId

-- Let's prevent re-insertion. WHERE NOT EXISTS ( SELECT 1 FROM reports rs WHERE rs.name IN( SELECT name FROM newData ));

我称之为“ 如果不存在 ”类固醇。 所以,这有助于我和我主要是这样做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值