简而言之:我想对 SQL Server (2008) 数据库进行 XML 批量加载,并为父级生成自动增量 ID,可以在子级中使用。这似乎受到范围的限制:父节点尚未完成,因此尚未插入。有人知道解决这个问题的方法吗?
更长的描述(对不起,它真的很长,但我尽量完整):
从一个客户那里,我得到了很多具有相似结构的 XML 文档,从中可以生成一个测试数据库。它们被导出以供其他工具使用,我的客户没有权限也没有联系来影响结构或内容。(这些工具是由另一方为母公司编写的。)他也没有对 XML 或导出它们的数据库的正式描述。
事实证明,“顶级”XML 节点<Registration>
确实有 ID,但它们在文档中并不是唯一的。(顶部节点是相对的,它们确实有一个根节点和一个列表节点,但在 XML 中它们是进入数据库的最高元素。)ID 可以在其他 XML 文档中使用,因为它们引用到<Case>
不在导出中的另一个对象。所以我需要生成自动增量ID,以保持所有<Registration>
元素的唯一性,即使跨文件也是如此。
我的<Registration>
-node 有很多女儿,例如<Activity>
-node。这些节点需要引用它们的父节点,因此它们应该使用生成的 auto-increment-id。但是,由于它们是未完成父节点的一部分,因此父节点仍在范围内,并且尚未插入表中,如msdn和technet上的“记录子集和密钥排序规则”中所述。但是,这些站点上的示例具有明确的唯一CustomerId
ID,而不是自动生成的 Id。
尽管这个关于“密钥排序规则”的文档看起来无法做到这一点,但我不能相信对于缺少(唯一)ID 的 XML 文件没有办法解决这个问题。更奇怪的是:它确实在 child 中插入了一个 parent-id,但数字低了一个。所以我假设这是前一个范围的自动增量 ID(其中 0 是默认值,尚未插入任何内容,我确实希望为 NULL)。所以我确实看到了一种解决方法:之后增加我的子表中的父键(UPDATE Activity SET RegistrationId = RegistrationId + 1
)。但是,这确实需要保持一个限制 ( WHERE TimeStamp > ...
) 并且不需要其他(手动或脚本)干预。
我已经尝试了很多不同的关系船和 VB 脚本(例如,我更喜欢自动生成我的表格),但我只会发布我的最新尝试。这也将用于说明从前一个范围插入自动增量 ID。
我的主要问题是:
- 是否有可能获得正确的自动递增父 ID?
但也欢迎其他提示,例如:
CREATE TABLE
在 SQL 中没有显式语句的情况下,使用什么设置自动生成自动增量标识?
生成表格:
CREATE TABLE [dbo].[Registration](
[Id] INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_Registration PRIMARY KEY,
[XmlId] [nvarchar](40) NULL,
)
CREATE TABLE [dbo].[Activity](
[Id] INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_Activity PRIMARY KEY,
[RegistrationId] INT CONSTRAINT FK_Activity_Registration FOREIGN KEY (RegistrationId) REFERENCES Registration (Id),
[XmlId] [nvarchar](1000) NULL,
)
要导入的 XML 文件:
<Updates>
<Registrations>
<Registration ID="NonUniqCaseId-123">
<Activities>
<Activity ID="UniqActId-1234" />
<Activity ID="UniqActId-1235" />
</Activities>
</Registration>
<Registration ID="NonUniqCaseId-124">
<Activities>
<Activity ID="UniqActId-1241" />
<Activity ID="UniqActId-1242" />
</Activities>
</Registration>
</Registrations>
</Updates>
用于测试上传的 VB 脚本(我想稍后在程序中包含一个循环,以处理多个文件):
Dim objBL
Set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.4.0")
objBL.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=Test;integrated security=SSPI"
objBL.ErrorLogFile = "error.log"
objBL.CheckConstraints = False
objBL.XMLFragment = False
objBL.SchemaGen = True
objBL.SGDropTables = False
objBL.KeepIdentity = False
objBL.Execute "BulkTestMapping.xsd", "BulkTestContents.xml"
Set objBL = Nothing
XSD:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified"
elementFormDefault="qualified"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xs:annotation>
<xs:appinfo>
<sql:relationship name="Registration_Activity"
parent="Registration"
parent-key="Id"
child="Activity"
child-key="RegistrationId"
inverse="true"
/>
</xs:appinfo>
</xs:annotation>
<xs:element name="Registration"
sql:relation="Registration"
sql:key-fields="Id"
>
<xs:complexType>
<xs:sequence>
<xs:element name="Activities" minOccurs="0" maxOccurs="unbounded" sql:is-constant="true">
<xs:complexType>
<xs:sequence>
<xs:element name="Activity" minOccurs="0" maxOccurs="unbounded"
sql:relation="Activity"
sql:key-fields="RegistrationId"
sql:relationship="Registration_Activity"
>
<xs:complexType>
<xs:attribute name="ID" sql:field="XmlId" form="unqualified" type="xs:string" />
<xs:attribute name="DbId" sql:identity="ignore" sql:field="Id" msdata:AutoIncrement="true" msdata:ReadOnly="true" type="xs:int" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="ID" form="unqualified" sql:field="XmlId" />
<xs:attribute name="DbId" sql:identity="ignore" sql:field="Id" msdata:AutoIncrement="true" type="xs:int" />
</xs:complexType>
</xs:element>
</xs:schema>
结果表(注意减RegistrationId
一):
[Registration]
Id XmlId
1 NonUniqCaseId-123
2 NonUniqCaseId-124
[Activity]
Id RegistrationId XmlId
1 0 UniqActId-1234
2 0 UniqActId-1235
3 1 UniqActId-1241
4 1 UniqActId-1242
编辑:这比我想象的还要糟糕。如果我再次添加记录,外键(子键)再次从 0 开始!所以很难甚至不可能确定更正(每张表)应该是什么:
[Registration]
Id XmlId
1 NonUniqCaseId-123
2 NonUniqCaseId-124
3 NonUniqCaseId-123
4 NonUniqCaseId-124
[Activity]
Id RegistrationId XmlId
1 0 UniqActId-1234
2 0 UniqActId-1235
3 1 UniqActId-1241
4 1 UniqActId-1242
5 0 UniqActId-1234
6 0 UniqActId-1235
7 1 UniqActId-1241
8 1 UniqActId-1242