Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 搜索存储在MS SQL数据库中的XML文件_Sql Server_Xml - Fatal编程技术网

Sql server 搜索存储在MS SQL数据库中的XML文件

Sql server 搜索存储在MS SQL数据库中的XML文件,sql-server,xml,Sql Server,Xml,我有超过500000个XML文件存储在MS SQL数据库中,例如下面的数据库,它经过编辑以节省问题的空间 <?xml version="1.0"?> <PROJECTS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <APPLICATION_ID>7000518</APPLICATION_ID> <ACTIVITY&

我有超过500000个XML文件存储在MS SQL数据库中,例如下面的数据库,它经过编辑以节省问题的空间

    <?xml version="1.0"?>
    <PROJECTS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <row>
    <APPLICATION_ID>7000518</APPLICATION_ID>
    <ACTIVITY>C06</ACTIVITY>
    <ADMINISTERING_IC>RR</ADMINISTERING_IC>
    <APPLICATION_TYPE>1</APPLICATION_TYPE>
    <BUDGET_START>09/01/2009</BUDGET_START>
    <BUDGET_END>09/30/2013</BUDGET_END>
    <FULL_PROJECT_NUM>1C06RR020539-01A1</FULL_PROJECT_NUM>
    <FY>2009</FY>
    <ORG_STATE>CA</ORG_STATE>
    <ORG_ZIPCODE>900952000</ORG_ZIPCODE>
    <PIS>
    <PI>
    <PI_NAME>JONES,MARY</PI_NAME>
    <PI_ID>9876543</PI_ID>
    </PI>
    <PI>
    <PI_NAME>DOE, JOHN</PI_NAME>
    <PI_ID>1234567</PI_ID>
    </PI>
    </PIS>
    <PROJECT_TERMSX>
    <TERM>Extramural Activities</TERM>
    <TERM>Extramural Research Facilities Construction Project</TERM>
    </PROJECT_TERMSX>
    <PROJECT_TITLE>The Center for Oral/Research</PROJECT_TITLE>
    <SUPPORT_YEAR>1</SUPPORT_YEAR>
    </row>
   </PROJECTS>
但是我如何才能找到与所有XML文件相关联的数据,这些文件将DOE,JOHN作为PI,PI是PI的子节点?例如应用程序ID和预算启动等?
感谢您的帮助

XML对于归档和数据交换非常有用,但对于存储积极使用/过滤/搜索的数据来说,它是一个错误的容器。因此,我强烈建议将所有数据传输到经典的索引表中,如下所示:

注意:我将您的XML简化为每个级别的一些示例,其余部分遵循相同的方法,由您决定。声明的表变量用于模拟测试场景:

DECLARE @YourTable TABLE(ID INT IDENTITY,YourXml XML);
INSERT INTO @YourTable VALUES
('<PROJECTS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
    <APPLICATION_ID>7000518</APPLICATION_ID>
    <ACTIVITY>C06</ACTIVITY>
    <!-- more first level elements like above -->

    <!-- Here there are multiple PIs -->
    <PIS>
      <PI>
        <PI_NAME>JONES,MARY</PI_NAME>
        <PI_ID>9876543</PI_ID>
      </PI>
      <PI>
        <PI_NAME>DOE, JOHN</PI_NAME>
        <PI_ID>1234567</PI_ID>
      </PI>
    </PIS>

    <!-- Here there are multiple PROJECT_TERMS -->
    <PROJECT_TERMSX>
      <TERM>Extramural Activities</TERM>
      <TERM>Extramural Research Facilities Construction Project</TERM>
    </PROJECT_TERMSX>


    <!-- These are normal first level elements again -->
    <PROJECT_TITLE>The Center for Oral/Research</PROJECT_TITLE>
    <SUPPORT_YEAR>1</SUPPORT_YEAR>
  </row>
</PROJECTS>');
-此选择从项目中读取并将所有相关PI数据存储在另一个临时表PIs中

-条件相同

-这是临时表的内容

SELECT * FROM #Projects;
SELECT * FROM #PIs;
SELECT * FROM #Terms;

--Clean up
GO
DROP TABLE #Projects;
DROP TABLE #PIs;
DROP TABLE #Terms;
在清理之前,您将输入一些代码,将您的数据从这些暂存表写入实际表。定义关系的ID与数据一起存储。这应该很容易。您将需要插入或合并,这取决于您是否必须处理现有数据

暗示
您可能会考虑项目和PI以及项目和术语之间的m:n关系。为此,您需要编写一个单独的PI表和一个单独的Term表,在这两个表之间有一个映射表,其中包含应用程序的id和第二个id,这两个id都是外键

所有XML的结构是否相同?您的代码看起来像是在使用真正的XML数据类型,但您的示例以?这是存储为字符串的数据类型吗?或者你是从文件中读到的?您是否总是在寻找要筛选的相同信息,或者是否需要从内部获取任何信息?乍一看,我建议在索引边列中写入一些值。也许把所有的数据都写到一个普通的表中?所有的XML文件都是相同的结构。数据类型是XML。我将得到的XML数据文件解析为不同的文件,其中包含大约100K条记录。如果有更好的方法,我愿意接受建议。我应该将所有内容解析到普通表中吗?我希望它能找到与PI关联的记录,然后将它们解析成表。我不需要所有的10万条记录,但在搜索之前我不知道是哪一条
SELECT r.value('(APPLICATION_ID/text())[1]','bigint') AS APPLICATION_ID
      ,r.value('(ACTIVITY/text())[1]','nvarchar(max)') AS ACTIVITY
      --more columns like above
      ,r.query('PIS') AS AllPis
      ,r.query('PROJECT_TERMSX') AS AllProjectTerms
      --more first level columns
INTO #Projects
FROM @YourTable AS t
OUTER APPLY t.YourXml.nodes('/PROJECTS/row') AS A(r);
SELECT APPLICATION_ID
      ,p.value('(PI_ID/text())[1]','bigint') AS PI_ID
      ,p.value('(PI_NAME/text())[1]','nvarchar(max)') AS PI_NAME
INTO #PIs
FROM #Projects AS p
OUTER APPLY p.AllPis.nodes('PIS/PI') AS A(p); 
SELECT APPLICATION_ID
      ,t.value('(./text())[1]','nvarchar(max)') AS TERM
INTO #Terms
FROM #Projects AS p
OUTER APPLY p.AllProjectTerms.nodes('PROJECT_TERMSX/TERM') AS A(t); 
SELECT * FROM #Projects;
SELECT * FROM #PIs;
SELECT * FROM #Terms;

--Clean up
GO
DROP TABLE #Projects;
DROP TABLE #PIs;
DROP TABLE #Terms;