Sql 插入新行并获取主键或获取现有记录的主键
我在Postgres 9.3中有一个简单的标记表:Sql 插入新行并获取主键或获取现有记录的主键,sql,postgresql,postgresql-9.3,Sql,Postgresql,Postgresql 9.3,我在Postgres 9.3中有一个简单的标记表: CREATE TABLE tag ( id SERIAL PRIMARY KEY, text TEXT NOT NULL UNIQUE ); 目前,我可以很容易地插入新标签并取回新id: INSERT INTO tag (text) VALUES ('hey') RETURNING id 但是,我想检查标记是否已经存在(唯一约束),如果它确实存在,则返回现有标记的id 我试图使用COALESCE来实现这一点: SELECT COAL
CREATE TABLE tag (
id SERIAL PRIMARY KEY,
text TEXT NOT NULL UNIQUE
);
目前,我可以很容易地插入新标签并取回新id:
INSERT INTO tag (text) VALUES ('hey') RETURNING id
但是,我想检查标记是否已经存在(唯一约束),如果它确实存在,则返回现有标记的id
我试图使用COALESCE
来实现这一点:
SELECT COALESCE(
(SELECT id FROM tag WHERE text='hey'),
(INSERT INTO tag (text) VALUES ('hey') RETURNING id)
)
但不幸的是,尽管我相信这种逻辑是合理的,但我似乎无法在COALESCE
中使用INSERT
语句(在INTO
中生成语法错误)
实现这一点最简单的方法是什么?这应该会给你同样的结果。如果该行不存在,则创建它。在该部分执行之后,该行肯定会存在,我们选择它的id
IF NOT EXISTS (SELECT id FROM tag WHERE text = 'hey')
BEGIN
INSERT INTO tag (text) VALUES ('hey')
END
SELECT id FROM tag WHERE text = 'hey'
这是他的功劳
我把我的答案放在这里是因为虽然他的答案确实为我指明了方向,但有点不同,我把我的答案简化了一点
WITH
existing AS (SELECT id FROM tag WHERE text='hey'),
new AS (INSERT INTO tag (text) SELECT 'hey' WHERE NOT EXISTS (SELECT 1 FROM existing) RETURNING id)
SELECT id FROM existing UNION ALL SELECT id FROM new
对不起,我不知道PostgreSQL和MSSQL之间的区别。我应该在回答之前调查一下。它是适用于某些平台的有效SQL(MSSQL),因此请更具体地提出批评意见,使其更具建设性。它可能是有效的
T-SQL
,但肯定不是有效的SQL
。SQL中没有IF
语句(也没有BEGIN
或END
),明白了吗。根据原始帖子的语法,我推断它是t-sql或pl/sql。不想争论,只是解释一下。以后我会记住这一点:)