如果不存在则INSERT,否则返回id

Mau*_*amm 7 php sql postgresql

有一些限制:

  1. 无法修改数据库
  2. 列不是唯一的
  3. 需要返回最后一个插入ID(RETURNING id)
  4. 如果存在,则返回现有ID
  5. 它将通过我们的自定义数据库库调用(select中的值将作为PHP的参数(?,?,?,!))

INSERT INTO tags (name, color, groupid)
SELECT  'test', '000000', 56
WHERE NOT EXISTS (
  SELECT text FROM tags WHERE name = 'test' AND groupid = 56
)
RETURNING id
Run Code Online (Sandbox Code Playgroud)

这是有效的 - 直到我需要获得现有的id.有了这个我只得到插入的ID.如果没有插入,是否可以返回SELECT语句的值?

更新:

DO $$
BEGIN
    IF NOT EXISTS (
      SELECT text FROM tags WHERE name = 'test' AND groupid = 56
    )
    THEN
      INSERT INTO tags (name, color, groupid)
          VALUES  ('test', '000000', 56) RETURNING id;
    ELSE
      RETURN SELECT text FROM tags WHERE name = 'test' AND groupid = 56;
    END IF;
END
$$
Run Code Online (Sandbox Code Playgroud)

正在使用这种格式进行测试 - 但最终会出现一些错误:

RETURN cannot have a parameter in function returning void
Run Code Online (Sandbox Code Playgroud)

Gar*_*ary 3

您可以使用 CTE 来完成此操作。

info cte 包含源数据,因此请将其中的值替换为 PHP 的占位符。

如果存在现有记录,CTE 将返回联合前半部分的结果(因此将显示旧的 id),如果执行了插入,则返回后半部分的结果(因此将显示新的 id)。

WITH info (name, color, groupid) AS
  (values('test','000000',56)),
  trial AS (
    INSERT INTO tags(name, color, groupid)
      SELECT info.name, info.color, info.groupid
      FROM info
      WHERE NOT EXISTS (
        SELECT * FROM tags t2
        WHERE t2.name = info.name AND t2.groupid= info.groupid)
    RETURNING id)
SELECT tags.id
FROM tags
INNER JOIN info ON tags.name = info.name AND tags.groupid= info.groupid
UNION ALL
SELECT trial.id
FROM trial;
Run Code Online (Sandbox Code Playgroud)

SQL 小提琴示例:http://sqlfiddle.com/#!15/a7b0f /2

使用 CTE 的 Postgres 手册页

http://www.postgresql.org/docs/9.1/static/queries-with.html