Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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
Sql 使用情况回滚到具有条件的保存点_Sql_Postgresql_Case_Savepoints - Fatal编程技术网

Sql 使用情况回滚到具有条件的保存点

Sql 使用情况回滚到具有条件的保存点,sql,postgresql,case,savepoints,Sql,Postgresql,Case,Savepoints,是否可以使用大小写回滚到保存点? 我的问题是 BEGIN; SAVEPOINT my_savepoint; INSERT INTO DPoint (uuid) VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214') ON CONFLICT (uuid) DO NOTHING; WITH ins1 AS (INSERT INTO Point (latitude, longitude, srid) VALUES (37.251667, 14.917222,

是否可以使用大小写
回滚到保存点
? 我的问题是

BEGIN;
SAVEPOINT my_savepoint;
INSERT INTO DPoint (uuid) VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214')
ON CONFLICT (uuid) DO NOTHING;
WITH
 ins1 AS (INSERT INTO Point (latitude, longitude, srid)
VALUES (37.251667, 14.917222, 4326) RETURNING id),
 ins2 as (INSERT INTO SPoint (idPt, uuiddpt)
     VALUES ((SELECT id FROM ins1), '5547f4b7-00b3-4aac-8ceb-c9ca163a0214') RETURNING id),
 ins3 as (INSERT INTO Distance (idSpt, uuiddpt)
     VALUES ((SELECT id FROM ins2), '5547f4b7-00b3-4aac-8ceb-c9ca163a0214'))
INSERT INTO DPointTS (uuid, type, name, idPoint)
VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214', NULL, NULL, (SELECT id FROM ins1));

SELECT CASE WHEN
(SELECT uuid FROM DPoint
WHERE uuid = '5547f4b7-00b3-4aac-8ceb-c9ca163a0214' )
is not NULL THEN ROLLBACK TO SAVEPOINT my_savepoint END;
COMMIT;
我的想法是:

SELECT uuid IS NULL AS is_not_uuid FROM DPoint WHERE uuid = '5547f4b7-00b3-4aac-8ceb-c9ca163a0214';
\gset
\if :is_not_uuid
    \echo 'insert row to DPoint'
    INSERT INTO DPoint (uuid) VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214');
    ... 
    my INSERT query

\endif
当再次尝试插入DPoint.uuid='5547f4b7-00b3-4aac-8ceb-C9CA163A014'时,无需插入点、点、距离和DPoint。因此,我想将这些插入回滚到事务中的我的_保存点。也许你知道我必须以什么方式重写代码吗

编辑:

SELECT uuid IS NULL AS is_not_uuid FROM DPoint WHERE uuid = '5547f4b7-00b3-4aac-8ceb-c9ca163a0214';
\gset
\if :is_not_uuid
    \echo 'insert row to DPoint'
    INSERT INTO DPoint (uuid) VALUES ('5547f4b7-00b3-4aac-8ceb-c9ca163a0214');
    ... 
    my INSERT query

\endif

我更新策略时没有保存点-如果SELECT query返回
TRUE
我将评估所有插入。我是如何执行查询的,仅在命令行中?在DataGRIP中的console.sql中尝试时,它会抛出一个错误-它诚实地执行所有行,并在插入到DPoint(uuid)中失败。如果该点已经存在。我想以一种方式执行这些语句

不,你不能那样做

您必须编写客户端代码并使用条件处理

例如,使用
psql

-- set the variable "want_rollback" to TRUE or FALSE
SELECT uuid IS NOT NULL AS want_rollback
FROM dpoint
WHERE uuid = '5547f4b7-00b3-4aac-8ceb-c9ca163a0214' \gset
\if :want_rollback
ROLLBACK TO SAVEPOINT my_savepoint;
\endif
有关
\if
的详细信息,请参阅:

\if表达式

\elif表达式
\else

\endif

这组命令实现可嵌套的条件块。条件块必须以
\if
开头,以
\endif
结尾。在这两个子句之间可以有任意数量的
\elif
子句,可以选择后跟一个
\else
子句。普通查询和其他类型的反斜杠命令可能(通常)出现在构成条件块的命令之间

\if
\elif
命令读取其参数,并将其作为布尔表达式计算。如果表达式产生
true
,则处理继续正常进行;否则,将跳过行,直到达到匹配的
\elif
\else
\endif
为止。一旦
\if
\elif
测试成功,则不会计算同一块中稍后的
\elif
命令的参数,而是将其视为false。只有在前面没有匹配
\if
\elif
成功时,才会处理
\else
后面的行

与任何其他反斜杠命令参数一样,
\if
\elif
命令的
表达式
参数受变量插值和反引号展开的影响。之后,它会像开/关选项变量的值一样进行计算。因此,一个有效值是任何明确的不区分大小写的匹配项:
true
false
1
0
。例如,
t
t
tR
都将被视为
true

未正确计算为true或false的表达式将生成警告并被视为false

被跳过的行通常会被解析以标识查询和反斜杠命令,但查询不会发送到服务器,并且会忽略条件以外的反斜杠命令(
\if
\elif
\else
\endif
)。仅检查条件命令的有效嵌套。跳过行中的变量引用不会展开,也不会执行反引号展开

给定条件块的所有反斜杠命令必须出现在同一源文件中。如果主输入文件或\include ed文件在所有本地\If块关闭之前达到EOF,则psql将引发错误


同一页还将解释
\gset

谢谢您的快速回答!你能告诉我更多关于条件处理的细节吗?我不知道如何使用want\u rollback,\gset…我添加了一些文档。
\if
仅在
psql
中有效。如果您在不同的环境中工作,则必须使用该环境中可用的编程语言。