sql-serverxmldatabasexsdxml-schema-collection

Modifying SQL Server Schema Collection


SQL Server XML Schema Collection is an interesting concept and I find it very useful when designing dynamic data content. However as I work my way through implementing Schema Collections, I find it very difficult to maintain them.

Schema Collection DDL allows only CREATE and ALTER/ADD nodes to existing schemes.

CREATE XML SCHEMA COLLECTION [ <relational_schema>. ]sql_identifier AS 'XSD Content'
ALTER XML SCHEMA COLLECTION [ <relational_schema>. ]sql_identifier ADD 'Schema Component'

When you want to remove any node from a schema you have to issue following DDL's.

  1. If that schema collection assigned to a table column, you have to alter table to remove schema collection association from that column
  2. Drop the schema collection object
  3. Re-Create schema collection
  4. Alter table column to re-associate schema collection to that column.

This is pain when it comes to 100+ of schemes in a collection. Also you have to re-create XML indexes all over again, if any.

Any solutions, suggestions, tricks to make this schema collection object editing process easier?


Solution

  • I agree with David that XML is not the panacea we were told it would be, but there are some situations where it is either unavoidable or the best tool for the job. Schema maintenance is painful though. I only have a couple to deal with and still lose hours.

    This script might help. It generates the table drops and adds you'll need. It would need to mdified to include UDFs or other objects that might reference the XML schema. To generate the Add schema statements, I suggest you use the "Generate Scripts..." function in the tasks menu in Mgt Studio and save them off for Step 2 of the script.

    SET NOCOUNT ON
    
    /* 
        1) Save cols to table var
    */
    DECLARE @xmlCols TABLE (
    numID INTEGER IDENTITY(1,1),
    TBL nvarchar(1024),
    COL nvarchar(1024),
    SCH nvarchar(1024)
    );
    
    insert into @xmlCols (TBL,COL,SCH)
    SELECT DISTINCT OBJECT_NAME(colm.object_id) AS 'TABLE', colm.name AS 'COLUMN', coll.name AS 'Schema' 
    FROM  sys.columns colm
       inner JOIN     sys.xml_schema_collections coll
            ON colm.xml_collection_id = coll.xml_collection_id
    ORDER BY OBJECT_NAME(colm.object_id), colm.name   
    
    DECLARE @lastRow as int
    DECLARE @currentRow as int
    DECLARE @dbName as varchar(1024)
    DECLARE @tableName as varchar(1024)
    DECLARE @colName as varchar(1024)
    DECLARE @schemaName as varchar(1024)
    SET @lastRow = @@ROWCOUNT
    SET @currentRow = @lastRow
    SET @dbName = 'dbNAme'
    
    print ''
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print '--!!!!! Scipt Schemas and Save in Mgt Studio !!!!'
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print ''
    
    
    print ''
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print '--!!!!! Omit Schemas from COls !!!!'
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print ''
    --omit the Schema for each column
    WHILE @currentRow <> 0
    BEGIN
        SELECT @tableName=TBL, @colName=COL, @schemaName=SCH from @xmlCols WHERE numID = @currentRow
    
        print N'ALTER TABLE [' + @tableName + N'] ALTER COLUMN ['+ @colName + N'] XML'
    
        set @currentRow = @currentRow -1
    END
    
    print ''
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print '--!!!!! drop your xml schema(s)  !!!!'
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print ''
    SET @currentRow = @lastRow
    WHILE @currentRow <> 0
    BEGIN
        SELECT @tableName=TBL, @colName=COL, @schemaName=SCH from @xmlCols WHERE numID = @currentRow
    
        print N'DROP XML SCHEMA COLLECTION [dbo].['+@schemaName+']'
    
        set @currentRow = @currentRow -1
    END
    
    print ''
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print '--!!!!! CLean your Tables      !!!!'
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print ''
    
    --clean up the tables
    SET @currentRow = @lastRow
    WHILE @currentRow <> 0
    BEGIN
        SELECT @tableName=TBL, @colName=COL, @schemaName=SCH from @xmlCols WHERE numID = @currentRow
    
        print N'DBCC CleanTable (''' + @dbName + N''', ''' + @tableName + N''', 0)'
    
        set @currentRow = @currentRow -1
    END
    
    print ''
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print '--!!!!! Run XML Schema Scripts !!!!'
    print '--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    print ''
    SET @currentRow = @lastRow
    WHILE @currentRow <> 0
    BEGIN
        SELECT @tableName=TBL, @colName=COL, @schemaName=SCH from @xmlCols WHERE numID = @currentRow
    
        print N'ALTER TABLE [' + @tableName + N'] ALTER COLUMN ['+ @colName + N'] XML('+ @schemaName + N')'''
    
        set @currentRow = @currentRow -1
    END
    

    Hope it helps.