TSVTMode 参数

TSVTMode 参数用于配置虚拟表的行为和显示。

使用 TSCreateVirtualTab 过程的 TSVTMode 参数执行以下控制:

TSCreateVirtualTab 过程中使用 TSVTMode 参数执行以下控制:

TSCreateExpressionVirtualTab 过程中使用 TSVTMode 参数执行以下控制:

TSVTMode 参数的缺省值设置虚拟表的行为。TSVTMode 参数的其他每一个值都会将缺省行为的某一个方面改为相反的值。可以将 TSVTMode 参数设置为组合值。例如,如果将 TSVTMode 参数设置为 514 (512 + 2),那么空元素和隐藏的元素都会在虚拟表中显示。可以将 TSVTMode 参数的值指定为表中所示的十进制数,也可以指定为十六进制数。

表 1. TSVTMode 参数的设置
标志 描述
TS_VTI_PUT_ELEM_NO_DUPS 0 缺省值。虚拟表具有以下行为:
  • 不允许相同时间点有多个元素。底层时间系列的更新将更新相同时间点的现有元素。使用 PutElemNoDups 函数。
  • 空元素不会包括在虚拟表中。
  • 基本表的更新需要基本表中 TimeSeries 列之外每一列的准确值。表中 TimeSeries 列之外的所有列都用于标识要更新的行。
  • 如果基本表具有主键,那么将使用主键来查找要更新的行,且基本表的更新无需不属于主键的列的准确值。如果基本表没有主键,那么表中 TimeSeries 列之外的所有列都将用于标识要更新的行,且基本表的更新需要基本表中 TimeSeries 列之外每一列的准确值。NOT NULL 约束包括在虚拟表中,用于基本表中的主键列和具有 NOT NULL 约束的其他列。
  • 对于现有行的更新,仅可以更新 TimeSeries 列。
  • 隐藏的元素不会包括在虚拟表中。
  • 从虚拟表中按时间戳记选择数据时,将返回其时间戳记最接近或早于查询中指定的时间戳记的行。如果时间系列是不规则的,那么返回的行显示的时间戳记与查询中指定的相同,无论实际时间戳记是否相同。
TS_VTI_PUT_ELEM 1 允许相同时间点有多个元素。对底层时间系列的更新将插入元素,即使相应时间点已存在元素。使用 PutElem 函数。
TS_VTI_SHOW_NULLS 2 空元素在虚拟表中显示。隐藏的元素显示为空元素,除非还设置了值 512。
TS_VTI_DISABLE_NOT_NULL_CONSTRAINT 16 对于现有行,可以为不属于主键的列指定 NULL 值,无论那些列在基本表中是否具有 NOT NULL 约束。NOT NULL 约束不会包括在虚拟表中,但在基本表中强制执行。

对于新行,可以为不属于主键且没有 NOT NULL 约束的列指定空值。

TS_VTI_UPDATE_NONKEY_NOT_NULLS 32 此设置仅在基本表具有主键时有效。

可以在现有行中更新不属于主键的列的值。可以为不想更新的非主键列指定 NULL。除了主键列之外,在 INSERT 语句中具有非 NULL 值的所有列都将在基本表中更新。

TS_VTI_UPDATE_NONKEY_INCLUDE_NULLS 64 此设置仅在基本表具有主键时有效。

可以在现有行中更新不属于主键的所有列的值,包括对允许空值的列设置空值。不属于主键的列将更新为 INSERT 语句中包括的值。允许空值的列可以设置为 NULL。

TS_VTI_ELEM_INSERT 128 如果存在以下约束,可以将元素快速插入到容器中:
  • 基本表具有主键
  • 时间系列实例存在且存储在容器中
  • 基本表列未进行更新

不能与设置 16、32 或 64 组合使用。不能与 NewTimeSeries 参数组合使用。

