0

问题:

我想从 sql 服务器获取更改以打印到(可能很大)xml 文件中。Sql-Server 启用了 ChangeTracking 以识别具有更改的实体。因此我写了三个Scalar-valued Functions可以为单个实体生成适当的 XML。

  • GenerateAccountXml( int AccountId )
  • GenerateDeviceXml( int DeviceId )
  • GenerateServiceXml( int ServiceId )
  • 我还有三个Table-valued Function返回特定 ChangeTracking 编号的实体 ID。

  • GetAccountChangeSets(bigint changeTrackingId)
  • GetDeviceChangeSets( bigint changeTrackingId )
  • GetServiceChangeSets(bigint changeTrackingId)
  • 最后我打了这样一个电话:

    select
    
    (
        select
        (
            select [dbo].GenerateServiceXml( CT.ServiceId )
            from [dbo].GetServiceChangeSets( 22000 ) CT
        ) FOR XML PATH( 'Services' ), TYPE
    ),
    
    (
        select
        (
            select [dbo].GenerateDeviceXml( CT.DeviceId )
            from [dbo].GetDeviceChangeSets( 22000 ) CT
        ) FOR XML PATH( 'Devices' ), TYPE
    ),
    
    (
        select
        (
            select [dbo].GenerateAccountXml( CT.AccountId ) )
            from [dbo].GetAccountChangeSets( 22000 ) CT
        ) FOR XML PATH( 'Accounts' ), TYPE
    )
    
    FOR XML PATH( 'Changes' ), TYPE
    

    只要GetXXXChangeSets函数只为每个实体返回一个 EntityId,这就会起作用,但目前我为每个实体获得多个 XML-Rows。现在问题是以下错误消息:

    Subquery returned more than 1 value. This is not permitted when the subquery 
    follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    

    我试过这个STUFF命令,但它只接受一个varchar。当我在 varchar(max) 中转换输出时,<>符号被替换。

    这个问题还有其他解决方案吗?

    4

    1 回答 1

    1

    如果您稍微更改查询,我认为引擎应该处理这个问题并为您提供多个 XML 节点。如果您想为元素集合创建一个根节点,您可能需要将其更改XML PATH('Service')为“XML PATH (''), ROOT('Services')”,这会将所有行合并到一个节点中。

    本质上,我认为问题在于您有太多嵌套的子选择。内置可以很好地处理嵌套表达式FOR XML中的多行。SELECT

    select
    
    (   select [dbo].GenerateServiceXml( CT.ServiceId )
        from [dbo].GetServiceChangeSets( 22000 ) CT
        FOR XML PATH( 'Services' ), TYPE
    ),
    
    (
        select [dbo].GenerateDeviceXml( CT.DeviceId )
        from [dbo].GetDeviceChangeSets( 22000 ) CT
        FOR XML PATH( 'Devices' ), TYPE
    ),
    
    (
        select [dbo].GenerateAccountXml( CT.AccountId ) )
        from [dbo].GetAccountChangeSets( 22000 ) CT
        FOR XML PATH( 'Accounts' ), TYPE
    )
    
    FOR XML PATH( 'Changes' ), TYPE
    
    于 2013-06-25T13:58:28.757 回答