我有以下SQL语句。在其中我需要将存储为varchar的一些数字转换为十进制,以便对它们求和。
当我针对我的约束运行此SQL时,我收到此消息:
Msg 245,Level 16,State 1,Line 1 将varchar值'1635.34'转换为数据时转换失败 输入int。
令我感到困惑,因为我将数据转换为十进制数据。它也让我感到困惑,因为当我使用在字段中具有相同类型数据的不同约束(1234.56
类型的格式)时,它可以工作。该数据位于TotalPremium
字段中。
(我的逻辑有点复杂,所以这就是为什么SQL语句很复杂。为了清楚起见,我发布了所有这些内容。此外,重新设计数据库表字段类型不是一个选项。)
SELECT Account_No, version_num, LineOfBus, ProductNo, QuoteNo, Sum(Cast(TotalPremium as Decimal(16,2))) TotalPremium
FROM
(SELECT t.Account_No, t.version_num,
CASE
WHEN t.PackageIndicator = '1' THEN 'Package' Else t.Lob
END AS LineOfBus,
t.ProductNo, t.QuoteNo, Cast(COALESCE(t.TotalPremium,0) as decimal(16,2)) TotalPremium
FROM uAccountProductInfo as T
WHERE t.version_num IN
(SELECT sqVersionNumber.version_num
FROM
/* this captures unique package product records (or just stand alone records as well) */
(SELECT DISTINCT sqUnique.version_num, Count(sqUnique.version_num) VersionCount
FROM
/* grab list of all uniquer version, product, quote combinations (use distinct to combine package */
(SELECT DISTINCT version_num, productNo, quoteNo
FROM uAccountProductInfo
WHERE Account_No = '1172014' /* pass as parameter */
AND ProductNo IN ('6472930', '6474927') /* pass as parameter */
AND QuoteNo IN ('724185-01', '881957-08') /* pass as parameter */
) AS sqUnique
GROUP BY version_num
HAVING Count(version_num) = 2 /* pass as variable based on number of products, quotes */
) as sqVersionNumber
)
AND t.Account_no = '1172014' /* pass as parameter */
AND t.ProductNo IN ('6472930', '6474927') /* pass as parameter */
AND t.QuoteNo IN ('724185-01', '881957-08') /* pass as parameter */) as sqLOB
GROUP BY Account_No, version_num, LineOfBus, ProductNo, QuoteNo
答案 0 :(得分:3)
在合并之前将t.TotalPremium
转换为十进制。您的查询对字符串和整数执行coalesce
,然后将结果转换为十进制。 Try using
0.0 instead of
0 as well.
编辑除了可读性之外,我实际上并不认为使用0.0
而不是0
是一个好主意。如果这是目标,则将其强制转换为相同的十进制数据类型。否则,这可以被解释为优于decimal
的数据类型。 0
或int
varchar
不应优先于我们的小数值。
答案 1 :(得分:2)
您可以使用isnull()
代替coalesce()
,但使用与RexMaison指出的相同数据类型仍然是更好的做法。
create table t (TotalPremium varchar(16));
insert into t values (''),(null),('1635.34');
/* no error */
select isnull(t.TotalPremium,0)
from t;
/* no error */
select coalesce(t.TotalPremium,'0')
from t;
/* error */
select coalesce(t.TotalPremium,0)
from t;
rextester演示:http://rextester.com/OHEJ71310
答案 2 :(得分:2)
问题是SQL Server不保证操作评估的顺序。你在这个领域显然有一些不合适的东西。在SQL Server 2012+中,使用sudo apt-get install php libapache2-mod-php
sudo a2enmod mpm_prefork && sudo a2enmod php7.0
sudo service apache2 restart
:
try_convert()
在早期版本中,请使用SELECT Sum(try_convert(decimal(16, 2), TotalPremium ))) as TotalPremium
:
case
SELECT Sum(case when isnumeric(TotalPremium) = 1 then convert(decimal(16, 2), TotalPremium)) end) as TotalPremium
并不完美,但它应该足以满足您的目的。
答案 3 :(得分:0)
只需在合并所有3个答案的元素后发布最终代码。
SELECT Account_No, version_num, LineOfBus, ProductNo, QuoteNo,
SUM(CASE
WHEN ISNUMERIC(TotalPremium) = 1 THEN CONVERT(decimal(16,2),TotalPremium)
END) As TotalPremium
FROM
(SELECT t.Account_No, t.version_num,
CASE
WHEN ISNull(t.PackageIndicator,'0') = '1' THEN 'Package' Else t.Lob
END AS LineOfBus,
t.ProductNo, t.QuoteNo,
ISNull(CASE
WHEN ISNUMERIC(t.TotalPremium) = 1 THEN CONVERT(decimal(16,2),t.TotalPremium)
END, 0) TotalPremium
FROM uAccountProductInfo as T
WHERE t.version_num IN
(SELECT sqVersionNumber.version_num
FROM
/* this captures unique package product records (or just stand alone records as well) */
(SELECT DISTINCT sqUnique.version_num, Count(sqUnique.version_num) VersionCount
FROM
/* grab list of all uniquer version, product, quote combinations (use distinct to combine package */
(SELECT DISTINCT version_num, productNo, quoteNo
FROM uAccountProductInfo
WHERE Account_No = '1172014' /* pass as parameter */
AND ProductNo IN ('6472930', '6474927') /* pass as parameter */
AND QuoteNo IN ('724185-01', '881957-08') /* pass as parameter */
) AS sqUnique
GROUP BY version_num
HAVING Count(version_num) = 2 /* pass as variable based on number of products, quotes */
) as sqVersionNumber
)
AND t.Account_no = '1172014' /* pass as parameter */
AND t.ProductNo IN ('6472930', '6474927') /* pass as parameter */
AND t.QuoteNo IN ('724185-01', '881957-08') /* pass as parameter */) as sqLOB
GROUP BY Account_No, version_num, LineOfBus, ProductNo, QuoteNo