在 SQL 服务器中将数字转换为 INT 的正确方法
Proper Way to CAST a Numeric as an INT in SQL Server
我收到一个无效的转换异常,因为我的 COALESCE 正在处理一个数字数据类型值和一个 int 数据类型值。
查询运行正常,但 C# 抛出无效转换异常。
我向我的 COALESCE 添加了一个强制转换,但仍然收到无效强制转换异常。
问题:我在我的 COALESCE 中正确投射了吗?
错误涉及的属性声明如下:
public int StartingMembershipCount { get; set; }
错误的地方在这里
m.StartingMembershipCount = r.GetNullableInt32("StartingMembershipCount",0);
我的数据助手定义为:
public static int GetNullableInt32(this IDataRecord r, string name, int defaultValue)
{
var ordinal = r.GetOrdinal(name);
int returnVal = 0;
if (r.IsDBNull(ordinal))
returnVal = defaultValue;
else
returnVal = r.GetInt32(ordinal);
return returnVal;
}
这是我的 COALESCE(表达式 1 具有数字数据类型)
COALESCE((
-- Expression 1
SELECT CAST(n.TOTAL_MBR AS INT)
FROM
usr_kiw_cus_certified n INNER JOIN
(SELECT ClubId, min(AsOfDate) AsOfDate FROM
(SELECT ukm.MASTER_CUSTOMER_ID ClubId, ukm.AS_OF_DATE AsOfDate FROM usr_kiw_cus_certified ukm WHERE ukm.AS_OF_DATE > @StartDate AND ukm.master_customer_id = c.MASTER_CUSTOMER_ID) as temp
GROUP BY ClubId) AS datetable
ON datetable.ClubId = n.MASTER_CUSTOMER_ID and n.AS_OF_DATE = datetable.AsOfDate
),
-- Expression 2
(SELECT COUNT(cr.MASTER_CUSTOMER_ID)
FROM cus_relationship cr
WHERE cr.RELATED_MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
AND cr.RELATIONSHIP_TYPE = 'employment'
GROUP BY cr.RELATED_MASTER_CUSTOMER_ID
)) AS StartingMembershipCount,
您必须转换整个表达式:
CAST(COALESCE((SELECT ...),(SELECT ...)) AS INT) AS StartingMembershipCount,
当子查询中没有行 return 时,SELECT 中的 CAST(或类型)不适用。
或者您可以 "just" 转换整个第一个子查询,因为第二个子查询总是 return 结果:
COALESCE(CAST((SELECT ...) AS INT), (SELECT ...)) AS StartingMembershipCount,
因为第二个总是 return 结果,所以根本不需要为 NULLable。使用 ISNULL 应该可以解决这个问题:
ISNULL(CAST((SELECT ...) AS INT), (SELECT ...)) AS StartingMembershipCount,
ISNULL 的缺点是它不能支持第三个参数,如果你需要的话;这不是标准的。优点是结果不可为NULLable,所以可以直接使用GetInt32
顺便说一句,当我在 C# 中遇到该异常时,我通常会暂时将 r.GetValue(ordinal) 转换为 return 作为对象的值(当然,你可以' t 分配给一个 int 变量),然后检查它的类型。
我收到一个无效的转换异常,因为我的 COALESCE 正在处理一个数字数据类型值和一个 int 数据类型值。
查询运行正常,但 C# 抛出无效转换异常。
我向我的 COALESCE 添加了一个强制转换,但仍然收到无效强制转换异常。
问题:我在我的 COALESCE 中正确投射了吗?
错误涉及的属性声明如下:
public int StartingMembershipCount { get; set; }
错误的地方在这里
m.StartingMembershipCount = r.GetNullableInt32("StartingMembershipCount",0);
我的数据助手定义为:
public static int GetNullableInt32(this IDataRecord r, string name, int defaultValue)
{
var ordinal = r.GetOrdinal(name);
int returnVal = 0;
if (r.IsDBNull(ordinal))
returnVal = defaultValue;
else
returnVal = r.GetInt32(ordinal);
return returnVal;
}
这是我的 COALESCE(表达式 1 具有数字数据类型)
COALESCE((
-- Expression 1
SELECT CAST(n.TOTAL_MBR AS INT)
FROM
usr_kiw_cus_certified n INNER JOIN
(SELECT ClubId, min(AsOfDate) AsOfDate FROM
(SELECT ukm.MASTER_CUSTOMER_ID ClubId, ukm.AS_OF_DATE AsOfDate FROM usr_kiw_cus_certified ukm WHERE ukm.AS_OF_DATE > @StartDate AND ukm.master_customer_id = c.MASTER_CUSTOMER_ID) as temp
GROUP BY ClubId) AS datetable
ON datetable.ClubId = n.MASTER_CUSTOMER_ID and n.AS_OF_DATE = datetable.AsOfDate
),
-- Expression 2
(SELECT COUNT(cr.MASTER_CUSTOMER_ID)
FROM cus_relationship cr
WHERE cr.RELATED_MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
AND cr.RELATIONSHIP_TYPE = 'employment'
GROUP BY cr.RELATED_MASTER_CUSTOMER_ID
)) AS StartingMembershipCount,
您必须转换整个表达式:
CAST(COALESCE((SELECT ...),(SELECT ...)) AS INT) AS StartingMembershipCount,
当子查询中没有行 return 时,SELECT 中的 CAST(或类型)不适用。
或者您可以 "just" 转换整个第一个子查询,因为第二个子查询总是 return 结果:
COALESCE(CAST((SELECT ...) AS INT), (SELECT ...)) AS StartingMembershipCount,
因为第二个总是 return 结果,所以根本不需要为 NULLable。使用 ISNULL 应该可以解决这个问题:
ISNULL(CAST((SELECT ...) AS INT), (SELECT ...)) AS StartingMembershipCount,
ISNULL 的缺点是它不能支持第三个参数,如果你需要的话;这不是标准的。优点是结果不可为NULLable,所以可以直接使用GetInt32
顺便说一句,当我在 C# 中遇到该异常时,我通常会暂时将 r.GetValue(ordinal) 转换为 return 作为对象的值(当然,你可以' t 分配给一个 int 变量),然后检查它的类型。