2014-02-12 32 views
0

我有一個數據集People,我希望能夠將該集合插入到我的表中,但驗證輸入XML匹配我創建的XML SCHEMA COLLECTION。在我的代碼不使用名稱空間的簡單版本中,我能夠完成這個任務,但我希望能夠使用用戶定義的數據類型以及名稱空間來完成此任務。當我嘗試用下面的代碼,我得到消息2260,級別16,狀態1,過程sp_InsertPerson,行16 的XQuery [節點()]:沒有命名的元素「人」如何使用MS SQL中的名稱空間驗證XML存儲過程參數與XSD?

我已經嘗試了事情的數量,並沒有能夠找出如何做到這一點。下面是創建存儲過程的代碼:

USE [A_IndexingTest] 
GO 
CREATE PROCEDURE [dbo].[sp_InsertPerson] 
(
    @xmlData XML (dbo.PersonSchemaCollection) 
) 
AS 
BEGIN 

INSERT INTO dbo.Person 
    (LastName, FirstName, Gender, DateOfBirth, IsFriendly) 
SELECT 
    person.field.value('(FirstName)[1]', 'nvarchar(100)'), 
    person.field.value('(LastName)[1]', 'nvarchar(100)'), 
    person.field.value('(Gender)[1]', 'char(1)'), 
    person.field.value('(DateOfBirth)[1]', 'datetime'), 
    person.field.value('(IsFriendly)[1]', 'bit') 
FROM @xmlData.nodes('/People/Person') AS person(field) 

SELECT CAST(SCOPE_IDENTITY() as int) 
END 
GO 

以及創建XSD:因爲我用它似乎我需要引用命名空間當存儲的過程得到一個targetNamespace

USE [A_IndexingTest] 
GO 
CREATE XML SCHEMA COLLECTION [dbo].[PersonSchemaCollection] AS 
N' 
    <?xml version="1.0"?> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://example.org/People" 
    xmlns:tns="http://example.org/People"> 

    <xs:simpleType name="firstName"> 
     <xs:restriction base="xs:string"> 
     <xs:minLength value="1" /> 
     <xs:maxLength value="100" /> 
     </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="lastName"> 
     <xs:restriction base="xs:string"> 
     <xs:minLength value="1" /> 
     <xs:maxLength value="100" /> 
     </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="gender"> 
     <xs:restriction base="xs:string"> 
     <xs:minLength value="1" /> 
     <xs:maxLength value="1" /> 
     </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="dateOfBirth"> 
     <xs:restriction base="xs:date"> 
     </xs:restriction> 
    </xs:simpleType> 

    <xs:simpleType name="isFriendly"> 
     <xs:restriction base="xs:boolean">   
     </xs:restriction> 
    </xs:simpleType> 

    <xs:element name="People"> 
     <xs:complexType> 
     <xs:sequence> 
      <xs:element maxOccurs="unbounded" name="Person"> 
      <xs:complexType> 
       <xs:sequence> 
       <xs:element name="FirstName" type="tns:firstName" minOccurs="1" maxOccurs="1" /> 
       <xs:element name="LastName" type="tns:lastName" minOccurs="1" maxOccurs="1" /> 
       <xs:element name="Gender" type="tns:gender" minOccurs="1" maxOccurs="1" /> 
       <xs:element name="DateOfBirth" type="tns:dateOfBirth" minOccurs="1" maxOccurs="1" /> 
       <xs:element name="IsFriendly" type="tns:isFriendly" minOccurs="1" maxOccurs="1" /> 
       </xs:sequence> 
      </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema>' 
+0

旁註:['CREATE PROCEDURE'(http://technet.microsoft.com/en-us/library/ms187926.aspx):「避免使用** SP _ **前綴時命名過程這個前綴被SQL Server用來指定系統過程,如果存在一個具有相同名稱的系統過程,使用該前綴可能會導致應用程序代碼中斷。 –

+0

感謝您的評論,我之前沒有想到這一點。這是我工作的公司的一個標準,我會向高層人員提及它,但現在它不在我手中:( – akousmata

+0

我通常的建議是在任何類型的SQL對象上都沒有前綴 - 語法是這樣的你可以知道你在看什麼類型的對象,只是看它的出現位置(除了視圖和表格之外,應該正確地對待它們) –

回答

0

創建。

CREATE PROCEDURE [dbo].[sp_InsertPerson] (
    @xmlData XML (dbo.PersonSchemaCollection) 
) 
AS 
BEGIN 

-- this is the part that I was missing 
WITH XMLNAMESPACES('http://example.org/People' as tns) 

INSERT INTO dbo.Person 
    (LastName, FirstName, Gender, DateOfBirth, IsFriendly) 
SELECT 

    -- additionally note the tns prefix for all of the fields and nodes 
    person.field.value('(tns:FirstName)[1]', 'nvarchar(100)'), 
    person.field.value('(tns:LastName)[1]', 'nvarchar(100)'), 
    person.field.value('(tns:Gender)[1]', 'char(1)'), 
    person.field.value('(tns:DateOfBirth)[1]', 'datetime'), 
    person.field.value('(tns:IsFriendly)[1]', 'bit') 
FROM @xmlData.nodes('/tns:People/tns:Person') AS person(field) 

SELECT CAST(SCOPE_IDENTITY() as int) 
END 
GO 
相關問題