Preciso analisar o XML de um arquivo em tabelas enquanto retenho seus relacionamentos por meio de valores de ID gerados de forma personalizada.
Por exemplo, se eu tivesse o seguinte XML:
<root>
<construction>
<constructionName>randomname1</constructionName>
<project>
<projectname>another randomname</projectname>
<businesspartners>
<partnername>bilbo bagginses</partnername>
</businesspartners>
<employees>
<employee>
<empname>frodo</empname>
<empaddress>etc...</empaddress>
</employee>
</employees>
</project>
<info>
<randElement></randElement>
</info>
<constructionType>houses</constructiontype>
</construction>
<construction>
<...(etc, same as above, times n^10)/>
</construction>
</root>
A partir disso, preciso gerar dados para as seguintes tabelas:
CONSTRUCTION (CONSTRUCTION_ID INT PRIMARY KEY
, CONSTRUCTIONNAME VARCHAR..
, CONSTRUCTIONTYPE VARCHAR.. )
PROJECT (PROJECT_ID INT PRIMARY KEY
, CONSTRUCTION_ID INT FOREIGN KEY REFERENCES CONSTRUCTION
, PROJECTNAME VARCHAR.., )
BUSINESSPARTNERS (BUSINESSPARTNERS_ID INT PRIMARY KEY
, PROJECT_ID INT FOREIGN KEY REFERENCES PROJECT
, PARTNERNAME VARCHAR..)
etc...
Basicamente, a ideia é construir tabelas com suas referências intactas para representar o XML. As estruturas da tabela já existem e não podem ser alteradas para acomodar este script. Isso é simplesmente uma questão de ser capaz de fazer o mesmo tipo de análise XML e, em seguida, adicionar os dados às tabelas enquanto gera os valores de ID de referência corretos, como fizemos antes com a integração. Só fazendo isso exclusivamente com SQL Server, e sem usar SSIS .
Agora, o cenário real e o arquivo em questão são bastante grandes, então não espero de forma alguma uma resposta completa. Apenas dicas sobre onde começar a procurar. Eu sou bastante inexperiente em lidar com XML.
Por enquanto, minha solução preferida seria apenas importar os dados com OPENROWSET
e, em seguida, usar o SQL dinâmico OPENXML
para analisar o documento nas tabelas, basicamente fazendo um loop dos elementos e seus subelementos, um de cada vez. Mas isso parece muito mais problemático do que alguma outra maneira mais inteligente.
Como os valores de ID são gerados?
Isso é parte da questão. Por enquanto não são. A ideia é que a cada CONSTRUCTION
elemento seria atribuído um ID
aumento de 1. Então, todos os filhos de CONSTRUCTION
se refeririam ao mesmo ID
atribuído ao pai e assim por diante. Basicamente, trata-se apenas de dividir os dados do XML em várias tabelas, mantendo intacta a integridade referencial.
Eu não teria nenhum problema em usar uma coluna de identidade como chave primária, desde que as relações não se misturassem como resultado. Não sei como fazer isso, então presumi que seria necessário, de alguma forma, definir manualmente a lógica para criar os IDs, em oposição à identidade.
Você pode usar uma variante da técnica descrita em Usando merge..output para obter o mapeamento entre source.id e target.id e por Adam Machanic em Dr. OUTPUT or: How I Learned to Stop Worrying and Love the MERGE .
Você usa
merge
e captura o ID gerado com o fragmento XML que pertence a esse ID em uma variável de tabela e, em seguida, usa essa variável de tabela ao adicionar linhas às tabelas filhas.SQL Fiddle