更改表中包含或不包含数据的列长度

Posted

技术标签:

【中文标题】更改表中包含或不包含数据的列长度【英文标题】:Alter column length with or without data in table 【发布时间】:2015-03-19 11:52:15 【问题描述】:

关于 ORACLE (PL/SQL) 脚本。老实说,我对数据库不是很熟悉。 我想将列中字符串的长度从 30 更改为 60。它不是空列。 如果表为空并且我运行以下脚本,那么它可以工作:

alter table [TABLE_NAME] add ( NEW_COLUMN NVARCHAR2(60)  DEFAULT 'null' NOT NULL );
/
alter table [TABLE_NAME] DROP CONSTRAINT PK_[TABLE_NAME];
/
begin
   for rec in ( select * from [TABLE_NAME] )
   loop
      update [TABLE_NAME] set NEW_COLUMN =rec.OLD_COLUMN where Name_ID=rec.Name_ID;
   end loop;
end;
/
alter table [TABLE_NAME] drop column OLD_COLUMN;
/
alter table [TABLE_NAME] rename column NEW_COLUMN to OLD_COLUMN;
/
alter table [TABLE_NAME] add CONSTRAINT PK_[TABLE_NAME] PRIMARY KEY(Name_ID);
/

但是如果表有值,那么这个脚本就不起作用。 它给出错误:无法删除约束 - 不存在约束

但是,如果我删除有关约束的行(第二个和倒数第二个),那么它就可以工作。 现在我不知道表是空的还是有数据的,所以我需要一个可以在这两种情况下工作的脚本。有人可以帮忙吗?

以下创建表格的脚本:

CREATE TABLE TABLE_NAME
(
Name_ID NVARCHAR2(7) NOT NULL,
OLD_COLUMN NVARCHAR2(30) NOT NULL,
CONSTRAINT PK_TABLE_NAME PRIMARY KEY(Name_ID, OLD_COLUMN)
)
/

因此,在创建表时,它会放置主键约束,但在更新表时,它会以某种方式删除此约束。我只是简单地说明一下这里的情况。这些表是通过 java 代码更新的。我需要做的是制作一个适用于两种情况的脚本 - 使用数据或在创建表和修改列之后。

【问题讨论】:

请编辑您的问题以包含创建表(包括约束)脚本,以便我们至少可以尝试复制您的特定场景。另外,为什么要在 PL/SQL 中进行更新?这样做会使事情复杂化并减慢速度。相反,为什么不只是:update table_name set new_column = old_column;,然后是明确的commit; 另外,“脚本不起作用”是什么意思?它会出错吗?如果是这样,您会遇到什么错误? 我认为错误是rec. OLD_COLUMN中的空格;顺便提一句。你应该按照 Boneist 的说明进行更新,不要忘记 commit 这里没有显式提交并不是什么大问题,因为下一个 DDL 语句会自动进行提交,但最好不要依赖隐式 DDL 提交。跨度> 【参考方案1】:

以下脚本适用于我,无论插入语句是否存在(即表有或没有数据):

CREATE TABLE TABLE_NAME
(
Name_ID NVARCHAR2(7) NOT NULL,
OLD_COLUMN NVARCHAR2(30) NOT NULL,
CONSTRAINT PK_TABLE_NAME PRIMARY KEY(Name_ID, OLD_COLUMN)
);

insert into table_name (name_id, old_column)
values ('test', 'test_old_col');

commit;

alter table table_name add (new_column nvarchar2(60) default 'null' not null);

update table_name set new_column = old_column;

commit;

alter table table_name drop constraint PK_TABLE_NAME;

alter table table_name drop column old_column;

alter table table_name rename column new_column to old_column;

alter table TABLE_NAME add CONSTRAINT PK_TABLE_NAME PRIMARY KEY(Name_ID, old_column);

drop table table_name;

我假设您打算重新创建包含 old_column 的主键,否则如果 name_id 列中存在任何重复值,您将无法重新创建它。

【讨论】:

好的。它现在工作。我不确定在复制值之前删除约束是否会引发此问题。您还建议以不同的方式复制值。谢谢。 不会的,不;该约束对 new_column 的内容没有影响。我只是将约束的删除移动到它最符合逻辑的位置(至少对我来说!) - 就在列删除之前。【参考方案2】:

作为替代方案,您可以保存旧数据并使用新参数创建新表。然后插入旧值。

在 SQL Server Management Studio 中:

"你的数据库" => 任务 => generatescripts => 选择特定的数据库对象 => "你的表" => 高级 => 脚本的数据类型 - 模式和数据 => 生成

【讨论】:

对不起,我没有注意到它是 ORACLE (PL/SQL)。但想法是一样的。

以上是关于更改表中包含或不包含数据的列长度的主要内容,如果未能解决你的问题,请参考以下文章

更改多个表的列长度

更改 Hybris 中已经存在的列的长度?

在 Vue 项目中包含或初始化 jQuery 库的最佳方法是啥?

为 R 中的列表长度分析重新组织数据集

无法在包含 NULL 值的 SQL 表中创建 JSON 格式的列

如何检索所有表列、数据类型、数据长度、约束类型以及引用的列和表