TS_VTI_REDUCED_LOG 256 减少将元素插入到容器中时生成的日志记录数。缺省情况下,插入的每个元素都将生成两个日志记录:一个用于插入的元素,一个用于页面标题更新。如果设置了此标志,那么会针对每个事务而不是每个元素来记录页面标题更新。

INSERT 语句必须在没有其他类型的 SQL 语句的事务内运行。只有在该事务落实之后,脏读取才可看到插入的元素。

TS_VTI_SCAN_HIDDEN 512 隐藏的元素在虚拟表中显示。
TS_VTI_SCAN_DISCREET 1024 从虚拟表中按时间戳记选择数据时,将仅返回其时间戳记与查询中指定的时间戳记完全相同的行。

更新基本表中的列

使用 TSCreateVirtualTab 过程创建虚拟表时,可以从虚拟表更新基本表中的数据。

下表描述假设基本表具有主键,应该如何控制对基本表中的列的更新。是否指定 NewTimeSeries 参数还会影响将数据插入基本表的行为。有关 NewTimeSeries 参数的影响的信息,请参阅 TSCreateVirtualTab 过程

表 2. 影响基本表中更新哪些列的 TSVTMode 参数设置
要更新的列 TSVTMode 参数设置
仅更新 TimeSeries 列。必须为非主键列指定有效值,但无需准确的值。 0
仅更新 TimeSeries 列。可以指定 NULL 作为非主键列的值 16
更新 TimeSeries 列和所有其他在 INSERT 语句中没有空值的非主键列。 32
更新 TimeSeries 列和所有其他非主键列。可以将没有 NOT NULL 约束的列设置为空值。 64、64 + 16
更新 TimeSeries 列和所有其他没有 NOT NULL 约束的非主键列。可以为具有 NOT NULL 约束的列指定空值。 32 + 16

以下示例对 TSVTMode 参数的一些设置进行了说明。示例使用的基本表包含以下列:帐号、计量表标识、时间系列数据、计量表所有者和计量表地址。帐号列和计量表标识列是主键。TimeSeries 列包含时间戳记列、能量列和温度列。所有者列具有 NOT NULL 约束。示例中创建的每个虚拟表最初都包含以下一行,用于表示一个时间系列元素:

acct_no      6546
meter_id     234
t            2011-01-01 00:00:00.00000
energy       33070
temperature  -13.0000000000
owner        John
address      5 Nowhere Place

1 row(s) retrieved.

示例 1:将 TSVTMode 参数设置为 0

以下语句创建名为 smartmeters_vti_nn 的虚拟表,并且将 TSVTMode 参数设置为 0

