20

我有一个我认为被错误宣布的专栏。它包含数据,我不希望丢失数据。

我希望将定义从 varchar(max) 更改为 varchar(an integer)。我的印象是我不能只改变列类型?

最好的方法是创建一个临时列“column2”,将数据传输到该列,从有问题类型的列,删除问题列,然后将临时列重命名为原始有问题的列?

如果是这样,我如何将问题列中的值复制到新列?

编辑:对于任何有同样问题的人,您可以使用 ALTER 语句。

4

4 回答 4

29

只要数据类型有点“相关” - 是的,你绝对可以这样做。

您可以将 an 更改INT为 a BIGINT- 第二种类型的值范围更大,因此您不会有“丢失”任何数据的危险。

您可以将 a 更改VARCHAR(50)VARCHAR(200)- 再次,类型兼容,大小越来越大 - 没有截断任何内容的风险。

基本上,你只需要

ALTER TABLE dbo.YourTable
ALTER COLUMN YourColumn VARCHAR(200) NULL

管他呢。只要您的字符串长度不超过这 200 个字符,就可以了。不确定如果您确实有更长的字符串会发生什么 - 转换将失败并出现错误,或者它会继续并告诉您某些数据可能已被截断。所以我建议你先在你的数据副本上试试这个:-)

VARCHAR如果您需要将 a 更改为 an或类似的东西,它会变得有点棘手INT- 显然,如果您的列值不“适合”新类型,则转换将失败。但即使使用单独的“临时”新列也无法解决此问题——您需要以某种方式处理那些“不兼容”的情况(忽略它们,将 NULL 保留在那里,将它们设置为默认值 - 某些东西)。

VARCHAR此外,如果您有非西欧字符,则在和之间切换NVARCHAR可能会变得棘手 - 您可能会在转换时丢失某些条目,因为它们不能以另一种格式表示,或者从一种类型到另一种类型的“默认”转换没有按预期工作。

于 2012-05-18T09:46:49.913 回答
3

计算该表的该列存储的最大数据长度。

Select max(len(fieldname)) from tablename

现在,您可以将该列的大小减小到上一个查询中得到的结果。

ALTER TABLE dbo.YourTable
ALTER COLUMN YourColumn VARCHAR(200) NULL
于 2012-05-18T09:55:52.080 回答
1

根据 PostgreSQL文档,您可以简单地alter table

ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);

但事情是这样的

只有当列中的每个现有条目都可以通过隐式强制转换转换为新类型时,这才会成功。如果需要更复杂的转换,您可以添加一个 USING 子句,指定如何从旧值计算新值。

于 2018-04-05T07:30:51.827 回答
0

添加一个类型为 varchar(NN) 的临时 column2,运行update tbl set column2 = column,检查是否发生任何错误;如果一切正常,请更改原始列,将数据复制回来并删除 column2。

于 2012-05-18T09:48:33.973 回答