As far as I can tell, the only differences required to make this work are:
1) add sql:is-constant with namespace
2) convert xs:integers to xs:decimals or even xs:string
3) convert xs:date to xs:string
I haven't been ignoring your questions, I'm afraid I can't answer questions
as to why xsds won't work with SQL Server. Maybe they are meant to be
compatible with .net. Have you tried any .net methods of reading XML files
with schemas? Maybe there are compatibility problems with XML data-types and
SQL Server data-types. It's not unusual in ETL to have to load to a staging
table (eg where all columns are VARCHAR) and then clean the data.
All I know is, these xsd are not quite suitable for SQL Server straightaway,
but need a few minor modifications.
I have been working on way to make this easy, so it can be used against
multiple xsds. Try this:
IF OBJECT_ID( 'dbo.usp_fix_xsd' ) IS NOT NULL
DROP PROC dbo.usp_fix_xsd
GO
------------------------------------------------------------------------------------------------
-- Fix up an .xsd file for import into SQL Server START
-- Example call:
-- EXEC dbo.usp_fix_xsd 'C:\...\Genome\original_schema1.xml'
------------------------------------------------------------------------------------------------
CREATE PROC dbo.usp_fix_xsd
@filepath NVARCHAR(MAX), -- the filepath of the .xsd you want to fix
@debug_yn BIT = 0
AS
SET NOCOUNT ON
-- Load up orginal schema
DECLARE @xml XML
DECLARE @sql NVARCHAR(MAX)
DECLARE @loop_limit INT
-- Avoid infinite loops
SET @loop_limit = 99
SET @sql = 'SELECT @xml = x.y
FROM OPENROWSET( BULK ''' + @filepath + ''', SINGLE_CLOB ) x(y)'
IF @debug_yn = 1
SELECT @sql
-- Extract loaded XML
EXEC sp_executesql @sql, N'@xml XML OUT', @xml OUT
-- Inspect the XML beforehand
IF @debug_yn = 1
SELECT 'Before' AS source,
x.y.value('local-name(.)', 'VARCHAR(50)'),
x.y.value( '@type', 'SYSNAME' )
FROM @xml.nodes( '//xs:element' ) x(y)
-- Add sql:is-constant attribute
SET @xml.modify( 'declare namespace
sql="urn:schemas-microsoft-com:mapping-schema";
insert attribute sql:is-constant{1} as last into (//xs:element)[1]' )
-- Update all @type attributes with value xs:integer to xs:decimal
DECLARE @i INT SET @i = 0
WHILE @xml.exist( '(//xs:element[@type = "xs:integer"]/@type)[1]' ) = 1
BEGIN
SET @xml.modify( 'replace value of (//xs:element[@type =
"xs:integer"]/@type)[1] with "xs:decimal"' )
SET @i = @i + 1
IF @i > @loop_limit
BEGIN
RAISERROR( 'Too many loops.', 16, 1 )
BREAK
END
END
IF @debug_yn = 1
IF @i > 0
PRINT CAST( @i AS VARCHAR(10) ) + ' xs:integer converted to xs:decimal'
SET @i = 0
-- Update all @type attributes with value xs:date to xs:string
WHILE @xml.exist( '(//xs:element[@type = "xs:date"]/@type)[1]' ) = 1
BEGIN
SET @xml.modify( 'replace value of (//xs:element[@type =
"xs:date"]/@type)[1] with "xs:string"' )
SET @i = @i + 1
IF @i > @loop_limit
BEGIN
RAISERROR( 'Too many loops.', 16, 1 )
BREAK
END
END
IF @debug_yn = 1
IF @i > 0
PRINT CAST( @i AS VARCHAR(10) ) + ' xs:date converted to xs:string'
IF @debug_yn = 1
-- Inspect the XML afterwards
SELECT 'After' AS source,
x.y.value('local-name(.)', 'VARCHAR(50)'),
x.y.value( '@type', 'SYSNAME' )
FROM @xml.nodes( '//xs:element' ) x(y)
-- Return the modified schema
SELECT @xml
GO
All I did, was start with a working bulk load example and .xsd and go from
there. My other advice to you is to remain calm!
My final advice to you is try the MSDN SQL XML newsgroup which is much more
busy than this one:
http://forums.microsoft.com/msdn/Sho...ID=89&SiteID=1
Present simple problems with sample data, desired results etc and keep
trying!
Oh and remain calm, again ; )
(PS I know how frustrating SQLXMLBulkLoad can be. I love it when it doesn't
do anything, doesn't tell you it hasn't done anything and won't tell you why).