EXECUTE PROCEDURE TSCreateVirtualTab('smartmeters_vti_nn', 
        'smartmeters', 'origin(2011-01-01 00:00:00.00000), 
        calendar(ts_15min), regular,threshold(20), container()', 0);

以下语句将新行插入虚拟表,使其成为基本表中的时间系列的新元素:

INSERT INTO smartmeters_vti_nn(acct_no,meter_id,t,energy,temperature,owner,address)
 VALUES(6546, 234,
        '2011-01-01 00:45:00.00000'::datetime year to fraction(5),
        3234, -12.00,
        'Ignored_value', 'Ignored_value');
1 row(s) inserted.

主键列的值与原始行匹配。owneraddress 列的值将被忽略,不会使用这些值来标识必须更新的行,并且这些值在基本表中不会更新。执行 INSERT 语句后,虚拟表包含两行,每行都包含 owneraddress 列的原始值:

SELECT * FROM smartmeters_vti_nn;


acct_no      6546
meter_id     234
t            2011-01-01 00:00:00.00000
energy       33070
temperature  -13.0000000000
owner        John
address      5 Nowhere Place

acct_no      6546
meter_id     234
t            2011-01-01 00:45:00.00000
energy       3234
temperature  -12.0000000000
owner        John
address      5 Nowhere Place

2 row(s) retrieved.

示例 2:将 TSVTMode 参数设置为 32

以下语句创建名为 smartmeters_vti_nn_nk_nn 的虚拟表,并且将 TSVTMode 参数设置为 32

EXECUTE PROCEDURE TSCreateVirtualTab('smartmeters_vti_nn_nk_nn', 
           'smartmeters', 'origin(2011-01-01 00:00:00.00000), 
           calendar(ts_15min), regular,threshold(20), container()', 32);

以下语句将新行插入虚拟表,使其成为基本表中的时间系列的新元素:

INSERT INTO smartmeters_vti_nn_nk_nn(acct_no,meter_id,t,energy,
                                     temperature,owner,address)
 VALUES(6546, 234,
        '2011-01-01 00:45:00.00000'::datetime year to fraction(5),
        3234, -12.00,
        'Jim', NULL);
1 row(s) inserted.

owner 列的值将更新为 Jimaddress 列的值不变,因为空值会被忽略。现在虚拟表包含两行,每行的 owner 列都具有新值,并且 address 列都具有现有值:

SELECT * FROM smartmeters_vti_nn_nk_nn;


acct_no      6546
meter_id     234
t            2011-01-01 00:00:00.00000
energy       33070
temperature  -13.0000000000
owner        Jim
address      5 Nowhere Place

acct_no      6546
meter_id     234
t            2011-01-01 00:45:00.00000
energy       3234
temperature  -12.0000000000
owner        Jim
address      5 Nowhere Place

2 row(s) retrieved.

示例 3:将 TSVTMode 参数设置为 64

以下语句创建名为 smartmeters_vti_nn_nk_in 的虚拟表,并且将 TSVTMode 参数设置为 64:

EXECUTE PROCEDURE TSCreateVirtualTab('smartmeters_vti_nn_nk_in', 
         'smartmeters', 'origin(2011-01-01 00:00:00.00000), 
         calendar(ts_15min), regular,threshold(20), container()', 64);

以下语句将新行插入虚拟表,使其成为基本表中的时间系列的新元素:

INSERT INTO smartmeters_vti_nn_nk_in(acct_no,meter_id,t,energy,
                                     temperature,owner,address)
 VALUES(6546, 234,
        '2011-01-01 00:45:00.00000'::datetime year to fraction(5),
        3234, -12.00,
        'Jim', NULL);
1 row(s) inserted.

owner 列的值将更新为 Jimaddress 列的值更新为空值。现在虚拟表包含两行,每行的 owner 列都具有新值,并且 address 列都具有空值:

SELECT * FROM smartmeters_vti_nn_nk_in;


acct_no      6546
meter_id     234
t            2011-01-01 00:00:00.00000
energy       33070
temperature  -13.0000000000
owner        Jim
address
acct_no      6546
meter_id     234
t            2011-01-01 00:45:00.00000
energy       3234
temperature  -12.0000000000
owner        Jim
address
2 row(s) retrieved.

重复时间点

缺省情况下,数据库服务器使用 PutElemNoDups 函数将元素添加到底层时间系列。如果在相同时间点已存在某个元素,将更新现有元素。可以对底层时间系列执行批量更新,这样相同时间点就不会产生重复的元素。

TSVTMode 参数包括值 1 时,数据库服务器使用 PutElem 函数将元素添加到底层时间系列。PutElem 函数对底层不规则时间系列中的现有数据更新的处理方式与 PutElemNoDups 函数不同。

空元素和隐藏的元素

TSVTMode 参数包括在虚拟表中显示空的或隐藏的时间系列元素的选项。缺省情况下,如果基本表在特定时间点有空元素,那么虚拟表没有该时间点的条目。可以使用 TSVTMode 参数将空元素显示为一行空值,再加上基本表的 timestamp 列和任何非时间系列列。

如果 TSVTMode 参数包括值 2,那么空时间系列元素在虚拟表中显示为空值。隐藏的元素也显示为空值。如果 TSVTMode 参数不包括值 2,那么空时间系列元素不在虚拟表中显示。

如果 TSVTMode 参数包括值 512,那么隐藏的时间系列元素在虚拟表中显示;否则将不显示。

以下语句创建四个虚拟表,都基于名为 inst 的同一个基本表,该基本表包含名为 barsTimeSeries 列。每个表使用的 TSVTMode 参数值都不同。inst_vt0 表不显示空元素或隐藏的元素。inst_vt2 表显示空元素。inst_vt512 表显示隐藏的元素。inst_vt514 表显示空元素和隐藏的元素。

execute procedure TSCreateVirtualTab( 'inst_vt0', 'inst', 0);
execute procedure TSCreateVirtualTab( 'inst_vt2', 'inst', 2);
execute procedure TSCreateVirtualTab( 'inst_vt512', 'inst', 512);
execute procedure TSCreateVirtualTab( 'inst_vt514', 'inst', 514);

以下语句通过使用 HideElem 函数隐藏一个元素:

update inst set bars = HideElem( bars, 
    datetime(2011-01-18) year to day) where code = 'AA';
1 row(s) updated.

以下查询显示 inst_vt0 表不包含 2011-01-18 的隐藏元素:

select * from inst_vt0
where code = 'AA'
and t between datetime(2011-01-14) year to day
and datetime(2011-01-19) year to day
order by t;

code AA
t     2011-01-14 00:00:00.00000
high  69.25000000000
low   68.37500000000
final 68.62500000000
vol   462.0000000000

code AA
t     2011-01-19 00:00:00.00000
high  69.62500000000
low   69.12500000000
final 69.62500000000
vol   96.69999700000
2 row(s) retrieved.

以下查询显示 inst_vt2 表包含空元素:

select * from inst_vt2
where code = 'AA'
and t between datetime(2011-01-14) year to day
and datetime(2011-01-19) year to day
order by t;

code AA
t     2011-01-14 00:00:00.00000
high  69.25000000000
low   68.37500000000
final 68.62500000000
vol   462.0000000000

code AA
t     2011-01-17 00:00:00.00000
high 
low
final
vol

code AA
t     2011-01-18 00:00:00.00000
high
low
final
vol

code AA
t     2011-01-19 00:00:00.00000
high  69.62500000000
low   69.12500000000
final 69.62500000000
vol   96.69999700000
4 row(s) retrieved.

以下查询显示 inst_vt512 表明确包含隐藏的元素:

select * from inst_vt512
where code = 'AA'
and t between datetime(2011-01-14) year to day
and datetime(2011-01-19) year to day
order by t;

code AA
t     2011-01-14 00:00:00.00000
high  69.25000000000
low   68.37500000000
final 68.62500000000
vol   462.0000000000

code AA
t     2011-01-18 00:00:00.00000
high  69.75000000000
low   68.75000000000
final 69.62500000000
vol   281.2000100000

code AA
t     2011-01-19 00:00:00.00000
high  69.62500000000
low   69.12500000000
final 69.62500000000
vol   96.69999700000
3 row(s) retrieved.

以下查询显示 inst_vt514 表明确包含隐藏的元素和空元素:

select * from inst_vt514
where code = 'AA'
and t between datetime(2011-01-14) year to day
and datetime(2011-01-19) year to day
order by t;

code AA
t     2011-01-14 00:00:00.00000
high  69.25000000000
low   68.37500000000
final 68.62500000000
vol   462.0000000000

code AA
t     2011-01-17 00:00:00.00000
high 
low 
final 
vol 

code AA
t     2011-01-18 00:00:00.00000
high  69.75000000000
low   68.75000000000
final 69.62500000000
vol   281.2000100000

code AA
t     2011-01-19 00:00:00.00000
high  69.62500000000
low   69.12500000000
final 69.62500000000
vol   96.6999970000
4 row(s) retrieved.