SQL - 使用XML路径查询

时间:2016-07-01 08:49:15

标签: sql sql-server

我有以下查询:

SELECT     ara.req_id
FROM        tbl_ara ara
WHERE       id in (
                        SELECT STUFF((
                        SELECT ',' + cast(id as varchar(8000))
                        FROM contact
                        WHERE ct_id = 2
                        FOR XML PATH('')
                        ), 1, 1, ''))

因此,theres是名为contact的表格,当ids类型为2时,我想要获取所有id。然后我用Stuff创建一个列表。 然后我想使用另一个表并获取他们public async void Run(IBackgroundTaskInstance taskInstance) { BackgroudTaskDefferal defferal = taskInstance.GetDeferral(); await DoSomethingAsync(); // Other irrevelant stuff then... defferal.Complete(); } 在该列表中的所有记录。 您可以在查询中看到逻辑。 问题是SQL无法将其识别为列表,我收到以下错误:

  

消息245,级别16,状态1,行11转换时转换失败   nvarchar值   '6019,49111,49112'   数据类型int。

3 个答案:

答案 0 :(得分:3)

在您的情况下,

STUFF返回字符数据。从文档(https://msdn.microsoft.com/en-us/library/ms188043.aspx):

  

如果character_expression是受支持的字符数据类型之一,则返回字符数据。如果character_expression是受支持的二进制数据类型之一,则返回二进制数据。

所以你没有得到一个ID列表,而是一个包含数字和逗号的字符串。

是否有理由不直接使用ID?

SELECT 
    [ara].[req_id]
FROM [tbl_ara] [ara]
WHERE [id] IN
             (
              SELECT 
                  [id]
              FROM [contact]
              WHERE [ct_id] = 2
             )

编辑:当然@ gofr1的JOIN解决方案也是一个不错的选择。

答案 1 :(得分:2)

最简单的方法是JOIN:

SELECT ara.req_id
FROM tbl_ara ara
INNER JOIN contact c
    ON ara.id = c.id
WHERE c.ct_id = 2

如果要使用STUFF运行,则应使用动态SQL。首先准备语句,然后执行它:

DECLARE @sql nvarchar(max), @inpart nvarchar(max)

SELECT @inpart = STUFF((
                    SELECT ',' + cast(id as varchar(8000))
                    FROM contact
                    WHERE ct_id = 2
                    FOR XML PATH('')
                    ), 1, 1, '')


SELECT @sql = '
SELECT     ara.req_id
FROM        tbl_ara ara
WHERE       id in (' + @inpart+ ')'


PRINT @sql

--EXEC sp_executesql @sql

PRINT会告诉你:

SELECT     ara.req_id
FROM        tbl_ara ara
WHERE       id in (6019,49111,49112)

取消注释EXEC sp_executesql @sql以执行查询。

答案 2 :(得分:1)

你为什么不试试这个:

SELECT  ara.req_id
FROM    tbl_ara As ara
WHERE   Exists( Select  1
                From    contact As c
                Where   c.ct_id = 2
                        And c.id = ara.id
              )

as exists子句仅检查单个匹配是否存在,并在找到匹配时返回该行。