Sql 无法将varchar转换为int或减去它们
我有以下一组SQL语句。目的是找出每种商品的售价Sql 无法将varchar转换为int或减去它们,sql,sql-server,sql-server-2008,sql-server-2005,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
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中遇到的错误:
Msg 245,第16级,状态1,第3行将varchar值“0.0”转换为数据类型int时,转换失败
如何解决这个问题?您应该修复数据。但我建议显式转换:
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);
注意:此答案使用的是十进制(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'
--但这些都不能转换为十进制。您应该修复数据。但我建议显式转换:
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);
注意:此答案使用的是十进制(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'
--但这些都不能转换为十进制。尝试转换为精度足以覆盖实际数据集的十进制类型,例如
UPDATE SALE SET cost = '0.0' WHERE cost IS NULL OR ISNUMERIC(cost) = 0;
ALTER TABLE SALE ALTER COLUMN cost DECIMAL(12, 4);
您得到的确切错误消息似乎以字符串literal
0.0
不能转换为整数为中心。但是,如果您试图转换为十进制,那么这听起来并不正确,在这种情况下,0.0
是一个完全可以接受的值。尝试转换为精度足以覆盖实际数据集的十进制类型,例如
UPDATE SALE SET cost = '0.0' WHERE cost IS NULL OR ISNUMERIC(cost) = 0;
ALTER TABLE SALE ALTER COLUMN cost DECIMAL(12, 4);
您得到的确切错误消息似乎以字符串literal
0.0
不能转换为整数为中心。但是,假设您试图转换为十进制,那么这听起来并不正确,在这种情况下,0.0
是一个完全可以接受的值。我建议创建一个具有所需结构的新表,并将datain复制到新表中。然后重命名您的表。
代码如下:
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';
这将有所帮助。我建议创建一个具有所需结构的新表,并将数据复制到新表中。然后重命名您的表。 代码如下:
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';
这将有所帮助。@Neetu-您也可以使用
CONVERT
而不是从2012年开始提供的TRY\u CONVERT
(如您标记的2008和2005所述),它说:Msg 195,级别15,状态10,第4行“decimal”不是可识别的内置函数名。使用CONVERT代替TRY\u CONVERT,它显示0条记录。甚至在桌子上scost@Neetu-您也可以使用CONVERT
而不是从2012年开始提供的TRY\u CONVERT
(如您标记的2008和2005所述)。它说:Msg 195,级别15,状态10,第4行“decimal”不是可识别的内置函数名。使用CONVERT代替TRY\u CONVERT,它显示0条记录。即使在表scostCheck中,也要检查varchar列中是否有逗号。ISNUMERIC找不到它们,因为它将检查所有数字类型(包括货币)。错误消息建议cost为int,而不是varchar。在不使用前面的UPDATE
的情况下尝试ALTER。检查varchar列中是否有逗号。ISNUMERIC找不到它们,因为它将检查所有数字类型(包括货币)。错误消息建议cost为int,而不是varchar。在没有前面的更新的情况下尝试更改。您好,现在它显示:(0行受影响)Msg 5074,级别16,状态1,第3行对象“DF_SALE_scost”依赖于列“scost”。Msg 4922,级别16,状态9,第3行ALTER TABLE ALTER COLUMN scost失败,因为一个或多个对象访问此列。@Neetu这看起来是一个错误,源于架构中完全不同的问题。您好,现在它显示:(0行受影响)Msg 5074,级别16,状态1,第3行对象“DF_SALE_scost”依赖于列“scost”。Msg 4922,级别16,状态9,第3行ALTER TABLE ALTER COLUMN scost失败,因为一个或多个对象访问此列。@Neetu这看起来像是一个错误,源于架构中完全不同的问题。是的,至少这样,现在一切正常。ThanxYeah,至少有了这个,现在一切都正常了。塔克斯