Sql 如何将nvarchar(254)转换为十进制(7,2)

Sql 如何将nvarchar(254)转换为十进制(7,2),sql,sql-server,casting,type-conversion,alteryx,Sql,Sql Server,Casting,Type Conversion,Alteryx,我有一个包含10M+行的表,希望将其中一列的数据类型从nvarchar(254)更改为decimal(7,2)。进行此更改最有效的查询是什么 我曾尝试使用ALTER进行此更改,但在SSMS中出现错误 将数据类型nvarchar转换为数字时出错 我也尝试过使用CAST,但这也会导致错误。诚然,我不是DBA,因此我很难理解以下内容: 如何正确编写不会产生错误的强制转换查询 CAST和CONVERT函数是否在数据库级别更改数据的设计(即在对象资源管理器中,当我右键单击表,然后单击“设计”时,我会看到列

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

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

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

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

  • 如何正确编写不会产生错误的强制转换查询

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

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

    SET STATISTICS TIME ON
    
    ALTER TABLE Clone3
    
    ALTER COLUMN Price decimal(7,2)
    
    最终目标是正确地存储这些数据,以便在将其放入其他可视化程序(例如Tableau、Power BI等)时可以执行算术运算。也就是说,这里的预期结果是将数据类型更改为
    Decimal(7,2)
    ,但实际结果是
    nvarchar(254)

    更新

    运行
    后,从Clone3中选择Price,其中TRY_CONVERT(十进制(7,2),Price)为空
    有239条记录以科学记数法返回。例如-5.0000000000000003E-2

    最终更新

    我运行了下面的查询来更新导致转换错误的记录(这些是负数,如'-0.05',由于某种奇怪的原因被转换为科学符号)

    更新克隆3
    设定价格=铸造(浮动价格)
    其中TRY_CONVERT(十进制(7,2),Price)为空

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

    ALTER TABLE Clone3
    更改列价格小数点(7,2)


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

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

    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;
    

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

    5。999999999999999999 8E-2
    不能直接转换为十进制(7,2),尽管它可以转换为
    浮点数,然后可以转换为十进制(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
    

    如果在转换过程中出现错误,首先需要找到有问题的值。你能分享(部分)Clone3中TRY_CONVERT(十进制(7,2),Price)为空的
    SELECT Price的结果吗谢谢。另外,我刚刚注意到,但是“要更改为
    十进制(7,2)
    的数据类型,但实际结果是
    nvarchar(254)
    ”是什么意思?如果希望返回的结果是
    varchar
    ,则存储
    varchar
    。老实说,这句话听起来像是胡说八道——我在写这篇文章的时候,试图按照上面的指导方针去做,但我觉得我误读了一些东西。我的场景中的“实际结果”就是我目前看到的。为了重申我在上面写的内容,“……这里的预期结果是将数据类型更改为Decimal(7,2),但我目前看到的是nvarchar(254)。”对于任何混淆,我深表歉意。@Larnu-以下是我运行的您请求的查询的一些结果:`-7.0000000000000007E-2-5.0000000000000003E-2-5.99999999999999998E-2 5.999999999999999998E-2.9999999999999999999E-2-5.0000000000000000000003E-2.99999999999999999999E-2-4.0000000000000001E-2`没有评论提供这种信息的地方。请编辑您的帖子。这不会解决“将数据类型nvarchar转换为数字时出错”的问题。不过,感谢您的回复!你知道复制表格需要多长时间吗(同样是10米以上的记录,每小时计数)?另外,“truncate table”语句的用途是什么?不需要将行复制两次。如果这样做的话,插入到具有所需结构的新表以及删除和重命名将更加有效route@MartinSmith . . . 重新插入保留了索引、触发器和约束。可以轻松地将它们添加到空表中,以避免将所有行复制两次(如果您甚至希望触发此迁移插入),这听起来是个好主意,David。在TRY_CONVERT(decimal(7,2),Price)为NULL的Clone3中,如何动态地转换
    SELECT Price的结果作为浮点数?该查询只产生239个结果,因此我的想法是,在将这些数据类型更改为float之后,我可以在整个数据集上运行嵌套cast语句的另一部分。思想?
    
    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