在 SQLite 中 IF() 语句的替代方案

33

我有MySQL的Perl代码:

UPDATE pages
SET rkey = rkey + 2,
    lkey = IF(lkey >= $key, lkey + 2, lkey)
WHERE rkey >= $key

我需要在SQLite中使用这段代码,但是IF()函数没有被支持。我该怎么做?

3个回答

70

对于通用的SQL,可以使用CASE

CASE用于为SQL提供if-then-else类型的逻辑。其语法如下:

SELECT CASE ("column_name")
  WHEN "condition1" THEN "result1"
  WHEN "condition2" THEN "result2"
  ...
  [ELSE "resultN"]
  END
FROM "table_name"
http://www.sqlite.org/lang_expr.html 的“The CASE expression”部分获取。
例如。
UPDATE pages
SET rkey = rkey + 2,
    lkey = CASE  WHEN lkey >= $key THEN lkey + 2 ELSE lkey END
WHERE rkey >= $key

这里是一个关于SQLite和CASE的链接(包含使用子查询进行更新的示例)http://sqlite.awardspace.info/syntax/sqlitepg09.htm

在通用SQL中,可以在UPDATE语句中使用CASE,但是我不确定SQLite是否支持带有CASE的UPDATE。

http://www.craigsmullins.com/ssu_0899.htm 的"使用CASE表达式修改数据"章节。


谢谢,但我需要在UPDATE子句中使用它。 - VeroLom
1
VeroLom,只需在UPDATE中尝试它。CASE是基本表达式扫描的一部分,而不是SELECT的一部分。 - osgx
当我使用代码"...lkey = CASE WHEN lkey => $key THEN lkey + 2 ELSE lkey END..."时,SQLite 思考了很长时间但没有结果。 - VeroLom
更新了。如果代码无法运行,您可以尝试使用带有case的子查询。 - osgx
1
嗯...我在sqlitebrowser中尝试了一下,它运行正常,但是当我在Perl中尝试时,等待时间很长。 - VeroLom

10

SQLite 3.32.0及更高版本支持IIF函数。

iif(X,Y,Z)

iif(X,Y,Z)函数在X为真时返回Y,在X为假时返回Z。

iif(X,Y,Z)函数在逻辑上等同于并生成与CASE表达式“CASE WHEN X THEN Y ELSE Z END”相同的字节码。


例如:

UPDATE pages
SET rkey = rkey + 2,
    lkey = IIF(lkey >= $key, lkey + 2, lkey)
WHERE rkey >= $key;

1
请注意,SQLite 3.32.0 版本已于2020年5月22日发布,其中添加了 IIF 函数。 - Mathieu Rey

7
UPDATE pages
SET rkey = rkey + 2,
    lkey = IF(lkey >= $key, lkey + 2, lkey)
WHERE rkey >= $key

??? it to

UPDATE pages
SET lkey = lkey + 2
WHERE rkey >= $key AND lkey >= $key

UPDATE pages
SET rkey = rkey + 2,
WHERE rkey >= $key

这不是更好吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接