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

标签 sql sql-server casting

我有以下 SQL 语句。在其中,我需要将一些存储为 varchar 的数字转换为十进制以便对它们求和。

当我针对我的约束运行此 SQL 时,我会收到以下消息:

Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '1635.34' to data type 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

最佳答案

问题在于 SQL Server 不保证操作的评估顺序。您显然在该领域有一些不适当的地方。在 SQL Server 2012+ 中,使用 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

isnumeric() 并不完美,但它应该足以满足您的目的。

关于当我不要求它时,SQL 错误将数据转换为 Int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43686218/

相关文章:

php - sql查询不适用于三个表连接

c# - 如何在具有值类型约束的泛型声明类型之间进行复制

sql - 跨三个表的 LEFT JOIN(带联结表)

sql - 在 SQL 中对 SELECT DISTINCT 使用 ORDER BY

sql - 无法在函数MS SQL中声明变量

sql-server - 如何获取 sql server XML 列的 xml 安全版本

c - 显式 int32 -> float32 转换的规则

java - 将 2D 对象数组的列转换为 1D 字符串数组

sql - 如何在多个表中强制执行唯一性

mysql - 查找日期范围内商店中存储架的可用性