【问题标题】:Creating a query from an XML input parameter in a stored procedure and verifying the output从存储过程中的 XML 输入参数创建查询并验证输出
【发布时间】:2019-10-15 14:31:08
【问题描述】:

我创建了一个将 XML 数据作为输入读取的存储过程。我有两个问题,希望有人可以帮助解决。

问题1:当我执行存储过程时,我只取回AccountType (9) 的第一个值。我期待/想要取回AccountType 的所有值。

问题 2: 解决上述问题后,我想使用来自 AccountType 的值从另一个表中选择用户,例如dbo.UserData

我尝试过的:

我在另一个可以调试的 SO 帖子上看到了这一点,但我不确定如何使用它或它在做什么。

select col.query('.') as Debug

XML:

<root>
    <From>4</From>
    <AccountType>9</AccountType>
    <AccountType>5</AccountType>
    <AccountType>6</AccountType>
    <AccountType>7</AccountType>
    <AccountType>5</AccountType>
    <AccountType>4</AccountType>
    <AccountType>1</AccountType>
    <AccountType>15</AccountType>
    <AccountType>16</AccountType>
    <AccountType>1</AccountType>
    <AccountType>ivs</AccountType>
    <AccountType>10</AccountType>
    <AccountType>12</AccountType>
    <AccountType>11</AccountType>
    <AccountType>tfs</AccountType>
    <AccountType>vsa</AccountType>
    <AccountType>13</AccountType>
    <AccountType>14</AccountType>
    <GroupID>1</GroupID>
    <GroupID>5</GroupID>
</root>

存储过程:

CREATE PROCEDURE dbo.UserSelect
    @XMLInput XML
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT
        'AccountType' = x.v('AccountType[1]', 'nvarchar(2)')
    FROM  
        @XMLInput.nodes('/root') AS x(v)
END

存储过程的执行:

DECLARE @XML as XML

SET @XML = '<root>
    <From>4</From>
    <AccountType>9</AccountType>
    <AccountType>5</AccountType>
    <AccountType>6</AccountType>
    <AccountType>7</AccountType>
    <AccountType>5</AccountType>
    <AccountType>4</AccountType>
    <AccountType>1</AccountType>
    <AccountType>15</AccountType>
    <AccountType>16</AccountType>
    <AccountType>1</AccountType>
    <AccountType>ivs</AccountType>
    <AccountType>10</AccountType>
    <AccountType>12</AccountType>
    <AccountType>11</AccountType>
    <AccountType>tfs</AccountType>
    <AccountType>vsa</AccountType>
    <AccountType>13</AccountType>
    <AccountType>14</AccountType>
    <GroupID>1</GroupID>
    <GroupID>5</GroupID>
</root>'

EXEC dbo.UserSelect @XML

【问题讨论】:

    标签: sql sql-server xml stored-procedures


    【解决方案1】:

    您很接近,但您需要在nodes 函数中指定“AccountType”节点。然后使用value函数获取值。

    select distinct x.v.[value]('.','nvarchar(2)') AccountType
    from @XML.nodes('/root/AccountType') x(v)
    

    在 ITVF(内联表值函数)中,它看起来像:

    create function dbo.GetAccountTypeFromXML
    (
      @Xml xml
    )
    returns table
    return
      select distinct x.v.[value]('.','nvarchar(2)') AccountType
      from @XML.nodes('/root/AccountType') x(v)
    

    然后可以用作例如:

    select *
    from dbo.UserData
    where AccountType in (select AccountType from dbo.GetAccountTypeFromXML(@Xml))
    

    【讨论】:

    • 我要再次感谢您。另一个问题 - 使用 AccountType '@XML' 时。我怎么知道 AccountType 是否存在于“@XML”中?例如,可能存在没有 AccountType 节点的情况。
    • 你尝试的时候发生了什么?你想发生什么?
    • 当我尝试它时,如果 AccountType 不存在,它似乎正在检查空值或空值。如果 xml 中不存在 AccountType,那么我希望它完全排除检查 AccountType。
    • 我不知道您的最终查询/使用情况是什么,但是如果按照建议使用 ITVF,当没有 AccountType 条目时它不会返回任何内容,因此只需检查没有返回的内容,例如(select count(*) from dbo.GetAccountTypeFromXML(@Xml)) = 0 或大于 0 或任何适合 :)
    • 我只是想在执行 sql select * from dbo.UserData where AccountType in (select AccountType from dbo.GetAccountTypeFromXML(@Xml)) 时检查节点 AccountType 是否存在。我想我已经通过检查是否存在返回布尔返回 1 来弄清楚它。IF @XML.exist('/root/AccountType') = 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 2021-04-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    相关资源
    最近更新 更多