我正在尝试将现有列转换为标识.
到目前为止,我可以通过以下方式轻松完成:
alter table list alter column id set generated always as identity (start with 0);
不幸的是,我需要它从表中已有的最大数据开始.
我尝试了以下但它抱怨子查询.
alter table list alter column id set generated always as identity (start with (select max(id) from list);
单独运行时子查询返回正常.
我在博客上找到了一个有趣的解决方案:如何将IDENTITY列添加到现有表中,
添加非空整数列您需要为它提供默认值,否则db2将拒绝它为非null
alter table public.clicks add column id integer not null default 0
从列中删除默认值我不完全确定为什么需要它,因为因特网上的一些手册省略了这一步但在没有这个的情况下我无法在DB2 9.7.3 LUW上使用它
alter table public.clicks alter column id drop default
现在将列设置为始终生成
alter table public.clicks alter column id set generated always as identity
Reorg表使其可写
reorg table public.clicks
现在用生成的itentity值替换零
update public.clicks set id = default
并可选择为表创建id列主键
alter table public.clicks add constraint pkey primary key(id)
使用存储过程的另一种解决方案
将数据迁移到DB2时重新启动IDENTITY列
如果使用IDENTITY列创建表,并且您需要确保您的标识列从加载数据的最后一个最大值开始.IBM Data Movement Tool会自动执行此操作,但如果您不使用该工具并希望将标识列的起始值与数据库中的数据同步,则可以使用此存储过程来同步数据.链接
--#SET TERMINATOR @
CREATE PROCEDURE RESETIDENTITYSTARTVALUE
(
IN schemaname VARCHAR(128),
IN tablename VARCHAR(128)
)
BEGIN
DECLARE sqlcode INTEGER;
DECLARE maxid BIGINT;
DECLARE idcolname VARCHAR(128);
DECLARE stmttxt VARCHAR(1000);
DECLARE s STATEMENT;
DECLARE cur CURSOR FOR s;
SELECT colname INTO idcolname
FROM SYSCAT.COLUMNS
WHERE tabname = tablename
AND tabschema = schemaname
AND identity = 'Y';
IF SQLCODE = 100 THEN
SIGNAL SQLSTATE '78000'
SET MESSAGE_TEXT = 'can''t find identity column';
END IF;
SET stmttxt = 'SELECT MAX("' || idcolname || '") FROM "' ||
schemaname || '"."' || tablename || '"';
PREPARE s FROM stmttxt;
SET maxid = 0;
OPEN cur;
FETCH cur INTO maxid;
CLOSE cur;
SET stmttxt = 'ALTER TABLE "' || schemaname || '"."' || tablename ||
'" ALTER COLUMN "' || idcolname ||
'" RESTART WITH ' || CHAR(maxid + 1);
EXECUTE IMMEDIATE stmttxt;
END
@
db2 connect to sample
db2 -tf sp.sql
db2 terminate
Run Code Online (Sandbox Code Playgroud)
DB2手册:如果要修改标识列
修改标识列定义
如果要重新创建表,然后执行导入或加载操作,并且如果表中有IDENTITY列,则将重置该值以在重新创建表内容后从1开始生成IDENTITY值.将新行插入此重新创建的表时,您不希望IDENTITY列再次从1开始.
您不希望IDENTITY列中出现重复值.为防止这种情况发生,您应该:
SELECT MAX(<IDENTITY column>).这将返回表的IDENTITY列值的等效值.ALTER TABLE <table name> ALTER COLUMN <IDENTITY column> RESTART WITH <last counter value + 1>