我有一个People
的数据集,我希望能够将该集合插入到我的表中,但验证输入XML是否与我创建的XML SCHEMA COLLECTION
匹配。在我不使用命名空间的更简单的代码版本中,我能够实现这一点,但我希望能够使用用户定义的数据类型以及命名空间来实现。当我尝试使用下面的代码时,我得到消息2260,级别16,状态1,过程sp_InsertPerson,第16行
XQuery [nodes()]:没有名为' People'
我已经尝试了很多东西,而且还没有能够弄清楚如何实现这一目标。以下是创建存储过程的代码:
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:
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 :(得分:0)
因为我正在使用targetNamespace
,所以我需要在创建存储过程时引用命名空间。
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