Я ищу самый простой способ экспортировать таблицу (или ее часть) в XML-файл, а затем импортировать этот XML-файл в соответствующую таблицу в другой базе данных.Как написать `select ... FOR XML` запросы, которые генерируют xml и xsd так, что они готовы к работе с SQLXMLBulkLoad?
Принцип я нашел очень простой:
- Экспорт: на исходной базе данных я генерировать строку XML, а также строку схемы XSD путем добавления
FOR XML root('Data')
иFOR XML, XMLSCHEMA
положения для выбора запроса. - Импорт: в целевую базу данных Я загружаю сгенерированный XML-файл с помощью SQLXMLBulkLoad с помощью сгенерированного xsd.
Но я не могу это сделать. Между экспортом и импортом я должен внести некоторые незначительные изменения в схему xsd.
Например, я генерировать XML и XSD строки по следующим запросам:
select top 3 * FROM myTable
FOR XML AUTO, ELEMENTS
,Root('Data')
и
SELECT top 0 * FROM myTable
FOR XML AUTO, ELEMENTS
,XMLSCHEMA
Результирующая generated.xml и generated.xsd выглядеть так:
<Data>
<myTable>
<field1>value11</field1>
...
<field1>value1n</field1>
</myTable>
<myTable>
<field1>value21</field1>
...
<field1>value2n</field1>
</myTable>
<myTable>
<field1>value31</field1>
...
<field1>value3n</field1>
</myTable>
</Data>
и
<xsd:schema
targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1"
xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd"/>
<xsd:element name="myTable">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="field1" type="..." .../>
...
<xsd:element name="fieldn" type="..." ... />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Но если я хочу, чтобы пакетная загрузка с помощью VB Script, как этот
set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0")
objBL.ConnectionString = "provider=SQLOLEDB.1;data source=localhost\SQLEXPRESS;database=Testdb;uid=sa;pwd=*****"
objBL.ErrorLogFile = ".\error.xml"
objBL.KeepIdentity = False
objBL.Execute "generated.xsd", "generated.xml"
set objBL=Nothing
, то это работает, только если я внести следующие изменения в generated.xsd
- удалить этот
xsd:schema
атрибут:targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1"
- добавить
xsd:schema
атрибут:xmlns:sql="urn:schemas-microsoft-com:mapping-schema"
- Заменить
<myTable>
элемента последовательностью<myTable>
элементов и обернуть все в<xsd:element name="Data" sql:is-constant="1">
элемент - Добавьте атрибуты
maxOccurs="unbounded" sql:relation="myTable"
к<myTable>
элементу
Таким образом, модифицированный XSD, который действительно подходит для пакетной загрузки сгенерированного XML с помощью SQLXMLBulkLoad выглядит как это:
<xsd:schema
xmlns:sql="urn:schemas-microsoft-com:mapping-schema"
xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd"/>
<xsd:element name="Data" sql:is-constant="1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="myTable" maxOccurs="unbounded" sql:relation="myTable">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="field1" type="..." .../>
...
<xsd:element name="fieldn" type="..." ... />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Интересно, если генерирующий SQL-запросы и/или VBScript могут быть изменены таким образом, что сгенерированного XML и XSD работы с VBScript без какого-либо ручного изменения?
Это очень хорошо вопрос (+1 с моей стороны)! Ясно, с кодом, но - я сожалею об этом, но пока не ответил ... SQL-Server предлагает «XMLSCHEMA» и «XMLDATA» для создания двух разных версий мета-описания (встроенного). Это явно не соответствует вашим потребностям. Вы можете использовать строковые методы vb, чтобы изменить это. Может быть, кто-то еще знает лучше ... – Shnugo