将xml元素内容(也是xml标记)插入SQL Server 2005中的列

时间:2012-01-04 11:32:12

标签: sql-server sql-server-2005 xquery-sql

对于下面的表格式

CREATE TABLE [dbo].[Employee](
    [EmployeeId] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Location] [nvarchar](50) NOT NULL,
    [Skills] [xml] NOT NULL,
    [Projects] [nvarchar](400) NULL,
 CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED 

在表中插入数据时,我只想插入<SkillSet>的子标记,但似乎<SkillSet>及其子元素插入到Skill xml列中。

declare @doc NVARCHAR(MAX)

declare @idoc INT

select @doc = '<Request Type="InsertEmployee" CRUD="C">
    <Employee>
      <EmployeeId>1</EmployeeId>
      <Name>Deeptechtons</Name>
      <Location>USA</Location>
        <SkillSet>
        <Skill>C#</Skill>
        <Skill>SQL Server 2005</Skill>
        <Skill>ASP.net</Skill>
        </SkillSet>
      <Projects>
        <Project>LowBin</Project>
        <Project>Maskin</Project>
      </Projects>
    </Employee>
  </Request>'

exec sp_xml_preparedocument @idoc output,@doc

insert into Employee (
                        EmployeeId
                        ,[Name]
                        ,Location
                        ,Skills,
                        Projects
                     )
            SELECT      NEWID()
                        ,[Name]
                        ,Location
                        ,Skills
                        ,Projects
            FROM OPENXML(@idoc,'Request/Employee',2)
            WITH
                    (
                        [Name] NVARCHAR(50)
                        ,Location   NVARCHAR(50)
                        ,Skills XML 'SkillSet'
                        ,Projects NVARCHAR(400)
                    )

exec sp_xml_removedocument @idoc

问题

  • 如何仅插入<Skillset>的子元素,而不是整个标记及其子元素。

  • 我预计Projects也会被插入,但只会插入第一个Project标记的Lowbin个内容。你能纠正我的代码吗?

1 个答案:

答案 0 :(得分:1)

由于您使用的是SQL Server 2005,因此您可以使用XML数据类型,而不是这样做。

declare @doc xml

select @doc = '<Request Type="InsertEmployee" CRUD="C">
    <Employee>
      <EmployeeId>1</EmployeeId>
      <Name>Deeptechtons</Name>
      <Location>USA</Location>
        <SkillSet>
        <Skill>C#</Skill>
        <Skill>SQL Server 2005</Skill>
        <Skill>ASP.net</Skill>
        </SkillSet>
      <Projects>
        <Project>LowBin</Project>
        <Project>Maskin</Project>
      </Projects>
    </Employee>
  </Request>'

insert into Employee (
                        EmployeeId
                        ,[Name]
                        ,Location
                        ,Skills,
                        Projects
                     )
select newid(),
       T.N.value('Name[1]',  'nvarchar(50)'),
       T.N.value('Location[1]',  'nvarchar(50)'),
       T.N.query('SkillSet/*'),
       cast(T.N.query('Projects/*') as nvarchar(400))
from @doc.nodes('/Request/Employee') as T(N)

结果:

BC76E37C-0C0D-4B7B-92FD-0F7807F9204B 
Deeptechtons 
USA 
<Skill>C#</Skill><Skill>SQL Server005</Skill>Skill>ASP.net</Skill>
<Project>LowBin</Project><Project>Maskin</Project>

<强>更新

如果你真的想出于某些原因使用OPENXML,可以使用它。

insert into Employee (
                        EmployeeId
                        ,[Name]
                        ,Location
                        ,Skills,
                        Projects
                     )
            SELECT      NEWID()
                        ,[Name]
                        ,Location
                        ,Skills.query('SkillSet/*')
                        ,cast(Projects.query('Projects/*') as nvarchar(max))
            FROM OPENXML(@idoc,'Request/Employee',2)
            WITH
                    (
                        [Name] NVARCHAR(50)
                        ,Location   NVARCHAR(50)
                        ,Skills XML 'SkillSet'
                        ,Projects XML
                    )