如何在 DB2/400 中创建生成的列

Posted

技术标签:

【中文标题】如何在 DB2/400 中创建生成的列【英文标题】:How to create generated columns in DB2/400 【发布时间】:2020-12-07 14:12:36 【问题描述】:

我想创建一个虚拟列,将两列连接到 1。我的尝试是:

--result sqlstate 42601 -104 (Token not valid: (. Valid token: IDENTITY)
alter table schema.table
  add column name1_v generated always as (trim(name1) || ' ' || trim(vt_alt))
  add column vtKuTx_v generated always as (trim(vtKuTx) || ' ' || trim(vt_alt))
;

这应该根据文档工作。 (https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/db2/rbafzpdf.pdf?view=kc)(第 851 页)。 有人知道如何完成这项工作吗?

提前致谢。

编辑: 我仔细检查了它。这也不起作用。

create or replace table table.schema (
  number int default 2,
  square int generated always as (number * number)
);

【问题讨论】:

错误信息是什么? 令牌无效:(。有效令牌:IDENTITY i系列的版本是多少? 使用 Db2-for-i 时,记录了以下限制“仅当列具有 ROWID 数据类型(或基于 ROWID 数据类型的不同类型)时,才能指定 GENERATED, column 是标识列,指定标识选项,指定 as-row-transaction-timestamp-clause,指定 as-row-transaction-start-id-clause,或者该列是行更改时间戳。"跨度> 我在 7.2 和 7.4 上进行了测试。错误消息的值略有不同。 7.4 等待一个特殊的寄存器 7.2 一个身份。 【参考方案1】:

在寻求帮助时,请始终提供您的 Db2 版本(或者在本例中为 i 系列的版本)。

当您使用 Db2 for i 时,您应该研究该 i 系列平台的 ALTER TABLE 的文档,然后在该页面上选择正确版本的 i 系列软件。

对于ALTER TABLE 的 GENERATED 子句,i 系列文档在注释 5 中指定了以下限制:

只有当列具有 ROWID 数据类型时,才能指定 GENERATED (或基于 ROWID 数据类型的不同类型),该列是 标识列,指定标识选项, as-row-transaction-timestamp-clause 被指定, 指定了 as-row-transaction-start-id-clause,或者该列是 行更改时间戳。

这可能是您的 -104 异常的原因。所以你需要找到一种替代方法来实现你的目标。

【讨论】:

【参考方案2】:

试试:

ALTER TABLE schema.table
  ADD COLUMN name1_v  DEFAULT trim(name1) || ' ' || trim(vt_alt)
  ADD COLUMN vtKuTx_v DEFAULT trim(vtKuTx) || ' ' || trim(vt_alt)
;

在这里,我找到了一个教程... https://www.db2tutorial.com/db2-basics/db2-alter-table-add-column/

【讨论】:

不错的尝试,但更新 name1 时它不会更新列。 我想它就像我使用过的所有 DBMS 一样工作。 向表中添加列是 DDL 操作。修改表的给定行中给定列的内容是 DML 操作。还有其他数据库具有 REFRESH 功能,该功能将在触发时将源列中的更改反映到目标列。或者,您可以引入在更新源列时触发的触发器。但是,如果您只想使用表定义来执行此操作,那么您所能做的就是 ALTER TABLE ... DROP COLUMN ... 和 ALTER TABLE ... ADD COLUMN ... 再次 触发器将是一个不错的解决方案。这些列将包含我们的 BI 系统的累积数据。所以我决定为导入器创建一个视图,以使嵌入的语句尽可能简单。【参考方案3】:

注意:此答案适用于 DB2 LUW,而不是 DB2-400。也许同样的道理也适用。

DB2 防止您无意中添加列,因为这可能是一项非常繁重的操作。相反,DB2 会强制您:

禁用约束。 添加列。 再次启用约束。

正如 DB2 SQL 编译器开发人员所说(原文如此):

添加/更改生成的列是唯一的表操作 物理更新表。更准确地说,它可能 更新它的所有无数行(在 Viper 中可能很多 分区)。

所以与其完全填满人们的日志空间(或强调 自动存档选项)我们认为执行此类操作是合适的 表检查挂起时执行繁重的操作。

因此,您可以这样做:

set integrity for schema.table off;

alter table schema.table
  add column name1_v generated as (trim(name1) || ' ' || trim(vt_alt))
  add column vtKuTx_v generated as (trim(vtKuTx) || ' ' || trim(vt_alt))
;

set integrity for schema.table immediate checked force generated;

请参阅db<>fiddle 的运行示例。

【讨论】:

它不起作用。但是感谢我不知道该网站的 db fiddle 链接。

以上是关于如何在 DB2/400 中创建生成的列的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 PostgreSQL 中创建生成的列时出现错误?

如何在 Bootstrap 中创建可滚动的列?

如何在 oracle 中创建具有对象数据类型的列

如何在 Sequelize 中类型为 TIME 的列中创建位置?

如何在报告中创建一个包含所有已检查列名称的列?

如何使用 typeORM 在 Nestjs 中创建类型为 Date 的列并键入 DateTime?