基本上我有两个表,Teachertbl
的主键为TeacherID
,TeacherBlobtbl
的{{1}}与TeacherID
相关,还有一个XML列TeacherTbl
。
TeacherBLOB
XML数据包含教师数据,例如班级和学生。
表的架构如下所示:
TeacherTbl:
TeacherBLOB
TeacherBlobTbl:
TeacherID int PRIMARY KEY
-- Other columns
TeacherID int FOREIGN KEY REFERENCES TeacherTbl (TeacherID)
TeacherBlob xml
中的XML示例如下所示:
TeacherBlob
基本上我想获得<Teacher>
. . .
<TeacherClass>
<FormRoom> Room A</FormRoom>
<TotalStudents> 25 </TotalStudents>
<Subject> Mathematics </Subject>
<Student>
<StudentName> James </StudentName>
<StudentAge> 15 </StudentAge>
<StudentAddress> </StudentAddress>
</Student>
</TeacherClass>
</Teacher>
和TeacherClass
并将它们移动到自己的表中。我想将Student
及其数据抓取到包含与TeacherClass
相关的外键的新表中。
除此之外,我想抓住与TeacherTbl
相关联的每个Student
,并使用与StudentClass
相关的外键将其移入自己的表格。
注意:我不想将TeacherClass
移到自己的表格中,我只关心Teacher
和TeacherClass
。
它应该类似于以下内容:
TeacherClasstbl:
Student
Studenttbl:
TeacherClassID int PRIMARY KEY
FormRoom VARCHAR(50)
TotalStudents int
Subject VARCHAR(100)
TeacherID int FOREIGN KEY REFERENCES TeacherTbl(TeacherID)
还值得注意的是,并非每个XML StudentID int PRIMARY KEY
StudentName VARCHAR(50)
StudentAge int
StudentAddress VARCHAR(100)
TeacherClass int FOREIGN KEY REFERENCES TeacherClassTbl(TeacherClassID)
都会有一个关联的Teacher
元素,并且解决方案需要满足来自TeacherClass
的新数据
请告诉我可用于实现此目的的任何工具/技术。
我考虑过制作一个按计划运行的存储过程,不确定是否有更好的解决方案。
谢谢!
答案 0 :(得分:1)
我建议将每个级别读入临时表表格,并从那里读取实际的转移:
我使用声明的表变量来模拟你的测试场景
DECLARE @Teacher TABLE(TeacherID INT IDENTITY,Name VARCHAR(100));
INSERT INTO @Teacher VALUES('Teacher 1'),('Teacher 2');
DECLARE @TeacherBLOB TABLE(TeacherBLOBID INT IDENTITY,TeacherID INT /*FK*/, TeacherBLOB XML);
INSERT INTO @TeacherBLOB VALUES
(1,'<Teacher>
<TeacherClass>
<FormRoom> Room A</FormRoom>
<TotalStudents> 25 </TotalStudents>
<Subject> Mathematics </Subject>
<Student>
<StudentName> James </StudentName>
<StudentAge> 15 </StudentAge>
<StudentAddress> </StudentAddress>
</Student>
</TeacherClass>
</Teacher>')
,(1,'<Teacher>
<TeacherClass>
<FormRoom> Room B</FormRoom>
<TotalStudents> 20 </TotalStudents>
<Subject> Physics </Subject>
<Student>
<StudentName> Jane </StudentName>
<StudentAge> 13 </StudentAge>
<StudentAddress> Some address </StudentAddress>
</Student>
<Student>
<StudentName> Tim </StudentName>
<StudentAge> 14 </StudentAge>
<StudentAddress> Some address </StudentAddress>
</Student>
</TeacherClass>
</Teacher>')
,(2,'<Teacher>
<TeacherClass>
<FormRoom> Room B</FormRoom>
<TotalStudents> 20 </TotalStudents>
<Subject> German </Subject>
<Student>
<StudentName> Hugo </StudentName>
<StudentAge> 14 </StudentAge>
<StudentAddress> Some address </StudentAddress>
</Student>
<Student>
<StudentName> Max </StudentName>
<StudentAge> 13 </StudentAge>
<StudentAddress> Some address </StudentAddress>
</Student>
</TeacherClass>
</Teacher>');
- 第一个查询读取TeacherClass
SELECT t.Name
,tc.query('.') AS TeacherClassXML
,tc.value('FormRoom[1]','nvarchar(max)') AS FormRoom
,tc.value('TotalStudents[1]','int') AS TotalStudents
INTO #TeacherClass
FROM @Teacher AS t
INNER JOIN @TeacherBLOB AS tb ON t.TeacherID=tb.TeacherID
OUTER APPLY tb.TeacherBLOB.nodes('/Teacher/TeacherClass') AS A(tc);
- 第二个查询读取主题
SELECT tc.*
,s.query('.') AS SubjectXML
,tc.TeacherClassXML.value('(TeacherClass/Subject)[1]','nvarchar(max)') AS [Subject]
INTO #Subject
FROM #TeacherClass AS tc
OUTER APPLY tc.TeacherClassXML.nodes('TeacherClass/Subject') AS B(s)
- 此查询读取学生
SELECT tc.*
,tc.TeacherClassXML.value('(TeacherClass/Subject)[1]','nvarchar(max)') AS [Subject]
,st.query('.') AS StudentXML
,st.value('StudentName[1]','nvarchar(max)') AS StudentName
,st.value('StudentAge[1]','int') AS StudentAge
,st.value('StudentAddress[1]','nvarchar(max)') AS StudentAddress
INTO #Student
FROM #TeacherClass AS tc
OUTER APPLY tc.TeacherClassXML.nodes('TeacherClass/Student') AS B(st)
- 检查内容
SELECT * FROM #TeacherClass;
SELECT * FROM #Subject;
SELECT * FROM #Student;
- 清理测试
GO
DROP TABLE #Student;
DROP TABLE #Subject;
DROP TABLE #TeacherClass;
在清理之前,您必须放置代码以填充真实的表格。