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

块语句

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

过程语言中最基本的构建块是块语句,它允许创建作用域(T-SQL 除外,它没有块作用域),以及将相关的语句在逻辑上分组在一起。就像在 Java 中,任何语句集都可以使用花括号分组:{ statment1; statement2; },在过程语言中,通常使用关键字 BEGINEND 来分隔一个块。例如

BEGIN
  INSERT INTO t (col) VALUES (1);
  INSERT INTO t (col) VALUES (2);
END;
create.begin(
  insertInto(T).columns(T.COL).values(1),
  insertInto(T).columns(T.COL).values(2)
).execute();

请注意 jOOQ 的 DSLContext.begin(Statement...) 接受一个普通的 varargs 数组(或集合)的 org.jooq.Statement 作为参数。因此,这些语句是用逗号分隔的,而不是用分号分隔的。另外,重要的是传递给过程 API 的语句不要调用 Query.execute() 方法,因为那样会在客户端执行语句,而不是将语句表达式嵌入到块中。

就像在 SQL 中一样,这样的块可以嵌套任意深度,例如

BEGIN
  BEGIN
    INSERT INTO t (col) VALUES (1);
    INSERT INTO t (col) VALUES (2);
  END;
  BEGIN
    INSERT INTO t (col) VALUES (3);
    INSERT INTO t (col) VALUES (4);
  END;
END;
create.begin(
  begin(
    insertInto(T).columns(T.COL).values(1),
    insertInto(T).columns(T.COL).values(2)
  ),
  begin(
    insertInto(T).columns(T.COL).values(3),
    insertInto(T).columns(T.COL).values(4)
  )
).execute();

客户端“块”

在某些情况下,可能希望仅在客户端将几个语句分组到一个“块”中,而不在服务器上生成 BEGINEND 关键字,如果不需要的话。可以使用 DSLContext.statements(Statement...) 来完成此操作。

INSERT INTO t (col) VALUES (1);
INSERT INTO t (col) VALUES (2);
 
statements(
  insertInto(T).columns(T.COL).values(1),
  insertInto(T).columns(T.COL).values(2))

当您想要将多个语句分组到一个逻辑 org.jooq.Statement 中,并让 jOOQ 确定是否需要 BEGIN .. END 块语法时,此 API 非常有用。 如果需要,则会添加它们 - 例如,当该块在顶层执行时,或嵌套在 IF 语句 中时,以防 IF 语句尚未拥有自己的 THEN 关键字来分隔多语句内容。

块执行

org.jooq.Block 扩展了 org.jooq.Query,而 org.jooq.Query 又扩展了 org.jooq.StatementQuery 是一个可以在其自身上执行的语句,作为一个独立的执行单元。

所有其他 org.jooq.Statement 类型(如下几节所述)不能在其自身上执行。 例如,在语句块之外执行 GOTO 语句 是没有意义的。

方言支持

此示例使用 jOOQ

begin(deleteFrom(BOOK), deleteFrom(AUTHOR))

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

Aurora Postgres、CockroachDB、Postgres、YugabyteDB

DO $$
BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;
$$

BigQuery

BEGIN
  DELETE FROM BOOK
  WHERE TRUE;
  DELETE FROM AUTHOR
  WHERE TRUE;
END;

DB2, Trino

BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END

Exasol, Informix, Oracle, SQLDataWarehouse, SQLServer, Snowflake, Teradata, Vertica

BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;

Firebird

EXECUTE BLOCK AS
BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END

H2

CREATE ALIAS block_1752830478984_474910 AS $$
  void x(Connection c) throws SQLException {
    try (PreparedStatement s = c.prepareStatement(
      "DELETE FROM BOOK"
    )) {
      s.execute();
    }
    try (PreparedStatement s = c.prepareStatement(
      "DELETE FROM AUTHOR"
    )) {
      s.execute();
    }
  }
$$;
CALL block_1752830478984_474910();
DROP ALIAS block_1752830478984_474910;

Hana

DO BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;

HSQLDB

BEGIN ATOMIC
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;

MariaDB

BEGIN NOT ATOMIC
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;

MySQL

CREATE PROCEDURE block_1752830487549_6282864()
MODIFIES SQL DATA
BEGIN
  DELETE FROM BOOK;
  DELETE FROM AUTHOR;
END;
CALL block_1752830487549_6282864();
DROP PROCEDURE block_1752830487549_6282864;

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

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

反馈

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

The jOOQ Logo