1

我有一个包含 10M+ 行的表,并且想要将其中一列的数据类型从nvarchar(254)更改为decimal(7,2)。进行此更改的最有效和最有效的查询是什么?

我尝试使用 ALTER 进行此更改,但在 SSMS 中出现错误

将数据类型 nvarchar 转换为数值时出错。

我也尝试过使用 CAST,但这也会导致错误。诚然,我不是 DBA,所以我很难理解以下内容:

  1. 如何正确编写不会产生错误的 CAST 查询

  2. CAST 和 CONVERT 函数是否更改了数据库级别的数据设计(意思是在对象资源管理器中,当我右键单击表然后单击“设计”时,我看到列的数据类型已更改)或者如果更改只会持续到下一个查询运行或程序退出。

该表最初是在一个多月前创建的,是几个月前运行的工作流的结果;此后,此工作流程已计划以每小时的节奏将新数据推送到表中,因此删除作业/表并重新开始不是一种选择。

SET STATISTICS TIME ON

ALTER TABLE Clone3

ALTER COLUMN Price decimal(7,2)

最终目标是正确存储这些数据,以便在将其摄取到其他可视化程序(例如,Tableau、Power BI 等)中时可以执行算术运算。也就是说,这里的预期结果是要更改数据类型toDecimal(7,2)但实际结果是nvarchar(254).

更新

运行后SELECT Price from Clone3 WHERE TRY_CONVERT(decimal(7,2),Price) IS NULL有 239 条记录以科学计数法返回。例如 -5.0000000000000003E-2

最后更新

我运行以下查询来更新导致转换错误的记录(这些是负数,例如“-0.05”,由于某种奇怪的原因被转换为科学记数法)。

UPDATE Clone3 SET Price = CAST(Price AS Float) WHERE TRY_CONVERT(decimal(7,2), Price) IS NULL

因为所有记录现在都是数字数据类型,所以我可以使用此查询将整个数据集转换为十进制 (7,2)。

ALTER TABLE Clone3 ALTER COLUMN Price decimal(7,2)

我想我可以称之为解决了,非常感谢大家的回复,特别是 @Larnu 提供的代码片段最终帮助我解决了这个问题。

4

2 回答 2

3

5.9999999999999998E-2不能直接转换为 decimal(7,2),尽管它可以转换为 a float,然后可以转换为 decimal(7,2)。例如

select cast(cast('5.9999999999999998E-2' as float) as decimal(7,2))

虽然不是最有效的,也不是这类事情的通用解决方案,但您可以更改表两次,例如:

use tempdb

drop table if exists t
create table t(s varchar(200))
insert into t(s) values ('5.9999999999999998E-2')

go

alter table t alter column s float
alter table t alter column s decimal(7,2)

go
select * from t
于 2019-01-21T19:27:24.910 回答
0

最有效的方法可能是清空表并重新加载它:

select *
into temp_t
from t;

truncate table temp_t;

alter table t alter column price decimal(7, 2);

insert into t
    select *
    from temp_t;

更新现有记录的开销更大。

于 2019-01-21T18:59:03.570 回答