转换varchar值时转换失败' 1 12:57:39 3168.68 485 H5555'到数据类型int。这发生在SQL中 Server 2012提供以下代码。
SELECT
MEMBER_ID
,STUFF
(
(
SELECT ',[' + C1 + '-' + C2 + ']' AS [text()]
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM TestSQL A
JOIN TestSQL B ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.CLAIM_ID <> '1 12:57:39 3168.68 485 H5555'
AND YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND (CAST(B.CLAIM_ID AS INT)-CAST(A.CLAIM_ID AS INT))=2
) Y
WHERE MEMBER_ID = X.MEMBER_ID
FOR XML PATH('')
),1,1,''
) AS CLAIM_ID_LIST
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM TestSQL A
JOIN TestSQL B ON A.MEMBER_ID = B.MEMBER_ID
WHERE YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND (CAST(B.CLAIM_ID AS INT)-CAST(A.CLAIM_ID AS INT))=2
AND A.CLAIM_ID IN (SELECT CLAIM_ID FROM TestSQL WHERE MEMBER_ID<>'')
) X
我试图过滤掉1 12:57:39 3168.68 485 H5555
并仍然给我这个错误。这是CLAIM_ID
。
WHERE MEMBER_ID = X.MEMBER_ID
FOR XML PATH正上方的子句,但我不知道为什么。第二个子查询有效。我很欣赏这方面的任何见解。
答案 0 :(得分:2)
这是错误的来源:
(CAST(B.CLAIM_ID AS INT)-CAST(A.CLAIM_ID AS INT)) = 2
将1 12:57:39 3168.68 485 H5555
投射到INT
会产生错误。虽然你说你已经在WHERE A.CLAIM_ID <> '1 12:57:39 3168.68 485 H5555'
过滤了它。优化器可以选择首先评估CAST
,从而导致错误。
您可能希望先在CTE
中对其进行过滤。然后使用CTE
代替:
;WITH CTE AS(
SELECT
*
FROM TestSQL
WHERE
CLAIM_ID <> '1 12:57:39 3168.68 485 H5555'
)
SELECT
MEMBER_ID
,STUFF
(
(
SELECT ',[' + C1 + '-' + C2 + ']' AS [text()]
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM CTE A
JOIN CTE B ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.CLAIM_ID <> '1 12:57:39 3168.68 485 H5555'
AND YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND (CAST(B.CLAIM_ID AS INT)-CAST(A.CLAIM_ID AS INT))=2
) Y
WHERE MEMBER_ID = X.MEMBER_ID
FOR XML PATH('')
),1,1,''
) AS CLAIM_ID_LIST
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM CTE A
JOIN CTE B ON A.MEMBER_ID = B.MEMBER_ID
WHERE YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND (CAST(B.CLAIM_ID AS INT)-CAST(A.CLAIM_ID AS INT))=2
AND A.CLAIM_ID IN (SELECT CLAIM_ID FROM CTE WHERE MEMBER_ID<>'')
) X
要确保只返回数字CLAIM_ID
,您可以在CTE
内使用此内容:
SELECT *
FROM TestSQL
WHERE CLAIM_ID NOT LIKE '%[^0-9]%'
答案 1 :(得分:1)
试试这个:
--use cte to create a copy of the table minus the dodgy row
--or simply set that claim to null and cast remaining values
--use this anywhere we need to cast claim_id to int
;with cte as
(
select *
, case
when CLAIM_ID = '1 12:57:39 3168.68 485 H5555'
then null
else
cast(CLAIM_ID as int)
end CLAIM_ID_INT
from TestSQL
)
SELECT
MEMBER_ID
,STUFF
(
(
SELECT ',[' + C1 + '-' + C2 + ']' AS [text()]
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM cte A
JOIN cte B ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.CLAIM_ID <> '1 12:57:39 3168.68 485 H5555'
AND YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND (B.CLAIM_ID_INT - A.CLAIM_ID_INT)=2
) Y
WHERE Y.MEMBER_ID = X.MEMBER_ID
FOR XML PATH('')
),1,1,''
) AS CLAIM_ID_LIST
FROM
(
SELECT DISTINCT A.MEMBER_ID
,A.CLAIM_ID AS C1
,A.PLAN_ID AS PC1
,B.CLAIM_ID C2
,B.PLAN_ID AS PC2
,A.AMOUNT AS AMT1
,B.AMOUNT AS AMT2
FROM cte A
JOIN cte B ON A.MEMBER_ID = B.MEMBER_ID
WHERE YEAR(A.DATE) > 2000
AND B.DATE > A.DATE
AND B.PLAN_ID <> A.PLAN_ID
AND B.CLAIM_ID_INT-A.CLAIM_ID_INT = 2
AND A.CLAIM_ID IN (SELECT CLAIM_ID FROM cte WHERE MEMBER_ID<>'')
) X