可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12

变量

适用于 ❌ 开源版   ✅ Express 版   ✅ 专业版   ✅ 企业版

在命令式语言中,局部变量是临时存储数据以供进一步处理的重要方式。 所有过程语言都有声明、赋值和引用此类局部变量的方法。

声明

在 jOOQ 中,可以使用 DSL.var() 创建局部变量表达式(不要与 DSL.val(T) 混淆,后者会创建绑定值!)

Variable<Integer> i = var("i", INTEGER);

这个变量本身没有任何作用。 但与 jOOQ 中的许多事物一样,它必须首先在实际 jOOQ 表达式之外声明,才能在 jOOQ 表达式中使用。

我们现在可以在声明语句中引用该变量,如下所示

-- MySQL syntax
DECLARE i INTEGER;
// All dialects
declare(i)

请注意,在不同的方言中,有很多不同的方法可以声明局部变量。 有

Oracle PL/SQL、PostgreSQL pgplsql 风格

在这些语言中,DECLARE 语句实际上不是可以在任何地方使用的独立语句。 它是 过程块的一部分,位于 BEGIN .. END 之前

-- PL/SQL syntax
DECLARE
  i INT;
BEGIN
  NULL;
END;

使用 jOOQ 时,您可以安全地忽略此事实,并在这些方言中添加 DECLARE 语句。 jOOQ 会将额外的 BEGIN .. END 块添加到您的周围块中,以确保整个块在语法和语义上都是正确的。

T-SQL、MySQL 风格

在这些语言中,DECLARE 语句确实是可以随时使用的独立语句。 就像在 Java 语言中一样,变量可以在任何位置声明,并且只能在词法上“进一步向下”使用。 暂时忽略 T-SQL 对作用域的 JavaScript 式理解。

-- T-SQL syntax
DECLARE @i INTEGER;

请注意,您可以安全地忽略某些方言(例如 T-SQL)中需要的 @ 符号。 jOOQ 会为您生成它。

赋值

局部变量需要一种方式来为其赋值。 可以在 org.jooq.Variableorg.jooq.Declaration 上直接进行赋值。 例如

-- T-SQL syntax
DECLARE @i INTEGER = 1;
// All dialects
declare(i).set(1)

或者,您可以拆分声明和赋值,或者为变量重新分配新值

-- T-SQL syntax
DECLARE @i INTEGER;
SET @i = 1;
SET @i = 2;
// All dialects
declare(i),
i.set(1),
i.set(2)

某些方言还支持在赋值表达式中使用子查询,以及在其过程语言中使用其他表达式。 例如

-- T-SQL syntax
SET @i = (SELECT MAX(col) FROM t);
// All dialects
i.set(select(max(T.COL)).from(T))

以上等同于此

-- PL/SQL syntax
SELECT MAX(col) INTO i FROM t;
// All dialects
select(max(T.COL)).into(i).from(T)

行赋值

某些方言支持变量的行赋值,其他语言称之为“解构”。 当从查询中分配多个值时,这尤其有用

-- HSQLDB syntax
SET (i, j) = (SELECT MIN(col), MAX(col) FROM t);
// All dialects
row(i, j).set(select(min(T.COL), max(T.COL)).from(T))

以上等同于此

-- PL/SQL syntax
SELECT MIN(col), MAX(col) INTO i, j FROM t;
// All dialects
select(min(T.COL), max(T.COL)).into(i, j).from(T)

引用

显然,一旦我们为局部变量分配了值,我们也希望在任意表达式和查询中引用它。

为此,org.jooq.Variable 扩展了 org.jooq.Field,因此,它可以在任何其他 列表达式可以使用的地方使用。 在过程语言中,一个简单的例子是递增一个局部变量

-- PL/SQL syntax
i := i + 1;
// All dialects
i.set(i.plus(1))

或者在一个更完整的例子中,在 SQL 语句中使用它

-- PL/SQL syntax
DECLARE
  i INT;
BEGIN
  i := 1;
  INSERT INTO t (col) VALUES (i);
END;
// All dialects
Variable<Integer> i = var("i", INTEGER);
create.begin(
  declare(i),
  i.set(1),
  insertInto(T).columns(T.COL).values(i)
).execute();

方言支持

此示例使用 jOOQ

begin(declare(i), i.set(1))

翻译成以下特定方言的表达式

Aurora Postgres、Postgres、YugabyteDB

DO $$
DECLARE
  i int;
BEGIN
  i := 1;
END;
$$

BigQuery

BEGIN
  DECLARE i int64;
  SET i = 1;
END;

CockroachDB

DO $$
DECLARE
  i int4;
BEGIN
  i := 1;
END;
$$

DB2

BEGIN
  DECLARE i integer;
  SET i = 1;
END

Exasol

BEGIN
  i int;
  i := 1;
END;

Firebird

EXECUTE BLOCK AS
  DECLARE i integer;
BEGIN
  :i = 1;
END

H2

CREATE ALIAS block_1752830478990_1732120 AS $$
  void x(Connection c) throws SQLException {
    Integer i = null;
    i = 1;
  }
$$;
CALL block_1752830478990_1732120();
DROP ALIAS block_1752830478990_1732120;

Hana

DO BEGIN
  DECLARE i integer;
  i = 1;
END;

HSQLDB

BEGIN ATOMIC
  DECLARE i int;
  SET i = 1;
END;

Informix

BEGIN
  DEFINE i integer;
  LET i = 1;
END;

MariaDB

BEGIN NOT ATOMIC
  DECLARE i int;
  SET i = 1;
END;

MySQL

CREATE PROCEDURE block_1752830487554_4679654()
MODIFIES SQL DATA
BEGIN
  DECLARE i int;
  SET i = 1;
END;
CALL block_1752830487554_4679654();
DROP PROCEDURE block_1752830487554_4679654;

Oracle

DECLARE
  i number(10);
BEGIN
  i := 1;
END;

Snowflake

BEGIN
  LET i number(10);
  i := 1;
END;

SQLDataWarehouse, SQLServer

BEGIN
  DECLARE @i int;
  SET @i = 1;
END;

Trino

BEGIN
  DECLARE i int;
  SET i = 1;
END

ASE, Access, Aurora MySQL, ClickHouse, Databricks, Derby, DuckDB, MemSQL, Redshift, SQLite, Sybase, Teradata, Vertica

/* UNSUPPORTED */
使用 jOOQ 3.21 生成。早期 jOOQ 版本的支持可能有所不同。 在我们的网站上翻译您自己的 SQL

反馈

您对此页面有任何反馈吗? 我们很乐意听到!

The jOOQ Logo