当我没有要求时,SQL错误将数据转换为Int

时间:2017-04-28 17:54:57

标签: sql sql-server casting

我有以下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

4 个答案:

答案 0 :(得分:3)

在合并之前将t.TotalPremium转换为十进制。您的查询对字符串和整数执行coalesce,然后将结果转换为十进制。 Try using 0.0 instead of 0 as well.

编辑除了可读性之外,我实际上并不认为使用0.0而不是0是一个好主意。如果这是目标,则将其强制转换为相同的十进制数据类型。否则,这可以被解释为优于decimal的数据类型。 0int 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