将数据库XML列数据移动到新的相关表

时间:2017-02-02 00:22:49

标签: c# sql-server xml database stored-procedures

基本上我有两个表,Teachertbl的主键为TeacherIDTeacherBlobtbl的{​​{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移到自己的表格中,我只关心TeacherTeacherClass

它应该类似于以下内容:

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的新数据

请告诉我可用于实现此目的的任何工具/技术。

我考虑过制作一个按计划运行的存储过程,不确定是否有更好的解决方案。

谢谢!

1 个答案:

答案 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;

清理之前,您必须放置代码以填充真实的表格。