过程或表函数主体中的表变量类型派生自 SQL 查询或显式声明。如果表变量从 SQL 查询派生其类型,则 SQLScript 编译器通过变量的第一个赋值确定其类型,从而提供很大的灵活性。如果未分配缺省值,则使用空内容初始化显式声明的表变量。
DECLARE [{, }...] [CONSTANT] {TABLE ()|} [ ]
::= { DEFAULT | '=' } { | | | }
使用 DECLARE 关键字声明本地表变量。对于引用类型,可以使用先前声明的表类型或类型定义 TABLE (
DECLARE temp TABLE (n int);
DECLARE temp MY_TABLE_TYPE;
还可以使用 DEFAULT 关键字或“=”直接为表变量分配默认值。缺省情况下,允许所有 语句,典型的表变量赋值也支持这些语句。
DECLARE temp MY_TABLE_TYPE = UNNEST (:arr) as (i);
DECLARE temp MY_TABLE_TYPE DEFAULT SELECT * FROM TABLE;
也可以使用 CONSTANT 关键字将表变量标记为只读。结果是无法再覆盖变量。请注意,如果使用 CONSTANT 关键字,则表变量应具有缺省值,不能为 NULL。
DECLARE temp CONSTANT TABLE(I INT) DEFAULT SELECT * FROM TABLE;声明表变量的另一种方法是使用 LIKE 关键字。您可以使用持久表、视图或另一个表变量的类型来指定变量类型。
DECLARE [CONSTANT] LIKE { | : }. [NOT NULL] [default_value]
DECLARE [CONSTANT] TABLE LIKE { | : } [default_value]
备注使用 LIKE not null 属性除外。当使用 LIKE
使用 DECLARE 关键字声明本地表变量。可使用 temp 引用表变量 :temp。有关详细信息,请参阅引用变量。
CREATE PROCEDURE exampleExplicit (OUT outTab TABLE(n int))
LANGUAGE SQLScript READS SQL DATA AS
BEGIN
DECLARE temp TABLE (n int);
temp = SELECT 1 as n FROM DUMMY ;
BEGIN
DECLARE temp TABLE (n int);
temp = SELECT 2 as n FROM DUMMY ;
outTab = Select * from :temp;
END;
outTab = Select * from :temp;
END;
call exampleExplicit(?);
在每个块中,都有使用相同名称声明的表变量。但是,由于输出参数
N
1
CREATE PROCEDURE exampleDerived (OUT outTab TABLE(n int))
LANGUAGE SQLScript READS SQL DATA
AS
BEGIN
temp = SELECT 1 as n FROM DUMMY ;
BEGIN
temp = SELECT 2 as n FROM DUMMY ;
outTab = Select * from :temp;
END;
outTab = Select * from :temp;
END;
call exampleDerived (?);
在此代码示例中,没有显式表变量声明已完成,这意味着
N
2
对于显式声明的表变量的每个赋值,将根据左侧的显式声明类型检查右侧的派生列名称和类型。
与派生类型相比,另一个区别是在编译期间对表变量的引用将返回警告。
BEGIN
DECLARE a TABLE (i DECIMAL(2,1), j INTEGER);
IF :num = 4
THEN
a = SELECT i, j FROM tab;
END IF;
END;
以上示例返回警告,因为如果 不是 4,则会取消分配表变量 <:num> 。此行为可由配置参数 UNINITIALIZED_TABLE_VARIABLE_USAGE 控制。除了发出警告,它还提供以下选项:
下表显示了差异:
派生类型显式声明创建新变量第一个 SQL 查询分配tmp = select * from table;块中的表变量声明:DECLARE tmp TABLE(i int);可变范围全局范围,不考虑首次声明的块仅在声明的块中可用。应用变量隐藏。未分配的变量检查编译期间无警告编译期间如果可以参考未分配的表变量,则发出警告。仅当使用表变量时才执行检查。
您可以在 SQLScript 中使用的表类型中的列上指定 NOT NULL 约束。历史上,语法不允许出现这种情况,并且在 SQLScript 中用作类型时,表和表类型上的现有 NOT NULL 约束将被忽略。现在,如果在表类型的列列表中直接指定 NOT NULL 约束,则会将其考虑在内。缺省情况下,持久表和表类型中的 NOT NULL 约束仍被忽略,以实现向后兼容性,但您可以通过更改配置使其有效,如下所示:
set '__SQLSCRIPT_NOT_NULL_COLUMN_MODE' = 'ignore' (default), 'ignore_with_warning', 'respect'
如果两者均已设置,则会话变量优先。将其设置为 'ignore_with_warning' 的效果与 'ignore' 相同,不同之处在于忽略约束时还会收到警告。使用 'respect' ,将考虑表和表类型中的 NOT NULL 约束(包括主键),但这可能会使现有过程失效。考虑以下示例: 示例代码create table mytab (i int primary key);create table mytab2 (i int);create procedure myproc (out ot mytab) as begin ot = select * from mytab2; -- error if not_null_column_mode is set to 'respect'end;