适用于:
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 }
参数
-
局部变量或会话变量。
CONDITION返回触发条件处理程序的条件。 您必须作为处理程序中的第一个语句发出
GET DIAGNOSTICS CONDITION 1。MESSAGE_TEXT返回与条件关联的消息文本作为
STRING。variable_name必须是STRING。RETURNED_SQLSTATE返回与作为
SQLSTATE处理的条件相关联的STRING。variable_name必须是STRING。MESSAGE_ARGUMENTS返回作为自变量提供给 Databricks 条件参数的
MAP<STRING, STRING>映射。 对于声明的条件,唯一的映射键是MESSAGE_TEXT。variable_name必须是MAP<STRING, STRING>CONDITION_IDENTIFIER返回导致异常的条件名称。
variable_name必须是STRING。LINE_NUMBER返回引发条件的语句的行号。
NULL(如果不可用)。
TRANSACTION_ACTIVE适用于:
Databricks SQL
Databricks Runtime 18.2 及更高版本当
1语句在原子复合语句中运行时返回;BEGIN ATOMIC ... END否则返回0。variable_name必须是一个INT。原子复合语句提供与 交互式事务相同的多语句事务语义;请参阅
BEGIN ATOMIC周围的范围。ROW_COUNT适用于:
Databricks SQL
Databricks Runtime 18.3 及更高版本返回受最近执行的 DML 语句影响的行数,作为一个
BIGINT。variable_name必须是BIGINT。返回
NULL时间:- 尚未在封闭复合体中执行任何语句。
- 最近的语句不是 DML 语句(例如,
SELECTDDL 或SET VAR)。 - 最新的 DML 语句不报告受影响的行计数。 内置 Delta Lake 写入(
INSERT、UPDATE、DELETE和MERGE 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.