将标识列添加到雪花中的现有表?

Posted

技术标签:

【中文标题】将标识列添加到雪花中的现有表?【英文标题】:Add identity column to existing table in Snowflake? 【发布时间】:2021-01-01 15:56:16 【问题描述】:

我在 Snowflake 中有一个表“MY_TABLE”,我想在其中添加一个标识列。我试过了

ALTER TABLE "MY_TABLE" 
    ADD COLUMN primary_key int IDENTITY(1,1);

但这会返回

SQL compilation error: Cannot add column 'PRIMARY_KEY' with non-constant default to non-empty table 'MY_TABLE'.

这在雪花中是不可能的吗?

为了解决这个限制,我尝试创建表的临时版本

CREATE OR REPLACE TABLE "MY_TABLE_TEMP" LIKE "MY_TABLE"
ALTER TABLE "MY_TABLE_TEMP" ADD COLUMN primary_key int IDENTITY(1,1)

INSERT INTO "MY_TABLE_TEMP"
    SELECT * FROM "MY_TABLE";

但现在我得到了错误

SQL compilation error: Insert value list does not match column list expecting <x+1> but got <x>

这是有道理的,因为我没有传递主键。在这一点上,似乎我可能不得不手动将 x (这是一个非常高的数字)的列名列表输入到 sql 查询中,所以我想知道我是否只是做错了。有没有其他人遇到过类似的问题?

【问题讨论】:

Snowflake 似乎不喜欢将新的自动增量列添加到现有表中。鉴于您的表似乎是空的,您可以修改您的 create 语句。 【参考方案1】:

你可以试试这个

CREATE TABLE TEST_TABLE_TEMP LIKE TEST_TABLE;
ALTER TABLE TEST_TABLE_TEMP ADD COLUMN primary_key int IDENTITY(1,1);

create or replace sequence seq_01 start = 1 increment = 1;

INSERT INTO TEST_TABLE_TEMP 
SELECT *,seq_01.NEXTVAL FROM TEST_TABLE;

SELECT * FROM TEST_TABLE_TEMP;

【讨论】:

不是 OP,但我有同样的问题,并且 ALTER TABLE 语句因 OP 的原始消息而失败。 实际上,雪花永远不应该启用 ALTER TABLE 解决方案来填充非空表的 IDENTITY 列是有原因的。答案在 SNOWFLAKE 的架构中。想想需要触及多少微分区以及这对计算成本意味着什么? 经过进一步探索,我认为有一个问题。这似乎对标识列使用不同的序列并为该列的初始值设定种子。插入到表中的下一行将再次从 1 开始。我可以通过执行 IDENTITY(r,1) 来解决这个问题,其中 r 是表中的行数。【参考方案2】:

您可以使用自己的SEQUENCE 代替IDENTITY,为每一行创建一个唯一的ID。

用序列修复问题中的示例:

CREATE OR REPLACE SEQUENCE seq1;
CREATE OR REPLACE TABLE "MY_TABLE_TEMP" LIKE "MY_TABLE";

ALTER TABLE "MY_TABLE_TEMP" 
ADD COLUMN primary_key int DEFAULT seq1.nextval;


INSERT INTO "MY_TABLE_TEMP"
SELECT *, seq1.nextval 
FROM "MY_TABLE";

(发布此答案后,我注意到它与 Rajib 的非常相似)

【讨论】:

不是 OP,但我的情况有些相同(使用序列而不是身份编辑:还有身份),我在尝试执行 ALTER TABLE 时遇到了同样的错误你在那里写的。【参考方案3】:

您不需要创建序列。您可以在插入中指定列:

CREATE TABLE TEST_TABLE_TEMP LIKE TEST_TABLE;
ALTER TABLE TEST_TABLE_TEMP ADD COLUMN primary_key int IDENTITY(1,1);

INSERT INTO TEST_TABLE_TEMP (col1,col2,...) 
SELECT col1,col2,... FROM TEST_TABLE;

如果您想在最后一个位置添加主列,则需要为您的表创建 DDL。比编辑它:添加您的主列并更改表名。插入将起作用。

【讨论】:

【参考方案4】:

只是一种预感,但是您是否尝试过在插入语句中包含 target_col_name。我假设如果您不指定它们,它会期待您刚刚在 select 语句中添加的附加列。

【讨论】:

以上是关于将标识列添加到雪花中的现有表?的主要内容,如果未能解决你的问题,请参考以下文章

向现有列添加标识

如何将列添加到现有表?

如何在 SQL Server 中添加标识列?

雪花外部表:添加新列

Oracle中如何将自动增量添加到现有表中

从数据库优先实体框架 6.2 中的 SaveChanges 中删除标识列