为具有多个索引的表创建XML文件,使用多个列创建索引将返回重复索引

时间:2016-09-22 16:30:21

标签: sql-server xml

我正在为可能有多个索引的表创建一个xml文件,索引可能有多个列。 我的问题是,当我有一个与之关联的多列的索引时,索引会多次写入xml文件。 (列数)。
这是我的问题:

SELECT [IndTbl].IndexName AS "@IndexName", [IndTbl].PrimaryKeyIndex AS "@PrimaryKeyIndex", [IndTbl].IndexDescription AS "@IndexDescription", 
 [IndTbl].PadIndex as "@PadIndex", [IndTbl].StatisticsNoRecompute as "@Statistics_NoRecompute", [IndTbl].IgnoreDupKey as "@IgnoreDupKey", 
 [IndTbl].AllowRowLocks as "@AllowRowLocks", [IndTbl].AllowPageLocks as "@AllowPageLocks",
     (
        SELECT DISTINCT [IndColTbl].IndexColumnName as "@ICName", [IndColTbl].IsDescendingSort as "@IsDescendingSort", [IndColTbl].OrdinalPosition as "@OrdinalPosition"
        FROM ( SELECT DISTINCT S4.IndexName, IndexColumnName, IsDescendingSort, OrdinalPosition
              FROM #SourceDBObjects S4 JOIN #TableObjectsToAdd T4 ON S4.TableName = T4.TableName AND S4.IndexName = T4.IndexName 
             ) AS [IndColTbl]
         WHERE [IndColTbl].IndexName = [IndTbl].IndexName 
        FOR XML PATH('IndexColumn'),
        TYPE
    )                       
FROM (SELECT DISTINCT T3.TableName, T3.IndexName, S3.PrimaryKeyIndex, IndexDescription, PadIndex, StatisticsNoRecompute, IgnoreDupKey, AllowRowLocks, AllowPageLocks                                
      FROM #SourceDBObjects S3 JOIN #TableObjectsToAdd T3 ON S3.TableName = T3.TableName AND S3.IndexName = T3.IndexName AND T3.IndexName IS NOT NULL ) AS [IndTbl]                     
WHERE [Table].TableName = [IndTbl].TableName
FOR XML PATH('Index'),
TYPE

临时表#SourceDBObjects包含所有索引数据。 临时表#TableObjectsToAdd只有要添加的索引名称。

我需要做的是在外部查询中添加DISTINCT。但使用DISTINCT时不允许FOR XML

因此,如果索引有7个与索引关联的列,则索引将在xml文件中显示7次。

我无法使用TOP 1,因为可能有多个与该表关联的索引。

如果我将IndexColumnName限制添加到IndexColumn子查询(在SELECT中),那么我得到索引7次,其中1列与索引关联。

如何在不使用DISTINCT的情况下限制索引显示多列?

2 个答案:

答案 0 :(得分:0)

我可能找到了解决方案...... 我向外部查询添加了GROUP BY,它限制了索引写入xml文件的次数。

答案 1 :(得分:0)

这有点复杂吗?

此查询将一次性获取所有信息...您可以非常轻松地添加更多数据(例如来自sys.stats)...

SELECT tables.name AS [@name]
      ,tables.object_id AS [@object_id]
      ,(
        SELECT indexes.name AS [@name]
              ,indexes.index_id AS [@id]
              ,(
                SELECT columns.name AS [@name]
                      ,columns.column_id AS [@column_id]
                      ,index_columns.index_column_id AS [@index_column_id]
                      ,index_columns.is_descending_key AS [@is_descending_key]
                FROM sys.index_columns
                    INNER JOIN sys.columns ON index_columns.object_id=columns.object_id AND index_columns.column_id=columns.column_id
                WHERE index_columns.index_id=indexes.index_id
                  AND index_columns.object_id=tables.object_id
                FOR XML PATH('index_column'),TYPE
              ) AS [index_columns]
        FROM sys.indexes
        WHERE indexes.object_id=tables.object_id
        FOR XML PATH('index'),TYPE
      ) AS [indexes]
FROM sys.tables WHERE tables.type='U'
FOR XML PATH('table'),ROOT('DataBase')

更新:更简单......

FOR XML RAW会将所有列及其名称作为属性放入XML中(除非您未指定ELEMENTS)。使用SELECT *,您无需输入太多内容即可获得所有信息...

SELECT tables.*
      ,(
        SELECT indexes.*
              ,(
                SELECT columns.name AS column_name
                      ,index_columns.*
                FROM sys.index_columns
                    INNER JOIN sys.columns ON index_columns.object_id=columns.object_id AND index_columns.column_id=columns.column_id
                WHERE index_columns.index_id=indexes.index_id
                  AND index_columns.object_id=tables.object_id
                FOR XML RAW('index_column'),TYPE
              ) AS [index_columns]
        FROM sys.indexes
        WHERE indexes.object_id=tables.object_id
        FOR XML RAW('index'),TYPE
      ) AS [indexes]
FROM sys.tables WHERE tables.type='U'
FOR XML RAW('table'),ROOT('DataBase')