つまり、SQL Server (2008) データベースに XML 一括読み込みを実行し、子で使用できる親の自動インクリメント ID を生成したいと考えています。これはスコープによって制限されているようです: 親ノードは完成していないため、まだ挿入されていません。誰もこれを回避する方法を知っていますか?
詳細な説明(申し訳ありませんが、非常に長いですが、私は完全にしようとしています):
顧客から、テスト DB を生成するための類似した構造を持つ XML ドキュメントをたくさん受け取りました。それらは別のツールで使用するためにエクスポートされます。私の顧客には、構造や内容に影響を与える権限も連絡先もありません。(ツールは別の関係者が親会社のために作成したものです。) また、エクスポート元の XML やデータベースの正式な説明もありません。
「トップ」の XML ノード<Registration>
には ID がありますが、これらはドキュメント全体で一意ではないことがわかります。(トップ ノードは相対的であり、ルート ノードとリスト ノードがありますが、XML ではデータベースに到達する最上位の要素です。) ID は他の XML ドキュメントで使用される場合があります。<Case>
エクスポートに含まれていない別のオブジェクトに。<Registration>
したがって、ファイル間でもすべての要素を一意に保つために、auto-increment-id を生成する必要があります。
私の<Registration>
-node には、 -node などの多くの娘がい<Activity>
ます。これらのノードは親を参照する必要があるため、生成された auto-increment-id を使用する必要があります。ただし、これらは未完成の親ノードの一部であるため、親ノードはまだスコープ内にあり、 msdnおよびtechnetの「レコード サブセットとキーの順序付け規則」で説明されているように、まだテーブルに挿入されていません。ただし、これらのサイトの例にCustomerId
は、自動生成された ID ではなく、明示的な unique があります。
「キーの順序付けルール」に関するこのドキュメントでは、これを行うことができないように見えますが、(一意の) ID がない XML ファイルに対してこれを回避する方法がないとは信じられません。さらに奇妙なのは、子に親 ID を挿入することですが、その数は 1 つ小さいことです。したがって、これは前のスコープの auto-increment-id であると想定しています (ここで、0 はまだ何も挿入されていないデフォルトであり、NULL を想定していました)。したがって、回避策が 1 つあります。その後、子テーブルの親キーをインクリメントします ( UPDATE Activity SET RegistrationId = RegistrationId + 1
)。ただし、これには制限 ( ) を維持する必要がありWHERE TimeStamp > ...
、他の (手動またはスクリプトによる) 介入は必要ありません。
私は多くの異なるリレーションシップと VB スクリプトを試しました (たとえば、テーブルの自動生成を好みます) が、最新の試みを投稿します。これは、前のスコープからの auto-increment-id の挿入を説明するのにも役立ちます。
私の主な問題は次のとおりです。
- 自動インクリメントされた正しい親 ID を取得することは可能ですか?
ただし、次のような他のヒントは大歓迎です。
CREATE TABLE
SQLで明示的なステートメントなしで自動インクリメントIDを自動生成するために使用する設定は何ですか?
テーブルを生成します。
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>
結果のテーブル (1 つずれていることに注意してください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