当存在空值时,将varchar中的列更改为十进制

时间:2015-02-18 08:08:12

标签: sql sql-server

如果数据中有空值,如何将sql varchar列更改为十进制列?

我想:

ALTER TABLE table1
ALTER COLUMN data decimal(19,6)

但我只是得到一个错误,我假设因为空值:

Error converting data type varchar to numeric. The statement has been terminated.

所以我想删除我可以将它们设置为零的空值:

ALTER TABLE table1
ALTER COLUMN data decimal(19,6) NOT NULL DEFAULT 0

但我似乎没有正确的语法。

转换此列的最佳方法是什么?

修改的 人们已经建议它不是导致我这个问题的空值,而是非数字数据。有没有一种简单的方法可以找到非数字数据并忽略它,或突出显示它以便我可以纠正它。

3 个答案:

答案 0 :(得分:2)

如果只是存在NULL,我会选择在alter column之前执行此操作:

update table1 set data = '0' where data is null

这将确保所有空值都消失,您可以成功转换。


但是,我不会某些你的假设。在我看来,您的新列完全能够处理NULL值,因为您还没有为其指定not null

我想要 数值,例如你得到的结果:

insert into table1 (data) values ('paxdiablo is good-looking')

虽然有些人可能认为应该对待0,假y值: - )

非NULL,非数字数据的存在似乎更有可能导致您的具体问题。


至于如何解决这个问题,您需要一个where子句来识别varchar列是否为有效数值,如果不是,则将其更改为{ {1}}或'0',视您的需要而定。

我不确定SQL Server是否具有正则表达式支持,但如果是这样,那将是我调查的第一个途径。

或者,如果您了解限制(a),您可以使用isnumeric()之类的内容:

NULL

在尝试转换列类型之前,这将强制所有非数字值为NULL。

而且,为了爱你所信仰的神灵,请在尝试任何这些操作之前备份你的数据。

如果以上解决方案都不起作用,可能值得添加一个全新的列并逐位填充。换句话说,将其设置为NULL以开始,然后找到将update table1 set data = NULL where isnumeric(data) = 0 复制到此新列的更新的系列

如果您对所有数据都已被复制感到高兴,那么如果您想要一次性完成转换,则应该可以在单个事务中运行一系列更新。删除新列,然后在一个操作中完成整个操作:

  • 创建新列;
  • 执行所有更新以复制数据;
  • 删除旧列;
  • 将新列重命名为旧名称。

(a)来自链接页面:

  

对于某些不是数字的字符,例如加号(+),减号( - )和有效货币符号(如美元符号($)),ISNUMERIC返回1。

答案 1 :(得分:0)

可能的解决方案:

CREATE TABLE test
(
    data VARCHAR(100)
)

GO

INSERT INTO  test VALUES ('19.01');
INSERT INTO  test VALUES ('23.41');

ALTER TABLE test ADD data_new decimal(19,6)
GO

UPDATE test SET data_new = CAST(data AS decimal(19,6));

ALTER TABLE test DROP COLUMN data
GO

EXEC sp_RENAME 'test.data_new' , 'data', 'COLUMN'

答案 2 :(得分:0)

正如人们所说,该错误不是来自空值,而是来自无法转换为十进制的varchar值。我找到的最典型的原因(在检查列之后不包含任何逻辑错误值,如非数字字符或双逗号值)是varchar值使用逗号表示十进制指针,而不是句点。

例如,如果您运行以下命令:

DECLARE @T VARCHAR(256)
SET @T = '5,6'
SELECT @T, CAST(@T AS DEC(32,2))

您将收到错误。

相反:

DECLARE @T VARCHAR(256)
SET @T = '5,6'

-- Let's change the comma to a period
SELECT @T = REPLACE(@T,',','.')

SELECT @T, CAST(@T AS DEC(32,2)) -- Now it works!

如果您的列具有这些情况,应该很容易查看,并在ALTER COLUMN之前运行相应的更新,如果这是原因。

您也可以使用类似的想法,并在列上进行正则表达式搜索,以查找与数字/数字+'。'+数字标准不匹配的所有值,但我吸吮正则表达式,以便其他人可以帮助。 :)

此外,美国系统使用奇怪的分隔符,如数字'123100.5',它将显示为'123,100.5',所以在这些情况下你可能只想用空字符串替换逗号然后尝试?