如果数据中有空值,如何将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
但我似乎没有正确的语法。
转换此列的最佳方法是什么?
修改的 人们已经建议它不是导致我这个问题的空值,而是非数字数据。有没有一种简单的方法可以找到非数字数据并忽略它,或突出显示它以便我可以纠正它。
答案 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',所以在这些情况下你可能只想用空字符串替换逗号然后尝试?