Oracle:如果行不存在,如何插入
在 PL/SQL (oracle) 中,如果行不存在,插入行的最简单方法是什么?
我想要这样的东西:
IF NOT EXISTS (SELECT * FROM table WHERE name = 'jonny') THEN
INSERT INTO table VALUES ("jonny", null);
END IF;
但它不起作用。
注意:此表有 2 个字段,例如姓名和年龄。但只有名字是PK。
What is the easiest way to INSERT a row if it doesn't exist, in PL/SQL (oracle)?
I want something like:
IF NOT EXISTS (SELECT * FROM table WHERE name = 'jonny') THEN
INSERT INTO table VALUES ("jonny", null);
END IF;
But it's not working.
Note: this table has 2 fields, say, name and age. But only name is PK.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
假设您使用的是 10g,您还可以使用 MERGE 语句。这允许您在该行不存在时插入该行,并在存在时忽略该行。当人们想要执行“upsert”时,他们往往会想到 MERGE(如果行不存在则插入,如果行存在则更新),但 UPDATE 部分现在是可选的,因此也可以在此处使用。
Assuming you are on 10g, you can also use the MERGE statement. This allows you to insert the row if it doesn't exist and ignore the row if it does exist. People tend to think of MERGE when they want to do an "upsert" (INSERT if the row doesn't exist and UPDATE if the row does exist) but the UPDATE part is optional now so it can also be used here.
如果 name 是 PK,则只需插入并捕获错误。这样做而不是任何检查的原因是,即使多个客户端同时插入,它也能工作。如果您检查然后插入,则必须在此期间保持锁定,否则无论如何都会出现错误。
其代码类似于
If name is a PK, then just insert and catch the error. The reason to do this rather than any check is that it will work even with multiple clients inserting at the same time. If you check and then insert, you have to hold a lock during that time, or expect the error anyway.
The code for this would be something like
我发现对于您想要确保目标表中存在一行的情况(特别是当您有两列作为主键时),但主键可能根本不存在,因此没有任何内容的情况,遵循这些示例有点棘手来选择。
这对我有用:
关键点是:
USING
块内的SELECT
语句必须始终返回行。如果此查询没有返回任何行,则不会插入或更新任何行。在这里,我从DUAL
中进行选择,因此始终只有一行。ON
条件设置匹配行的条件。如果ON
没有匹配项,则运行 INSERT 语句。I found the examples a bit tricky to follow for the situation where you want to ensure a row exists in the destination table (especially when you have two columns as the primary key), but the primary key might not exist there at all so there's nothing to select.
This is what worked for me:
The key points are:
SELECT
statement inside theUSING
block must always return rows. If there are no rows returned from this query, no rows will be inserted or updated. Here I select fromDUAL
so there will always be exactly one row.ON
condition is what sets the criteria for matching rows. IfON
does not have a match then the INSERT statement is run.WHEN MATCHED THEN UPDATE
clause if you want more control over the updates too.使用@benoit答案的部分内容,我将使用这个:
抱歉,我没有使用任何完整的给定答案,但我需要
IF
检查,因为我的代码比这个带有名称和的示例表复杂得多年龄领域。我需要一个非常清晰的代码。好的谢谢,我学到了很多!我会接受@benoit 的回答。Using parts of @benoit answer, I will use this:
Sorry for I don't use any full given answer, but I need
IF
check because my code is much more complex than this example table with name and age fields. I need a very clear code. Well thanks, I learned a lot! I'll accept @benoit answer.除了到目前为止给出的完美有效的答案之外,还有您可能想要使用的
ignore_row_on_dupkey_index
提示:该提示在 塔希提岛。
In addition to the perfect and valid answers given so far, there is also the
ignore_row_on_dupkey_index
hint you might want to use:The hint is described on Tahiti.
您可以使用以下语法:
如果它打开一个弹出窗口询问“输入替换变量”,则在上述查询之前使用此语法:
you can use this syntax:
if its open an pop for asking as "enter substitution variable" then use this before the above queries:
您应该使用合并:
例如:
或
https://oracle-base.com/articles/9i/merge-声明
You should use Merge:
For example:
or
https://oracle-base.com/articles/9i/merge-statement
CTE并且只有CTE:-)
扔掉多余的东西这里是所有内容几乎完整且详细的形式生活案例。您可以使用任何简洁的形式。
--
--
--
我称之为“如果不存在”。所以,这对我有帮助,而且我大部分都是这么做的。
CTE and only CTE :-)
just throw out extra stuff. Here is almost complete and verbose form for all cases of life. And you can use any concise form.
--
--
--
I call it "IF NOT EXISTS" on steroids. So, this helps me and I mostly do so.