【发布时间】:2014-12-30 23:02:07
【问题描述】:
我有这样的 T-SQL 代码:
DECLARE @xml XML = (SELECT CONVERT(xml, BulkColumn, 2) FROM OPENROWSET(Bulk 'C:\test.xml', SINGLE_BLOB) [blah])
-- Data for Table 1
SELECT
ES.value('id-number[1]', 'VARCHAR(8)') IDNumber,
ES.value('name[1]', 'VARCHAR(8)') Name,
ES.value('date[1]', 'VARCHAR(8)') Date,
ES.value('test[1]', 'VARCHAR(3)') Test,
ES.value('testing[1]', 'VARCHAR(511)') Testing,
ES.value('testingest[1]', 'VARCHAR(5)') Testingest
FROM @xml.nodes('xmlnodes/path') AS EfficiencyStatement(ES)
-- Data for Table 2
SELECT
U.value('fork[1]', 'VARCHAR(8)') Fork,
U.value('spoon[1]', 'VARCHAR(3)') Spoon,
U.value('spork[1]', 'VARCHAR(3)') Spork,
FROM @xml.nodes('xmlnodes/path/nextpath') AS Utensils(U)
现在,我已经尝试了我通常使用的以及其他变体,例如:
AS XML ON xml.[id-number] = [table1].[id-number]
郑重声明,id-number 在整个文档中是唯一的。它永远不会再发生。
这对于从我的 XML 文件中获取数据很有用,但是参照完整性为零。如何确保表 2(及以上)在插入时保持引用完整性?
这应该是一个更好的解释:
- 我想从文件中加载 XML 值。对于
INSERT,我可以毫无问题地使用OPENXML,并在最后使用AS XML ON xml.[id-number] = [table1].[id-number]根据id 号绑定它。 - 我想使用
UPDATE、MERGE或其他东西来更新数据库记录(包括所有链接的表及其列)——任何东西!为此,我相信我需要找到一种方法来根据每个表中存在的Foreign_ID值来维护引用完整性。有几十个表都通过Foreign_ID链接,那么我如何更新所有这些?
表格示例
Table #1
+-------------+-----------+-----------+------------+---------+-----------+------------+
| Primary_Key | ID_Number | Name | Date | Test | Testing | Testingest |
+-------------+-----------+-----------+------------+---------+-----------+------------|
| 70001 | 12345 | Tom | 01/21/14 | Hi | Yep | Of course! |
| 70002 | 12346 | Dick | 02/22/14 | Bye | No | Never! |
| 70003 | 12347 | Harry | 03/23/14 | Sup | Dunno | Same. |
+----^--------+-----------+-----------+------------+---------+-----------+------------+
|
|-----------------|
|
Table #2 | Linked to primary key in the first table.
+-------------+--------v--------+-------------+-------------+------------+
| Primary_Key | Foreign_ID | Fork | Spoon | Spork |
+-------------+-----------------+-------------+-------------+------------+
| 0001 | 70001 | Yes | No | No |
| 0002 | 70002 | No | Yes | No |
| 0003 | 70003 | No | No | Yes |
+-------------+-----------------+-------------+-------------+------------+
插入之后,我需要能够UPDATE XML 文件中的表和列。经过大量研究,我无法弄清楚如何更新Foreign_ID 链接的每个表的值同时保持参照完整性。这意味着我在其他表中插入了错误的数据。
我想要更新正确的数据。为了正确更新它,我需要确保 XQuery 匹配正确的数据。有些表有多个字段对应一个特定的 Foreign_ID。
这是我正在使用的代码:
DECLARE @xml XML = (SELECT CONVERT(xml, BulkColumn, 2) FROM OPENROWSET(Bulk 'C:\test.xml', SINGLE_BLOB) [blah])
-- Data for Table 1
SELECT
ES.value('id-number[1]', 'VARCHAR(8)') IDNumber,
ES.value('name[1]', 'VARCHAR(8)') Name,
ES.value('date[1]', 'VARCHAR(8)') Date,
ES.value('test[1]', 'VARCHAR(3)') Test,
ES.value('testing[1]', 'VARCHAR(511)') Testing,
ES.value('testingest[1]', 'VARCHAR(5)') Testingest
INTO #TempTable
FROM @xml.nodes('xmlnodes/path') AS EfficiencyStatement(ES)
-- @Serial Error: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
SET @IDNumber = (SELECT SerialNumber from #TempTable)
SET @Foreign_ID = (SELECT [Foreign_ID] from [table] WHERE [id-number] = @IDNumber)
MERGE dbo.[table1] AS CF
USING (SELECT IDNumber, Name, Date, Test, Testing, Testingest FROM #TempTable) AS src
ON CF.[id-number] = src.IDNumber
-- ID-Number is unique, and is used to setup the initial referential integrity. Foreign_ID does not exist in the XML files, so we are not matching on that.
WHEN MATCHED THEN UPDATE
SET
CF.[id-number] = src.IDNumber
-- and so on...
WHEN NOT MATCHED THEN
-- Insert statements here
GO
这适用于第一个表。通过Foreign_ID 更新其他表时,它不会保持完整性。请注意,SET @Serial 有错误,但是当我将其设置为其他任何内容时,它会正确更新。
【问题讨论】:
-
谢谢,但我已经有了,但这不能解决我的问题。这些是我们不允许修改的静态 XML 文件,它们不是 XSD。
标签: sql-server xml tsql sqlxml xquery-sql