Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编写Postgres Get或Create SQL查询_Sql_Postgresql - Fatal编程技术网

编写Postgres Get或Create SQL查询

编写Postgres Get或Create SQL查询,sql,postgresql,Sql,Postgresql,我想写一条Postgres SQL语句,它表示查找颜色为X、亮度为Y的用户。如果该用户存在,则返回其所有行数据。如果没有,则创建新行并传递附加信息。这两个单独的语句将执行以下操作: Select (color, brightness, size, age) FROM mytable WHERE color = 'X' AND brightness= 'Y'; 如果没有返回任何内容,则执行以下操作: INSERT INTO mytable (color, brightness, size, ag

我想写一条Postgres SQL语句,它表示查找颜色为X、亮度为Y的用户。如果该用户存在,则返回其所有行数据。如果没有,则创建新行并传递附加信息。这两个单独的语句将执行以下操作:

Select (color, brightness, size, age) FROM mytable WHERE color = 'X' AND brightness= 'Y';
如果没有返回任何内容,则执行以下操作:

INSERT INTO mytable (color, brightness, size, age) VALUES (X, Y, big, old);

有没有一种方法可以将它们组合成一个查询???

在SQL DBMS中,select test insert方法是一个错误:没有任何方法可以阻止另一个进程在您的
select
insert
语句之间插入“缺少的”行。改为这样做:

with sel as (
    select color, brightness, size, age
    from mytable
    where color = 'X' and brightness = 'Y'
), ins as (
    insert into mytable (color, brightness, size, age)
    select 'X', 'Y', 6.2, 40
    where not exists (
        select 1 from sel
    )
    returning color, brightness, size, age
)
select color, brightness, size, age
from ins
union
select color, brightness, size, age
from sel
insert into mytable (color, brightness, size, age)
select color, brightness, size, age 
from mytable
where not exists (
    select 1 from 
    from mytable
    where color = 'X' and brightness = 'Y'
);
SELECT (color, brightness, size, age) 
FROM mytable 
WHERE color = 'X' AND brightness= 'Y';

您应该能够将整个文本作为单个“查询”传递给DBMS。您可能需要考虑将其转换成存储过程。 如果列参与唯一索引约束,则可以使用自9.5版以来可用的方法:

INSERT INTO mytable (color, brightness, size, age)
VALUES ('X', 'Y', 'big', 'old')
ON CONFLICT (color) DO NOTHING;
(假设您在
颜色上有唯一索引)


文档是gere:

在此处添加我的解决方案。这与@Clodoaldo Neto和@astef的解决方案略有不同

WITH ins AS (
  INSERT INTO mytable (color, brightness, size, age)
  VALUES ('X', 'Y', 'big', 'old')
  ON CONFLICT (color) DO NOTHING
  RETURNING *
)
SELECT * FROM ins
UNION
SELECT * FROM mytable
  WHERE color = 'X';
我发现astef的解决方案不适合我的目的:它不执行“获取或创建”的“获取”部分!如果该值已经存在,则不会发生任何事情


语句末尾的并集确保如果没有插入值(因为它已经存在),我们仍然从表中检索该值

看到postgresql在
INSERT
语句上的
RETURNING
子句扩展,我最初希望可以使用union将INSERT和select组合在一个语句中,但我尝试了,不幸的是读写操作确实无法以这种方式混合。与此答案相关,对于更好的理解很有用:我无法理解这个答案是如何收集到这么多包含语法错误的选票的。没有选项
插入。。。其中…
用于在Postgres中插入。您可能是想
insert into mytable(颜色、亮度、大小、年龄)选择“X”、“Y”、1.2、3.4,如果不存在…
。我发现上述问题:如果存在冲突,表的串行ID计数器将在每次执行查询时递增。这并不理想。这并不能回答如何获取或创建行的问题。它确实可以。你这样做,然后你做SELET,然后总是成功的。所以你做“(插入或不插入)并得到“@Mitar…它没有。您假设存在冲突,因此这是一个Upsert查询…更新或插入。他们具体要求的是一个GET或CREATE。这意味着您希望查询某一行,如果该行不存在,则创建一个新行……可能根本没有任何冲突。例如,您可能希望查询具有特定ID的行,如果该行不存在,您只需要创建一个具有默认值的新行(随机生成的新ID)