无法将varchar转换为int或减去它们

时间:2018-08-10 11:03:16

标签: sql sql-server sql-server-2008 sql-server-2005

我有以下一组SQL语句。目的是找到每个项目的售价。

SELECT cost AS 'Price', disc AS 'Discount', (cost-disc) AS 'Selling Price' 
FROM SALE

问题在于cost, scost, disc列的数据类型为Varchar。因此,我尝试转换这些列,但是没有用。不,我尝试更改列数据类型,如下所示:

UPDATE SALE 
SET cost = '0.0' 
WHERE cost IS NULL OR ISNUMERIC(cost) = 0;

ALTER TABLE SALE 
    ALTER COLUMN cost DECIMAL(12,0);

UPDATE SALE 
SET scost = '0.0' 
WHERE scost IS NULL OR ISNUMERIC(scost) = 0;

ALTER TABLE SALE 
    ALTER COLUMN scost DECIMAL(12,0);

UPDATE SALE 
SET disc = '0.0' 
WHERE disc IS NULL OR ISNUMERIC(disc) = 0;

ALTER TABLE SALE 
    ALTER COLUMN disc DECIMAL(12,0);

我在SQL Server Management Studio中遇到的错误:

  

第245层状态1的状态3行
  将varchar值'0.0'转换为数据类型int时,转换失败。

如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

尝试转换为十进制类型,其精度足以覆盖您的实际数据集,例如

UPDATE SALE SET cost = '0.0' WHERE cost IS NULL OR ISNUMERIC(cost) = 0;
ALTER TABLE SALE ALTER COLUMN cost DECIMAL(12, 4);

您收到的确切错误消息似乎集中在字符串文字0.0的中心,该字符串不能转换为整数。但是,假设您尝试转换为小数,这听起来不对,在这种情况下,0.0是一个完全可以接受的值。

答案 1 :(得分:0)

您应该修复数据。但我建议显式转换:

select cost AS Price, disc AS Discount,
       (try_convert(decimal(20, 4), cost) - try_convert(decimal(20, 4), disc) ) as selling_price
from sale;

您不应将数字存储为字符串。您可以通过以下操作查看是否有任何值无效

select cost, disc
from sale
where try_convert(decimal(20, 4), cost) is null or
      try_convert(decimal(20, 4), disc) is null;

如果未返回任何行,则将其转换:

alter table alter column cost decimal(20, 4);
alter table alter column disc decimal(20, 4);

注意:此答案使用decimal(20, 4),您可以使用其他相关类型,但十进制似乎适合示例数据。

编辑:

在早期版本的SQL Server中,我建议:

select cost AS Price, disc AS Discount,
       ((case when cost not like '%[^0-9.]%' and cost not like '%.%.%'
              then convert(decimal(20, 4), cost)
         end) -
        (case when disc not like '%[^0-9]%'  and cost not like '%.%.%'
              then try_convert(decimal(20, 4), disc)
         end)
       ) as selling_price
from sale;

您可以使用类似的逻辑。我不建议使用isnumeric(),因为以下内容返回“ 1”-'$''.''3e4'-但这些都不转换为小数。

答案 2 :(得分:0)

我建议创建具有所需结构的新表,并将数据复制到新表中。然后重命名表。 下面是代码:

update SALE set cost='0.0' where cost='NULL' or cost IS NULL OR ISNUMERIC(cost) = 0;
update SALE set scost='0.0' where scost='NULL' or scost IS NULL OR ISNUMERIC(scost) = 0;
update SALE set disc='0.0' where disc='NULL' or disc IS NULL OR ISNUMERIC(disc) = 0;

CREATE TABLE SALENEW (cost decimal(18,2), scost decimal(18,2), disc decimal(18,2));

INSERT INTO SALENEW SELECT * FROM SALE;

EXEC sp_rename 'SALE', 'SALEBACKUP'; 
EXEC sp_rename 'SALENEW', 'SALE';

这会有所帮助。