【问题标题】:How do I validate SQL tables data using a schema如何使用架构验证 SQL 表数据
【发布时间】:2017-09-07 20:22:24
【问题描述】:

我的理解力很差,所以真的需要一个地方开始寻找信息。

我有 4 个 SQL 数据表。我想将它们全部输出到一个 XML 文件中。

我有一个 XML Schema 可以使用,但不知道如何使用它或应该在哪里使用它。

长期目标是拥有 30 个交接表,我们可以针对这些表运行验证脚本,然后使用给定的 XML 方案生成 1 个用于提交的 XML 文件。

我是这里的新手,边走边学,如果有任何建议可以在哪里寻找,我们将不胜感激。

示例 XML 数据

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2013 rel. 2 sp2 (http://www.altova.com)-->
-<MSDS:MSDS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:MSDS="http://www.datadictionary.nhs.uk/messages/MSDS-v1-0" xsi:schemaLocation="http://www.datadictionary.nhs.uk/messages/MSDS-v1-0 ../Schemas/MSDSMSDS_XMLSchema-v1-0.xsd">

-<MATHDRHeader>

<Version>1.0</Version>
<OrgCodeProv>5BC</OrgCodeProv>
<OrgCodeSubmitter>YEA</OrgCodeSubmitter>
<RPStartDate>2013-01-01</RPStartDate>
<RPEndDate>2013-03-12</RPEndDate>
<FileCreationDateTime>2013-03-13T13:00:27</FileCreationDateTime>
<RecordCount>1</RecordCount>


-<MAT001MothersDemographics>

<LocalPatientIdMother>112552254</LocalPatientIdMother>
<OrgCodeLocalPatientIdMother>5BC</OrgCodeLocalPatientIdMother>
<OrgCodeRes>5BC</OrgCodeRes>
<NHSNumberMother>1111111111</NHSNumberMother>
<NHSNumberStatusMother>01</NHSNumberStatusMother>
<PersonBirthDateMother>1982-01-05</PersonBirthDateMother>
<Postcode>LS1 4HY</Postcode>
<EthnicCategoryMother>99</EthnicCategoryMother>
<PersonDeathDateTimeMother>1900-01-01T00:00:00</PersonDeathDateTimeMother>


-<MAT003GPPracticeRegistration>

<LocalPatientIdMother>112552254</LocalPatientIdMother>
<OrgCodeGMPMother>4RT</OrgCodeGMPMother>
<StartDateGMPRegistration>2012-01-06</StartDateGMPRegistration>
<EndDateGMPRegistration>1900-01-01</EndDateGMPRegistration>
<OrgCodeCommissioner>6TY</OrgCodeCommissioner>
</MAT003GPPracticeRegistration>


-<MAT101BookingAppointmentDetails>

<AntenatalAppDate>2013-03-01</AntenatalAppDate>
<LocalPatientIdMother>112552254</LocalPatientIdMother>
<EDDAgreed>2013-05-01</EDDAgreed>
<EDDMethodAgreed>01</EDDMethodAgreed>
<PregnancyFirstContactDate>2013-11-11</PregnancyFirstContactDate>
<PregnancyFirstContactCareProfessionalType>060</PregnancyFirstContactCareProfessionalType>
<LastMenstrualPeriodDate>2012-10-01</LastMenstrualPeriodDate>
<PhysicalDisabilityStatusIndMother>Y</PhysicalDisabilityStatusIndMother>
<FirstLanguageEnglishIndMother>Y</FirstLanguageEnglishIndMother>
<EmploymentStatusMother>04</EmploymentStatusMother>
<SupportStatusMother>Y</SupportStatusMother>
<EmploymentStatusPartner>06</EmploymentStatusPartner>
<PreviousCaesareanSections>0</PreviousCaesareanSections>
<PreviousLiveBirths>0</PreviousLiveBirths>
<PreviousStillBirths>0</PreviousStillBirths>
<PreviousLossesLessThan24Weeks>0</PreviousLossesLessThan24Weeks>
<SubstanceUseStatus>01</SubstanceUseStatus>
<SmokingStatus>03</SmokingStatus>
<CigarettesPerDay>0</CigarettesPerDay>
<AlcoholUnitsPerWeek>0</AlcoholUnitsPerWeek>
<FolicAcidSupplement>03</FolicAcidSupplement>
<MHPredictionDetectionIndMother>N</MHPredictionDetectionIndMother>
<PersonWeight>75.0</PersonWeight>
<PersonHeight>1.45</PersonHeight>
<ComplexSocialFactorsInd>N</ComplexSocialFactorsInd>

</MAT101BookingAppointmentDetails>

</MATHDRHeader>

</MSDS:MSDS>

XDS 示例

 <xs:complexType name="MSDSMAT001MothersDemographicsType">
      <xs:sequence>
         <xs:element name="LocalPatientIdMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>LOCAL PATIENT IDENTIFIER (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="OrgCodeLocalPatientIdMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>ORGANISATION CODE (LOCAL PATIENT IDENTIFIER (MOTHER))</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="OrgCodeRes" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>ORGANISATION CODE (RESIDENCE RESPONSIBILITY)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="NHSNumberMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>NHS NUMBER (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="NHSNumberStatusMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>NHS NUMBER STATUS INDICATOR CODE (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="PersonBirthDateMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>PERSON BIRTH DATE (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="Postcode" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>POSTCODE OF USUAL ADDRESS (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="EthnicCategoryMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>ETHNIC CATEGORY (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="PersonDeathDateTimeMother" type="ST" minOccurs="0" maxOccurs="1">
            <xs:annotation>
               <xs:appinfo>PERSON DEATH DATE TIME (MOTHER)</xs:appinfo>
            </xs:annotation>
         </xs:element>
         <xs:element name="MAT003GPPracticeRegistration" type="MSDSMAT003GPPracticeRegistrationType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT101BookingAppointmentDetails"
                     type="MSDSMAT101BookingAppointmentDetailsType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT112DatingScanProcedure" type="MSDSMAT112DatingScanProcedureType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT201BloodGroupRhesusTest" type="MSDSMAT201BloodGroupRhesusTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT203RubellaSusceptibilityTest"
                     type="MSDSMAT203RubellaSusceptibilityTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT205HepatitisBScreeningTest"
                     type="MSDSMAT205HepatitisBScreeningTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT210AsymptomaticBacteriuriaScreeningOffer"
                     type="MSDSMAT210AsymptomaticBacteriuriaScreeningOfferType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT211HaemoglobinopathyScreeningTest"
                     type="MSDSMAT211HaemoglobinopathyScreeningTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT301MaternityCarePlan" type="MSDSMAT301MaternityCarePlanType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT303DownsSyndromeScreeningTest"
                     type="MSDSMAT303DownsSyndromeScreeningTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT305FetalAnomalyScreeningTest"
                     type="MSDSMAT305FetalAnomalyScreeningTestType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT306AntenatalAppointment" type="MSDSMAT306AntenatalAppointmentType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT307MedicalDiag" type="MSDSMAT307MedicalDiagType" minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT309MaternityObstetricDiag" type="MSDSMAT309MaternityObstetricDiagType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT310AntenatalAdmission" type="MSDSMAT310AntenatalAdmissionType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT404LabourAndDelivery" type="MSDSMAT404LabourAndDeliveryType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT408MCI" type="MSDSMAT408MCIType" minOccurs="0" maxOccurs="unbounded"/>
         <xs:element name="MAT501FetusOutcome" type="MSDSMAT501FetusOutcomeType" minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT502BabysDemographicsAndBirthDetails"
                     type="MSDSMAT502BabysDemographicsAndBirthDetailsType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT602PostpartumDischarge" type="MSDSMAT602PostpartumDischargeType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
         <xs:element name="MAT603PostpartumReadmission" type="MSDSMAT603PostpartumReadmissionType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
      </xs:sequence>
   </xs:complexType>

【问题讨论】:

  • 请提供更多详细信息(架构、缩减样本、预期输出),可能会发现,T-SQL 是错误的语言……还有其他可用的工具/语言吗?
  • 架构长度为 77000 个字符?我听说 SSIS 是更好的方法。
  • 使用.Net,您可以-例如-从有效架构创建DataSet,然后尝试将数据加载到此架构中...在SQL Server中,架构支持相当差-数据验证
  • 恐怕数据来源于 SQL 表,正如我所说的目标是将结果集输出到 XML 文件中
  • 我的理解:有一些带有数据的数据库表,您想将它们导出为 XML(文件)。当您使用模式来获得这种轻松时,您希望某种自动化......到目前为止正确吗?每个表一个 XML 还是一个大包含所有内容怪物?

标签: sql-server xml validation sql-server-2012 schema


【解决方案1】:

看来这个太难了,因为无法在任何网站上的任何地方在线获得回复

好吧,我不能让这一切顺利通过 :-D

太难了必须讨论...一个问题是,架构以及您提供的数据不完整/无效...在您尝试缩短提供的示例数据(太好了!)您创建了无效的示例数据... 我必须先投入大量时间来了解您真正想要什么,然后建立一个 mock-up 项目。

现在我们正处于太难的中心:我没有时间做这个......这是你应该提供的东西。最好的是一个可复制的独立项目。请阅读How to ask a good SQL questionHow to create a MCVE

SQL Server 不支持内置架构检查或架构相关的自动导出。因此,我在第一条评论中告诉过你,T-SQL 可能是错误的工具......

您没有回答问题还有其他可用的工具/语言 ...

这段代码是一个非常简单的 C# 代码。它将根据模式创建数据集的内部结构,然后将给定的 XML 加载到此 DataSet 中。当 XML 不兼容时,这将失败。这可能是您的架构检查

        var ds = new System.Data.DataSet("TestSchema");
        ds.ReadXmlSchema(@"C:\SomePath\MotherSchema.xml");
        ds.ReadXml(@"C:\SomePath\MotherData.xml");

//try-catch 中的上述内容,包装在一个函数中可能足以作为模式检查
//下面的代码会将数据读入字符串以检查是否成功(完全未经测试...)

        var sb = new System.Text.StringBuilder();
        foreach (var t in ds.Tables) {
            var tbl = t as System.Data.DataTable;
            foreach (var r in tbl.Rows) {
                var rw = r as System.Data.DataRow;
                foreach (var c in tbl.Columns) {
                    var cl = c as System.Data.DataColumn;
                    sb.AppendLine(string.Format("{0}.{1}: {2}",tbl.TableName,cl.ColumnName,rw[cl].ToString()));
                }
            }
        }
        var str = sb.ToString();

最后(正如我在评论中指出的那样如果我理解正确,您根本不需要架构)我将使用 FOR XML PATH 完全按照您需要的方式创建 XML。这与您复杂的 Access 遗留代码所采用的方法大致相同:只需创建一个正确的 XML。 Access 解决方案是否反映了任何架构?可能不是……明白我的意思吗?

更新只是给你一个想法:

USE master;
GO
CREATE DATABASE TestDB;
GO
USE TestDB;
GO

--一些小数据的小表。更多列只是更多相同...

CREATE TABLE MAT001MothersDemographics(ID BIGINT, Code VARCHAR(100));
INSERT INTO MAT001MothersDemographics VALUES(1111111,'1A1')
                                           ,(222222,'2B2');

CREATE TABLE MAT003GPPracticeRegistration(ID BIGINT,MotherID BIGINT,StartDate Date);
INSERT INTO MAT003GPPracticeRegistration VALUES(1,111111,{d'2001-01-01'})
                                              ,(2,222222,{d'2002-02-02'});

--我创建了没有命名空间的内部 XML,因为它们似乎只出现在最外层的节点中......

DECLARE @MotherID BIGINT=222222;
DECLARE @innerXML XML= --without namespaces
(
SELECT '1.0' AS [MVersion]
      ,'5BC' AS [OrgCodeProv]
      ,GETDATE() AS [FileCreationDateTime]
      ,(
        SELECT ID AS LocalPatientIdMother
              ,Code AS OrgCodeLocalPatientIdMother
        FROM MAT001MothersDemographics
        WHERE ID=@MotherID
        FOR XML PATH('MAT001MothersDemographics'),TYPE
       )
      ,(
        SELECT MotherID AS LocalPatientIdMother
              ,StartDate AS StartDateGMPRegistration
        FROM MAT003GPPracticeRegistration
        WHERE MotherID=@MotherID
        FOR XML PATH('MAT003GPPracticeRegistration'),TYPE
       )
FOR XML PATH('MATHDRHeader')
);

--这将使用&lt;MSDS:MSDS&gt; 节点包装先前创建的XML

WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' AS xsi 
                  ,'http://www.datadictionary.nhs.uk/messages/MSDS-v1-0' AS MSDS
                  ,'http://www.datadictionary.nhs.uk/messages/MSDS-v1-0 ../Schemas/MSDSMSDS_XMLSchema-v1-0.xsd' AS schemaLocation)
SELECT @innerXML
FOR XML PATH('MSDS:MSDS');

--清理

GO
USE master;
GO
DROP DATABASE TestDB;
GO

这一小部分的结果看起来非常符合您的需要:

    <MSDS:MSDS xmlns:schemaLocation="http://www.datadictionary.nhs.uk/messages/MSDS-v1-0 ../Schemas/MSDSMSDS_XMLSchema-v1-0.xsd" xmlns:MSDS="http://www.datadictionary.nhs.uk/messages/MSDS-v1-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <MATHDRHeader>
        <MVersion>1.0</MVersion>
        <OrgCodeProv>5BC</OrgCodeProv>
        <FileCreationDateTime>2017-04-21T10:45:57.590</FileCreationDateTime>
        <MAT001MothersDemographics>
          <LocalPatientIdMother>222222</LocalPatientIdMother>
          <OrgCodeLocalPatientIdMother>2B2</OrgCodeLocalPatientIdMother>
        </MAT001MothersDemographics>
        <MAT003GPPracticeRegistration>
          <LocalPatientIdMother>222222</LocalPatientIdMother>
          <StartDateGMPRegistration>2002-02-02</StartDateGMPRegistration>
        </MAT003GPPracticeRegistration>
      </MATHDRHeader>
    </MSDS:MSDS>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2012-04-16
    • 2013-12-01
    • 2018-12-18
    • 2019-07-28
    • 2010-09-08
    相关资源
    最近更新 更多