【问题标题】:Moving database XML column data to new related tables将数据库 XML 列数据移动到新的相关表
【发布时间】:2017-02-02 00:22:49
【问题描述】:

基本上我有两个表,Teachertbl 主键为TeacherIDTeacherBlobtblTeacherIDTeacherTbl 相关,还有一个XML 列TeacherBLOB

TeacherBLOB XML 数据包含教师数据,例如他们的班级和学生。

表的架构如下所示:

TeacherTbl:

TeacherID int PRIMARY KEY    
-- Other columns

TeacherBlobTbl:

TeacherID int FOREIGN KEY REFERENCES TeacherTbl (TeacherID)
TeacherBlob xml

TeacherBlob 中的 XML 示例如下所示:

<Teacher>
. . .
    <TeacherClass>
        <FormRoom> Room A</FormRoom>
        <TotalStudents> 25 </TotalStudents>
        <Subject> Mathematics </Subject>
            <Student>
                <StudentName> James </StudentName>
                <StudentAge> 15 </StudentAge>
                <StudentAddress> </StudentAddress>
            </Student>
    </TeacherClass>
</Teacher>

基本上我想获得TeacherClassStudent 并将它们移动到自己的表中。我想抓取TeacherClass,它的数据到一个新表中,外键与TeacherTbl 相关。

除此之外,我还想获取与StudentClass 关联的每个Student,并将其移动到它自己的表中,并使用与TeacherClass 相关的外键。

注意:我不想将Teacher移动到自己的表中,我只关心TeacherClassStudent

它应该如下所示:

TeacherClasstbl:

TeacherClassID int PRIMARY KEY
FormRoom VARCHAR(50)
TotalStudents int
Subject VARCHAR(100)
TeacherID int FOREIGN KEY REFERENCES TeacherTbl(TeacherID)

学生:

StudentID int PRIMARY KEY
StudentName VARCHAR(50)
StudentAge int
StudentAddress VARCHAR(100)
TeacherClass int FOREIGN KEY REFERENCES TeacherClassTbl(TeacherClassID)

还值得注意的是,并非每个 XML Teacher 都会有一个关联的 TeacherClass 元素,并且该解决方案需要满足传入 TeacherBlobTbl 的新数据。

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

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

谢谢!

【问题讨论】:

  • 一个学生在多个班级的情况如何处理?您想如何分配教师 ID 和学生 ID?
  • 我可以在学生和班级之间建立一个多对多的关系。 Teacher和Student不会直接关联,Student可以通过TeacherClass获取,TeacherClass可以通过Teacher获取。
  • 我会为此使用 SQL Server 集成服务。它具有处理 xml 数据的任务,以及用于更复杂场景的纯 c# 代码

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


【解决方案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;

清理之前你必须放置你的代码来填充你的真实表格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2010-12-18
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    相关资源
    最近更新 更多