GET DIAGNOSTICS 语句

适用于:已选中“是” Databricks SQL 已选中“是” Databricks Runtime 16.3 及更高版本

检索有关在异常处理程序、活动事务状态或受最近 DML 语句影响的行数中处理的条件的信息。

窗体 CONDITION 只能在 复合语句中的条件处理程序中使用。 该 TRANSACTION_ACTIVE 窗体可以用作独立的 SQL 语句或在 复合语句中。 窗体 ROW_COUNT 只能在 复合语句中使用,包括 SQL 存储过程的正文。

语法

GET DIAGNOSTICS CONDITION 1
  { variable_name = condition_info_item } [, ...]

GET DIAGNOSTICS
  { variable_name = statement_info_item } [, ...]

condition_info_item
  { MESSAGE_TEXT |
    RETURNED_SQLSTATE |
    MESSAGE_ARGUMENTS |
    CONDITION_IDENTIFIER |
    LINE_NUMBER }

statement_info_item
  { TRANSACTION_ACTIVE |
    ROW_COUNT }

参数

  • variable_name

    局部变量或会话变量。

  • CONDITION

    返回触发条件处理程序的条件。 您必须作为处理程序中的第一个语句发出 GET DIAGNOSTICS CONDITION 1

    • MESSAGE_TEXT

      返回与条件关联的消息文本作为 STRINGvariable_name 必须是 STRING

    • RETURNED_SQLSTATE

      返回与作为 SQLSTATE 处理的条件相关联的 STRINGvariable_name 必须是 STRING

    • MESSAGE_ARGUMENTS

      返回作为自变量提供给 Databricks 条件参数的 MAP<STRING, STRING> 映射。 对于声明的条件,唯一的映射键是 MESSAGE_TEXTvariable_name 必须是 MAP<STRING, STRING>

    • CONDITION_IDENTIFIER

      返回导致异常的条件名称。 variable_name 必须是 STRING

    • LINE_NUMBER

      返回引发条件的语句的行号。 NULL(如果不可用)。

  • TRANSACTION_ACTIVE

    适用于:检查标记为“是”的 Databricks SQL 检查标记为“是”是 Databricks Runtime 18.2 及更高版本

    1 语句在原子复合语句中运行时返回;BEGIN ATOMIC ... END否则返回 0variable_name 必须是一个 INT

    原子复合语句提供与 交互式事务相同的多语句事务语义;请参阅 BEGIN ATOMIC 周围的范围。

  • ROW_COUNT

    适用于:检查标记为“是”的 Databricks SQL 检查标记为“是”是 Databricks Runtime 18.3 及更高版本

    返回受最近执行的 DML 语句影响的行数,作为一个 BIGINTvariable_name 必须是 BIGINT

    返回 NULL 时间:

    • 尚未在封闭复合体中执行任何语句。
    • 最近的语句不是 DML 语句(例如,SELECTDDLSET VAR)。
    • 最新的 DML 语句不报告受影响的行计数。 内置 Delta Lake 写入(INSERTUPDATEDELETEMERGE INTOCOPY INTO)填充ROW_COUNT。 写入到非增量表并通过 Apache Spark 数据源 V2 目录进行写入返回 NULL
    • 输入处理程序。 每个语句在运行前重置 ROW_COUNT ,因此异常处理程序始终会观察到 NULL
    • 语句 CALL 返回。 从调用方中的过程重置 ROW_COUNT 返回,因此调用方无法观察在被调用方内执行的 DML。

    每个语句最多可以分配ROW_COUNT一个变量GET DIAGNOSTICS。 通过向同一语句添加更多赋值来组合使用 TRANSACTION_ACTIVE

    若要捕获受影响的行计数,请紧接 GET DIAGNOSTICS ... = ROW_COUNT 在 DML 语句之后。 嵌套 BEGIN ... END 块不会隐藏外部块的 DML(该值在嵌套复合体中保持可见),但任何干预的非 DML 语句或 CALL 清除槽。

例子

-- Capture details of a handled condition in an exception handler.
> CREATE OR REPLACE TABLE emp(name STRING, salary DECIMAL(10, 2));

> BEGIN
    DECLARE EXIT HANDLER FOR DIVIDE_BY_ZERO
      BEGIN
        DECLARE cond STRING;
        DECLARE message STRING;
        DECLARE state STRING;
        DECLARE args MAP<STRING, STRING>;
        DECLARE line BIGINT;
        DECLARE argstr STRING;
        DECLARE log STRING;
        GET DIAGNOSTICS CONDITION 1
           cond    = CONDITION_IDENTIFIER,
           message = MESSAGE_TEXT,
           state   = RETURNED_SQLSTATE,
           args    = MESSAGE_ARGUMENTS,
           line    = LINE_NUMBER;
        SET argstr = array_join(transform(map_entries(args), t -> concat_ws(' ', 'Param:', t.key, 'Val:', t.value)), ' ');
        SET log = 'Condition: ' || cond ||
                  ' Message: ' || message ||
                  ' SQLSTATE: ' || state ||
                  ' Args: ' || argstr ||
                  ' Line: ' || line;
        VALUES (log);
      END;
    SELECT 10/0;
  END;
 Condition: DIVIDE_BY_ZERO Message: Division by zero. Use try_divide to tolerate divisor being 0 and return NULL instead. If necessary, set <config> to “false” to bypass this error. SQLATTE: 22012 Args:  Parm: config Val: ANSI_MODE Line: 28
-- Check whether the current statement runs inside an atomic transaction.
> DECLARE VARIABLE tx INT;

> GET DIAGNOSTICS tx = TRANSACTION_ACTIVE;
> SELECT tx;
 0

> BEGIN ATOMIC
    DECLARE tx INT;
    GET DIAGNOSTICS tx = TRANSACTION_ACTIVE;
    SELECT tx;
  END;
 1
-- Capture the number of rows affected by the most recent DML statement.
> CREATE OR REPLACE TABLE emp(name STRING, salary DECIMAL(10, 2));

> BEGIN
    DECLARE rc BIGINT;
    INSERT INTO emp VALUES ('Alice', 100.00), ('Bob', 200.00), ('Carol', 300.00);
    GET DIAGNOSTICS rc = ROW_COUNT;
    VALUES ('Inserted ' || rc || ' rows.');
    DELETE FROM emp WHERE salary >= 200.00;
    GET DIAGNOSTICS rc = ROW_COUNT;
    VALUES ('Deleted ' || rc || ' rows.');
  END;
 Inserted 3 rows.
 Deleted 2 rows.