sql server导出查询结果到xml文件到硬盘

时间:2022-12-27 23:43:00
sql server导出查询结果到xml文件到硬盘
本来是用程序导出的xml文件到C盘下面,现在想请教各位能不能用sql server存储过程来实现?

64 个解决方案

#1


不过有些功能纯SQL做不到
/*
SQLServer2005 XML在T-SQL查询中的典型应用

整理:fcuandy
时间:2008.11.7

前言:
    此文只讲xml数据类型及相应的一些操作方法在解决日常T-SQL编程中的一些应用,而避开xml modify,
xml schema,xml索引,命名空间等这些语法性或者生硬的一些问题(这些语法您可以查联机丛书),即此文主要
讲以xml的一些操作特性及xquery去解决编程问题.

Tags:
    xquery ,FLWOR迭带 ,sql:column ,sql:variable ,nodes ,value ,query ,xpath ,xquery function, if, 聚合函数, xs:function等

典型应用举例:
*/


--(1)
--====================================================================
--拆分
DECLARE @s VARCHAR(100)
SET @s='a,b,c,dd,ee,f,aa,a,aa,f'

--常规做法(sql2000常用),以一split函数拆分串为表类型结构,如
--SELECT * FROM dbo.split(@s,',') a
--当然,也可能是循环去拆分,或者以一输助表的identity列利用charindex等函数拿identity列值与','的位置匹配实现拆分
--这些做法,roy_88及本人以前都整理过,不再累赘,可见推荐贴。即便 是xml法,也贴过多次,下面一笔带过

--XML做法:
SELECT b.v FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a   --将字串","换换为"</r><r>"并前后拼上<r>,</r>以用来构造xml串
CROSS APPLY
    (SELECT v=t.x.value('.','VARCHAR(10)') FROM a.x.nodes('//r') AS t(x) ) b  --使用 xml.nodes函数将xml串拆分为行
/*
a
b
c
dd
ee
f
aa
a
aa
f
*/


--(2)
--====================================================================
--去重,@s中出现的元素,重复的只要一个,希望结果为 'a,b,c,dd,ee,f'
--常规做法,循环或函数,或临时表拆后distinct
--XML做法:
--a.在(1)的基础上进行

;WITH fc AS   --定义cte命名,将@s转换为一个表结构
(
    SELECT DISTINCT b.v v
            FROM
                (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
            CROSS APPLY
                (SELECT v=t.x.value('.','VARCHAR(10)') FROM a.x.nodes('//r') AS t(x) ) b
)
--对这个表利用xml方法进行行值拼接
SELECT STUFF(b.v.value('/r[1]','varchar(100)'),1,1,'')
    FROM
    (SELECT v=(SELECT ',' + v FROM fc FOR XML PATH(''),ROOT('r'),TYPE)) b
/*
a,aa,b,c,dd,ee,f
*/

--b FLWOR语句 + T-SQL组合:
SELECT STUFF(v,1,1,'') FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
CROSS APPLY
    (SELECT x=(SELECT t.x.value('.','varchar(10)') v,idx=ROW_NUMBER() OVER(ORDER BY GETDATE()) FROM a.x.nodes('//r') AS t(x) FOR XML PATH('r'),TYPE)) b --利用row_number得到唯一idx
CROSS APPLY
    (SELECT v=CAST(b.x.query('for $r in //r where count(//r[v=$r/v and idx<$r/idx])=0 return concat(",",xs:string($r/v[1]))') AS VARCHAR(MAX))) c  --类似count计数法,取得v相同的节点集idx值最小的节点,原型为:
--SELECT * FROM tb a WHERE 1>(SELECT COUNT(*) FROM tb WHERE v=a.v AND id<a.id)
/*
a ,b ,c ,dd ,ee ,aa ,f
*/


--c distinct-values
SELECT REPLACE(v,' ',',') FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
CROSS APPLY
    (SELECT CAST(a.x.query('distinct-values(//r)') AS VARCHAR(MAX)) v) b  --直接调用distinct-values函数来操作
/*
a,b,c,dd,ee,f,aa
*/


-- 导入去重, last() , position()

DECLARE   @doc  xml
SET   @doc   ='<?xml version="1.0" encoding="gb2312" ?>
<employees>
    <employee>
        <empid>e0001</empid>
        <name>萧峰</name>
    </employee>
    <employee>
        <empid>e0002</empid>
        <name>段誉</name>
    </employee>
    <employee>
        <empid>e0003</empid>
        <name>王语嫣</name>
    </employee>
    <employee>
        <empid>e0003</empid>
        <name>张无忌</name>
    </employee>
</employees>
'
create table people2 

    personid varchar(10)  primary key ,
    name varchar(20) 
)

INSERT people2
SELECT DISTINCT b.* FROM
    (SELECT x = @doc.query('for $e in //employee  return  //employee[empid = $e/empid][last()]')) a  --FLWOR时,用当前节点去//emploee节点集中找节点集中empid等于当前节点的empid, 在找到的集合中取最后一个利用last()函数
CROSS APPLY
    (SELECT id=t.x.value('empid[1]','varchar(100)'),name=t.x.value('name[1]','varchar(100)') FROM a.x.nodes('//employee') AS t(x)) b

SELECT * FROM people2
/*
e0001    萧峰
e0002    段誉
e0003    张无忌
*/
GO
drop table people2 
GO
--同组一选多,也可应用此方法,不过没有必要,就不再累赘了。


--(3)
--====================================================================
--列名,列值相关
--a,按行聚合
declare @t table(Sname nvarchar(5),  V1 float,    V2 float,    V3 float,      V4 float,    V5 float,      V6 float) 
insert @t select N'张三',    0.11 , 0.21 , 0.29,  0.32 ,   0.11,    0.08 
insert @t select N'李四',    0.01 , 0.61 , 0.21,  0.73 ,   0.21,    0.12 
insert @t select N'张五',    0.31 , 0.21 , 0.23,  0.33 ,   0.91,    0.65 
insert @t select N'张六',    0.59 , 0.11,  0.26,  0.13,    0.01,    0.15 

select b.* from
    (select x=cast((select * from @t for xml path('r')) as xml)) a
cross apply
    (
        select name=x.query('./Sname/text()'),v=x.query('max(./*[local-name(.)!="Sname"])') from a.x.nodes('//r') as t(x)  
        --r为二级节点(因为文档本身无根节点,即为每项的*节点)即为一个r节点表示一条记录. r下级节点,每个表示一个列,因为列名未知,所以用/*匹配所有节点,因为name为区别列,不参与聚合运算,故用local-name取得来过滤
    ) b

/*
张三    0.32
李四    0.73
张五    0.91
张六    0.59
*/

--b ,由值引到取列
if not object_id('T1') is null
    drop table T1
GO
Create table T1([tId] int,[tName] nvarchar(4))
Insert T1
select 1,N'zhao' union all
select 2,N'qian' union all
select 3,N'sun'
Go
--> --> 借且(Roy)生成測試數據

if not object_id('T2') is null
    drop table T2
Go
Create table T2([tId] int,[zhao] nvarchar(1),[qian] nvarchar(1),[sun] nvarchar(1))
Insert T2
select 1,N'a',N'b',N'c' union all
select 2,N'd',N'e',N'f' union all
select 3,N'g',N'h',N'i'
Go


SELECT c.tid,c.tName,v FROM t1 c
CROSS APPLY
    (SELECT x=(SELECT * FROM t2 WHERE tid=c.tid FOR XML PATH('r'),TYPE)) a
CROSS APPLY
    (SELECT v=t.x.query('./*[local-name(.)=xs:string(sql:column("c.tName")) ]/text()') 
        FROM a.x.nodes('//r') AS t(x)
    ) b

/*
1    zhao    a
2    qian    e
3    sun    i
*/


--c, 列名,列值,与系统表 

CREATE TABLE tb(f1 INT,f2 INT,x INT,z INT,d INT,ex INT,dd INT,vv INT) 
INSERT tb SELECT 1,2,3,5,11,3,2423,33 
GO 
SELECT * FROM tb 
GO 
SELECT name,v FROM
  ( SELECT name FROM sys.columns WHERE object_id=object_id('tb','u') ) a 
CROSS JOIN
  (SELECT x=(SELECT * FROM tb FOR XML PATH('r'),TYPE)) b 
CROSS APPLY
(SELECT v=t.x.query('./*[local-name(.)=xs:string(sql:column("a.name")) ]/text()') FROM b.x.nodes('//r') AS t(x) ) c 
/*
f1    1
f2    2
x    3
z    5
d    11
ex    3
dd    2423
vv    33
*/
GO 
DROP TABLE tb
GO

--(4)
--一些综合计算
--以下表 ta.a值 yyyymmdd-yyyymmdd表连续时间段,","表单个日期
If object_id('ta','u') is not null 
    Drop table ta
Go
Create table ta(a varchar(100))
Go
Insert into ta
select '1 | |20080101-20080911' 
union all
select '2 | |20080101,20080201,20080301,20080515,20080808'
union all
select '3 | |20080101,20080201,20080301,20080515,20081108'
Go

declare @s varchar(8)
select @s= convert(varchar(8),getdate(),112)

select stuff(replace(replace(cast(x as varchar(1000)),'</item><item>',case when type='1' then '-' else ',' end),'</item>',''),1,6,type + ' | |') a
    from
    (
        select left(a,1) type, 
            cast(
                    '<item>' 
                    + 
                    replace(
                        stuff(a,1,5,''),
                        case when left(a,1)=1 then '-' else ',' end,
                        '</item><item>'
                        )
                    + 
                    '</item>'
                AS XML
                ) x
        from ta
    ) base

    where x.value('
            if (sql:column("base.type")="1") then
                if(
                    (/item/text())[1]<sql:variable("@s")
                    and
                    (/item/text())[2]>sql:variable("@s")
                )
                then 1
                else 0
            else
                count(//item[text()>sql:variable("@s")])
            '
            ,
            'int'
            )>0
go

#2


引用 1 楼 DBA_Huangzj 的回复:
不过有些功能纯SQL做不到
go[/code]

能把大部分的前台sql语句搬到存储过程里面就可以,创建文件那些可以不用也行。谢谢

#3


select * from tb for xml auto这是最简单的

#4


引用 3 楼 DBA_Huangzj 的回复:
select * from tb for xml auto这是最简单的

大哥你好像没回答我的问题嘛,我是想把某一个查询结果生成如下格式
其中的data customerIDType  CustomerID Code是我的查询列值,其他的是XML的固定格式。

#5


大哥你好像没回答我的问题嘛,我是想把某一个查询结果生成如下格式
sql server导出查询结果到xml文件到硬盘
其中的data customerIDType  CustomerID Code是我的查询列值,其他的是XML的固定格式。

#6


以前用FOR XML拼出来过,但是后来越来越多的信息,只能用C#搞

#7


引用 6 楼 DBA_Huangzj 的回复:
以前用FOR XML拼出来过,但是后来越来越多的信息,只能用C#搞

你教我用for xml拼下嘛哥,给我写个简单点的例子。

#8


你的原数据怎么样子的?

#9


引用 8 楼 DBA_Huangzj 的回复:
你的原数据怎么样子的?

我只有程序没有数据,看不到数据在哪个服务器上的。
sql server导出查询结果到xml文件到硬盘
图上,绿色的是固定的,黄色的从表1查询出来,紫色从表2查询出来(多行)。

#10


没有数据我很难帮你调,你看看这个例子:
SELECT Customer.custid AS [@custid], 
 Customer.companyname AS [companyname] 
FROM Sales.Customers AS Customer 
WHERE Customer.custid <= 2 
ORDER BY Customer.custid 
FOR XML PATH ('Customer'), ROOT('Customers');

结果:
<Customers> 
  <Customer custid="1"> 
    <companyname>Customer NRZBB</companyname> 
  </Customer> 
  <Customer custid="2"> 
    <companyname>Customer MLTDN</companyname> 
  </Customer> 
</Customers>

#11


引用 10 楼 DBA_Huangzj 的回复:
没有数据我很难帮你调,你看看这个例子:
</Customers>

你随便帮我建两个表,随便insert点数据进去就可以了

#12




CREATE TABLE [Sales].[Customers](
[custid] [int] IDENTITY(1,1) NOT NULL,
[companyname] [nvarchar](40) NOT NULL,
[contactname] [nvarchar](30) NOT NULL,
[contacttitle] [nvarchar](30) NOT NULL,
[address] [nvarchar](60) NOT NULL,
[city] [nvarchar](15) NOT NULL,
[region] [nvarchar](15) NULL,
[postalcode] [nvarchar](10) NULL,
[country] [nvarchar](15) NOT NULL,
[phone] [nvarchar](24) NOT NULL,
[fax] [nvarchar](24) NULL,
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED 
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


SET IDENTITY_INSERT Sales.Customers ON;
INSERT INTO Sales.Customers(custid, companyname, contactname, contacttitle, address, city, region, postalcode, country, phone, fax)
  VALUES(1, N'Customer NRZBB', N'Allen, Michael', N'Sales Representative', N'Obere Str. 0123', N'Berlin', NULL, N'10092', N'Germany', N'030-3456789', N'030-0123456');
INSERT INTO Sales.Customers(custid, companyname, contactname, contacttitle, address, city, region, postalcode, country, phone, fax)
  VALUES(2, N'Customer MLTDN', N'Hassall, Mark', N'Owner', N'Avda. de la Constitución 5678', N'México D.F.', NULL, N'10077', N'Mexico', N'(5) 789-0123', N'(5) 456-7890');

SET IDENTITY_INSERT Sales.Customers OFF;

#13


执行10楼的代码

#14


sql server导出查询结果到xml文件到硬盘救命啊

#15


sql server导出查询结果到xml文件到硬盘不合适吗?

#16


引用 15 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘不合适吗?

sql server导出查询结果到xml文件到硬盘
我要生成这种格式的啊.要不要数据?现在可以给你了

#17


拿来吧,我私信你,发我邮箱

#18


引用 17 楼 DBA_Huangzj 的回复:
拿来吧,我私信你,发我邮箱

好,我写好发你邮箱.

#19


引用 17 楼 DBA_Huangzj 的回复:
拿来吧,我私信你,发我邮箱

已发,请查收,谢谢亲。爱你 sql server导出查询结果到xml文件到硬盘

#20


你只要这部分?<DataField>
<Data UpperCorpOrderID="" Code="81206620073443503824"/>
<Data UpperCorpOrderID="" Code="81206620073443470219"/>
<Data UpperCorpOrderID="" Code="81206620073443499601"/>
</DataField>

#21


引用 20 楼 DBA_Huangzj 的回复:
你只要这部分?

我要这样的
sql server导出查询结果到xml文件到硬盘
效果

#22


引用 20 楼 DBA_Huangzj 的回复:
你只要这部分?

全部

#23


求搞                 .啊

#24


真不会搞,没这方面的经验

#25


sql server导出查询结果到xml文件到硬盘帮你问下别人,不过别太大期望

#26


引用 25 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘帮你问下别人,不过别太大期望

跪谢啊,我爱你,就像老鼠爱大米。

#27


sql server导出查询结果到xml文件到硬盘下面有请唐版主接力

#28


引用 27 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘下面有请唐版主接力

发数据给我们亲爱的版主,跪谢

#29


发了.....

#30


呵呵 ,数据好多呢,看着 sql server导出查询结果到xml文件到硬盘

#31


引用 30 楼 yupeigu 的回复:
呵呵 ,数据好多呢,看着 sql server导出查询结果到xml文件到硬盘

Excel导入嘛,或者随便弄点数据就可以。

#32


额。。。

弄不出来

#33


等版主来把。

#34


求带走啊..

#35


sql server导出查询结果到xml文件到硬盘唐大神正在努力,稍安勿躁

#36


引用 35 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神正在努力,稍安勿躁

哥,我快不行了,安慰我

#37


你自慰吧....

#38


sql server导出查询结果到xml文件到硬盘你要是让我知道没必要这样做你却非要这样做的话就等死吧你

#39


sql server导出查询结果到xml文件到硬盘大神们搞不出来的东西别期待我这平时不用开发的人写得出来

#40


引用 38 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘你要是让我知道没必要这样做你却非要这样做的话就等死吧你

真有必要啊,我要导出一大堆的xml文件。

#41


看不明白LZ的表结构,这里用自己做的测试例子,供参考.

-- 主表  yshm.mid字段为主键
create table yshm(mid int,a varchar(10),b varchar(10),c varchar(10))

-- 明细表  yshd.mid字段对应yshm.mid字段
create table yshd(mid int,d varchar(10),e varchar(10),f varchar(10))

insert into yshm
 select 1,'a1','b1','c1' union all
 select 2,'a2','b2','c2' union all
 select 3,'a3','b3','c3'

insert into yshd
 select 1,'d1','e1','f1' union all  -- 1
 select 1,'d2','e2','f2' union all
 select 2,'d3','e3','f3' union all  -- 2
 select 3,'d4','e4','f4' union all  -- 3
 select 3,'d5','e5','f5'


declare @xmldata varchar(max),@mid int,@a varchar(10),@b varchar(10),@c varchar(10),@x varchar(max),@cmd varchar(8000)

select @xmldata='<?xml version="1.0" encoding="UTF-8"?>
                 <Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
                 <Event ID="StockIn">'

declare ap scroll cursor for select mid,a,b,c from yshm

open ap
fetch first from ap into @mid,@a,@b,@c
while(@@fetch_status<>-1)
begin
  select @xmldata=@xmldata
                 +'<Bill mid="'+rtrim(@mid)+'" cola="'+@a+'" colb="'+@b+'" colc="'+@c+'" >'
                 +'<DataField>',
         @x=''
  
  select @x=@x+'<Data cold="'+d+'" e="'+e+'" f="'+f+'" />' 
   from yshd where mid=@mid
   
  select @xmldata=@xmldata+@x+'</DataField></Bill>'

 fetch next from ap into @mid,@a,@b,@c
end

close ap
deallocate ap

select @xmldata=@xmldata+'</Event></Document>'

select cast(@xmldata as xml) 'xmldata'

/*
xmldata
--------------------------------------------------------------------------------------------------------
<Document xmlns:xsi="http://www1.drugadmin.com" License="license" SN="computer" Version="3.0">
  <Event ID="StockIn">
    <Bill mid="1" cola="a1" colb="b1" colc="c1">
      <DataField>
        <Data cold="d1" e="e1" f="f1" />
        <Data cold="d2" e="e2" f="f2" />
      </DataField>
    </Bill>
    <Bill mid="2" cola="a2" colb="b2" colc="c2">
      <DataField>
        <Data cold="d3" e="e3" f="f3" />
      </DataField>
    </Bill>
    <Bill mid="3" cola="a3" colb="b3" colc="c3">
      <DataField>
        <Data cold="d4" e="e4" f="f4" />
        <Data cold="d5" e="e5" f="f5" />
      </DataField>
    </Bill>
  </Event>
</Document>

(1 row(s) affected)
*/

#42


sql server导出查询结果到xml文件到硬盘唐大神出现了

#43


牛人出现了 sql server导出查询结果到xml文件到硬盘

#44


引用 41 楼 ap0405140 的回复:
看不明白LZ的表结构,这里用自己做的测试例子,供参考.

引用 42 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神出现了

看得我好晕,几乎看不懂.

#45


sql server导出查询结果到xml文件到硬盘给你还诸多要求

#46


引用 44 楼 yangsh0722 的回复:
Quote: 引用 41 楼 ap0405140 的回复:

看不明白LZ的表结构,这里用自己做的测试例子,供参考.

引用 42 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神出现了

看得我好晕,几乎看不懂.


就是用了游标,最后把你要的那种格式的结果,给拼接了出来

#47


可以用while循环吗?

#48


引用 47 楼 yangsh0722 的回复:
可以用while循环吗?

用while实现也许比较麻烦喔,担心游标性能问题的话,可以用静态游标(cursor static).
导出xml文件的方法如下.

-- 主表  yshm.mid字段为主键
create table yshm(mid int,a varchar(10),b varchar(10),c varchar(10))
 
-- 明细表  yshd.mid字段对应yshm.mid字段
create table yshd(mid int,d varchar(10),e varchar(10),f varchar(10))

-- 中间表
create table xmltable(xmldata varchar(max))

insert into yshm
 select 1,'a1','b1','c1' union all
 select 2,'a2','b2','c2' union all
 select 3,'a3','b3','c3'
 
insert into yshd
 select 1,'d1','e1','f1' union all  -- 1
 select 1,'d2','e2','f2' union all
 select 2,'d3','e3','f3' union all  -- 2
 select 3,'d4','e4','f4' union all  -- 3
 select 3,'d5','e5','f5'


declare @xmldata varchar(max),@mid int,@a varchar(10),@b varchar(10),@c varchar(10),@x varchar(max),@cmd varchar(8000)
 
select @xmldata='<?xml version="1.0" encoding="UTF-8"?>
                 <Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
                 <Event ID="StockIn">'
 
declare ap cursor static for select mid,a,b,c from yshm
 
open ap
fetch first from ap into @mid,@a,@b,@c
while(@@fetch_status<>-1)
begin
  select @xmldata=@xmldata
                 +'<Bill mid="'+rtrim(@mid)+'" cola="'+@a+'" colb="'+@b+'" colc="'+@c+'" >'
                 +'<DataField>',
         @x=''
   
  select @x=@x+'<Data cold="'+d+'" e="'+e+'" f="'+f+'" />' 
   from yshd where mid=@mid
    
  select @xmldata=@xmldata+@x+'</DataField></Bill>'
 
 fetch next from ap into @mid,@a,@b,@c
end
 
close ap
deallocate ap
 
select @xmldata=@xmldata+'</Event></Document>'

truncate table xmltable
insert into xmltable(xmldata) values(@xmldata)

exec master..xp_cmdshell 'bcp "select cast(xmldata as xml) from DBAP.dbo.xmltable" queryout D:\yangsh.xml -S "." -U "sa" -P "001332@qq" -c -w ' 

D:\yangsh.xml 文件如下图
sql server导出查询结果到xml文件到硬盘

#49


写个类似的:


declare @xml nvarchar(max)

;with tt
as
(
select FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name,
       UpperCorpOrderID,
       Code
from
(
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443503824'
union all
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443470219'
union all
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443499601'
)t

)


select @xml = CAST(xx as nvarchar(max))
from
(
select * 
from
(
select 
       FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name,
       
       
       cast((select UpperCorpOrderID,Code
        from tt t2
        where t1.FromCorpID = t2.FromCorpID and
              t1.Actor = t2.Actor and
              t1.CorpOrderID = t2.CorpOrderID and
              t1.BillID = t2.BillID
        for xml raw('Data')--,root('')
        ) as xml) DataField
        
from tt t1
group by FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name
)a
for xml raw('Bill'),type
)b(xx)


select @xml = 
'<Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
<Event ID="StockIn">' 
              +@xml +
              '</Event></Document>'

select cast(@xml as xml) as 'dataxml'
/*
<Document xmlns:xsi="http://www1.drugadmin.com" License="license" SN="computer" Version="3.0">
  <Event ID="StockIn">
    <Bill FromCorpID="00000000000000043621" ActDate="2014-01-16 15:32:44" Actor="蔡琳" CorpOrderID="2995975" BillID="20130002995975" Name="102">
      <DataField>
        <Data UpperCorpOrderID="" Code="81206620073443503824" />
        <Data UpperCorpOrderID="" Code="81206620073443470219" />
        <Data UpperCorpOrderID="" Code="81206620073443499601" />
      </DataField>
    </Bill>
  </Event>
</Document>
*/
    

#50


恩,写得很好,我是来看帖子的

#1


不过有些功能纯SQL做不到
/*
SQLServer2005 XML在T-SQL查询中的典型应用

整理:fcuandy
时间:2008.11.7

前言:
    此文只讲xml数据类型及相应的一些操作方法在解决日常T-SQL编程中的一些应用,而避开xml modify,
xml schema,xml索引,命名空间等这些语法性或者生硬的一些问题(这些语法您可以查联机丛书),即此文主要
讲以xml的一些操作特性及xquery去解决编程问题.

Tags:
    xquery ,FLWOR迭带 ,sql:column ,sql:variable ,nodes ,value ,query ,xpath ,xquery function, if, 聚合函数, xs:function等

典型应用举例:
*/


--(1)
--====================================================================
--拆分
DECLARE @s VARCHAR(100)
SET @s='a,b,c,dd,ee,f,aa,a,aa,f'

--常规做法(sql2000常用),以一split函数拆分串为表类型结构,如
--SELECT * FROM dbo.split(@s,',') a
--当然,也可能是循环去拆分,或者以一输助表的identity列利用charindex等函数拿identity列值与','的位置匹配实现拆分
--这些做法,roy_88及本人以前都整理过,不再累赘,可见推荐贴。即便 是xml法,也贴过多次,下面一笔带过

--XML做法:
SELECT b.v FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a   --将字串","换换为"</r><r>"并前后拼上<r>,</r>以用来构造xml串
CROSS APPLY
    (SELECT v=t.x.value('.','VARCHAR(10)') FROM a.x.nodes('//r') AS t(x) ) b  --使用 xml.nodes函数将xml串拆分为行
/*
a
b
c
dd
ee
f
aa
a
aa
f
*/


--(2)
--====================================================================
--去重,@s中出现的元素,重复的只要一个,希望结果为 'a,b,c,dd,ee,f'
--常规做法,循环或函数,或临时表拆后distinct
--XML做法:
--a.在(1)的基础上进行

;WITH fc AS   --定义cte命名,将@s转换为一个表结构
(
    SELECT DISTINCT b.v v
            FROM
                (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
            CROSS APPLY
                (SELECT v=t.x.value('.','VARCHAR(10)') FROM a.x.nodes('//r') AS t(x) ) b
)
--对这个表利用xml方法进行行值拼接
SELECT STUFF(b.v.value('/r[1]','varchar(100)'),1,1,'')
    FROM
    (SELECT v=(SELECT ',' + v FROM fc FOR XML PATH(''),ROOT('r'),TYPE)) b
/*
a,aa,b,c,dd,ee,f
*/

--b FLWOR语句 + T-SQL组合:
SELECT STUFF(v,1,1,'') FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
CROSS APPLY
    (SELECT x=(SELECT t.x.value('.','varchar(10)') v,idx=ROW_NUMBER() OVER(ORDER BY GETDATE()) FROM a.x.nodes('//r') AS t(x) FOR XML PATH('r'),TYPE)) b --利用row_number得到唯一idx
CROSS APPLY
    (SELECT v=CAST(b.x.query('for $r in //r where count(//r[v=$r/v and idx<$r/idx])=0 return concat(",",xs:string($r/v[1]))') AS VARCHAR(MAX))) c  --类似count计数法,取得v相同的节点集idx值最小的节点,原型为:
--SELECT * FROM tb a WHERE 1>(SELECT COUNT(*) FROM tb WHERE v=a.v AND id<a.id)
/*
a ,b ,c ,dd ,ee ,aa ,f
*/


--c distinct-values
SELECT REPLACE(v,' ',',') FROM
    (SELECT CAST('<r>' + REPLACE(@s,',','</r><r>') + '</r>' AS XML) x) a
CROSS APPLY
    (SELECT CAST(a.x.query('distinct-values(//r)') AS VARCHAR(MAX)) v) b  --直接调用distinct-values函数来操作
/*
a,b,c,dd,ee,f,aa
*/


-- 导入去重, last() , position()

DECLARE   @doc  xml
SET   @doc   ='<?xml version="1.0" encoding="gb2312" ?>
<employees>
    <employee>
        <empid>e0001</empid>
        <name>萧峰</name>
    </employee>
    <employee>
        <empid>e0002</empid>
        <name>段誉</name>
    </employee>
    <employee>
        <empid>e0003</empid>
        <name>王语嫣</name>
    </employee>
    <employee>
        <empid>e0003</empid>
        <name>张无忌</name>
    </employee>
</employees>
'
create table people2 

    personid varchar(10)  primary key ,
    name varchar(20) 
)

INSERT people2
SELECT DISTINCT b.* FROM
    (SELECT x = @doc.query('for $e in //employee  return  //employee[empid = $e/empid][last()]')) a  --FLWOR时,用当前节点去//emploee节点集中找节点集中empid等于当前节点的empid, 在找到的集合中取最后一个利用last()函数
CROSS APPLY
    (SELECT id=t.x.value('empid[1]','varchar(100)'),name=t.x.value('name[1]','varchar(100)') FROM a.x.nodes('//employee') AS t(x)) b

SELECT * FROM people2
/*
e0001    萧峰
e0002    段誉
e0003    张无忌
*/
GO
drop table people2 
GO
--同组一选多,也可应用此方法,不过没有必要,就不再累赘了。


--(3)
--====================================================================
--列名,列值相关
--a,按行聚合
declare @t table(Sname nvarchar(5),  V1 float,    V2 float,    V3 float,      V4 float,    V5 float,      V6 float) 
insert @t select N'张三',    0.11 , 0.21 , 0.29,  0.32 ,   0.11,    0.08 
insert @t select N'李四',    0.01 , 0.61 , 0.21,  0.73 ,   0.21,    0.12 
insert @t select N'张五',    0.31 , 0.21 , 0.23,  0.33 ,   0.91,    0.65 
insert @t select N'张六',    0.59 , 0.11,  0.26,  0.13,    0.01,    0.15 

select b.* from
    (select x=cast((select * from @t for xml path('r')) as xml)) a
cross apply
    (
        select name=x.query('./Sname/text()'),v=x.query('max(./*[local-name(.)!="Sname"])') from a.x.nodes('//r') as t(x)  
        --r为二级节点(因为文档本身无根节点,即为每项的*节点)即为一个r节点表示一条记录. r下级节点,每个表示一个列,因为列名未知,所以用/*匹配所有节点,因为name为区别列,不参与聚合运算,故用local-name取得来过滤
    ) b

/*
张三    0.32
李四    0.73
张五    0.91
张六    0.59
*/

--b ,由值引到取列
if not object_id('T1') is null
    drop table T1
GO
Create table T1([tId] int,[tName] nvarchar(4))
Insert T1
select 1,N'zhao' union all
select 2,N'qian' union all
select 3,N'sun'
Go
--> --> 借且(Roy)生成測試數據

if not object_id('T2') is null
    drop table T2
Go
Create table T2([tId] int,[zhao] nvarchar(1),[qian] nvarchar(1),[sun] nvarchar(1))
Insert T2
select 1,N'a',N'b',N'c' union all
select 2,N'd',N'e',N'f' union all
select 3,N'g',N'h',N'i'
Go


SELECT c.tid,c.tName,v FROM t1 c
CROSS APPLY
    (SELECT x=(SELECT * FROM t2 WHERE tid=c.tid FOR XML PATH('r'),TYPE)) a
CROSS APPLY
    (SELECT v=t.x.query('./*[local-name(.)=xs:string(sql:column("c.tName")) ]/text()') 
        FROM a.x.nodes('//r') AS t(x)
    ) b

/*
1    zhao    a
2    qian    e
3    sun    i
*/


--c, 列名,列值,与系统表 

CREATE TABLE tb(f1 INT,f2 INT,x INT,z INT,d INT,ex INT,dd INT,vv INT) 
INSERT tb SELECT 1,2,3,5,11,3,2423,33 
GO 
SELECT * FROM tb 
GO 
SELECT name,v FROM
  ( SELECT name FROM sys.columns WHERE object_id=object_id('tb','u') ) a 
CROSS JOIN
  (SELECT x=(SELECT * FROM tb FOR XML PATH('r'),TYPE)) b 
CROSS APPLY
(SELECT v=t.x.query('./*[local-name(.)=xs:string(sql:column("a.name")) ]/text()') FROM b.x.nodes('//r') AS t(x) ) c 
/*
f1    1
f2    2
x    3
z    5
d    11
ex    3
dd    2423
vv    33
*/
GO 
DROP TABLE tb
GO

--(4)
--一些综合计算
--以下表 ta.a值 yyyymmdd-yyyymmdd表连续时间段,","表单个日期
If object_id('ta','u') is not null 
    Drop table ta
Go
Create table ta(a varchar(100))
Go
Insert into ta
select '1 | |20080101-20080911' 
union all
select '2 | |20080101,20080201,20080301,20080515,20080808'
union all
select '3 | |20080101,20080201,20080301,20080515,20081108'
Go

declare @s varchar(8)
select @s= convert(varchar(8),getdate(),112)

select stuff(replace(replace(cast(x as varchar(1000)),'</item><item>',case when type='1' then '-' else ',' end),'</item>',''),1,6,type + ' | |') a
    from
    (
        select left(a,1) type, 
            cast(
                    '<item>' 
                    + 
                    replace(
                        stuff(a,1,5,''),
                        case when left(a,1)=1 then '-' else ',' end,
                        '</item><item>'
                        )
                    + 
                    '</item>'
                AS XML
                ) x
        from ta
    ) base

    where x.value('
            if (sql:column("base.type")="1") then
                if(
                    (/item/text())[1]<sql:variable("@s")
                    and
                    (/item/text())[2]>sql:variable("@s")
                )
                then 1
                else 0
            else
                count(//item[text()>sql:variable("@s")])
            '
            ,
            'int'
            )>0
go

#2


引用 1 楼 DBA_Huangzj 的回复:
不过有些功能纯SQL做不到
go[/code]

能把大部分的前台sql语句搬到存储过程里面就可以,创建文件那些可以不用也行。谢谢

#3


select * from tb for xml auto这是最简单的

#4


引用 3 楼 DBA_Huangzj 的回复:
select * from tb for xml auto这是最简单的

大哥你好像没回答我的问题嘛,我是想把某一个查询结果生成如下格式
其中的data customerIDType  CustomerID Code是我的查询列值,其他的是XML的固定格式。

#5


大哥你好像没回答我的问题嘛,我是想把某一个查询结果生成如下格式
sql server导出查询结果到xml文件到硬盘
其中的data customerIDType  CustomerID Code是我的查询列值,其他的是XML的固定格式。

#6


以前用FOR XML拼出来过,但是后来越来越多的信息,只能用C#搞

#7


引用 6 楼 DBA_Huangzj 的回复:
以前用FOR XML拼出来过,但是后来越来越多的信息,只能用C#搞

你教我用for xml拼下嘛哥,给我写个简单点的例子。

#8


你的原数据怎么样子的?

#9


引用 8 楼 DBA_Huangzj 的回复:
你的原数据怎么样子的?

我只有程序没有数据,看不到数据在哪个服务器上的。
sql server导出查询结果到xml文件到硬盘
图上,绿色的是固定的,黄色的从表1查询出来,紫色从表2查询出来(多行)。

#10


没有数据我很难帮你调,你看看这个例子:
SELECT Customer.custid AS [@custid], 
 Customer.companyname AS [companyname] 
FROM Sales.Customers AS Customer 
WHERE Customer.custid <= 2 
ORDER BY Customer.custid 
FOR XML PATH ('Customer'), ROOT('Customers');

结果:
<Customers> 
  <Customer custid="1"> 
    <companyname>Customer NRZBB</companyname> 
  </Customer> 
  <Customer custid="2"> 
    <companyname>Customer MLTDN</companyname> 
  </Customer> 
</Customers>

#11


引用 10 楼 DBA_Huangzj 的回复:
没有数据我很难帮你调,你看看这个例子:
</Customers>

你随便帮我建两个表,随便insert点数据进去就可以了

#12




CREATE TABLE [Sales].[Customers](
[custid] [int] IDENTITY(1,1) NOT NULL,
[companyname] [nvarchar](40) NOT NULL,
[contactname] [nvarchar](30) NOT NULL,
[contacttitle] [nvarchar](30) NOT NULL,
[address] [nvarchar](60) NOT NULL,
[city] [nvarchar](15) NOT NULL,
[region] [nvarchar](15) NULL,
[postalcode] [nvarchar](10) NULL,
[country] [nvarchar](15) NOT NULL,
[phone] [nvarchar](24) NOT NULL,
[fax] [nvarchar](24) NULL,
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED 
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


SET IDENTITY_INSERT Sales.Customers ON;
INSERT INTO Sales.Customers(custid, companyname, contactname, contacttitle, address, city, region, postalcode, country, phone, fax)
  VALUES(1, N'Customer NRZBB', N'Allen, Michael', N'Sales Representative', N'Obere Str. 0123', N'Berlin', NULL, N'10092', N'Germany', N'030-3456789', N'030-0123456');
INSERT INTO Sales.Customers(custid, companyname, contactname, contacttitle, address, city, region, postalcode, country, phone, fax)
  VALUES(2, N'Customer MLTDN', N'Hassall, Mark', N'Owner', N'Avda. de la Constitución 5678', N'México D.F.', NULL, N'10077', N'Mexico', N'(5) 789-0123', N'(5) 456-7890');

SET IDENTITY_INSERT Sales.Customers OFF;

#13


执行10楼的代码

#14


sql server导出查询结果到xml文件到硬盘救命啊

#15


sql server导出查询结果到xml文件到硬盘不合适吗?

#16


引用 15 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘不合适吗?

sql server导出查询结果到xml文件到硬盘
我要生成这种格式的啊.要不要数据?现在可以给你了

#17


拿来吧,我私信你,发我邮箱

#18


引用 17 楼 DBA_Huangzj 的回复:
拿来吧,我私信你,发我邮箱

好,我写好发你邮箱.

#19


引用 17 楼 DBA_Huangzj 的回复:
拿来吧,我私信你,发我邮箱

已发,请查收,谢谢亲。爱你 sql server导出查询结果到xml文件到硬盘

#20


你只要这部分?<DataField>
<Data UpperCorpOrderID="" Code="81206620073443503824"/>
<Data UpperCorpOrderID="" Code="81206620073443470219"/>
<Data UpperCorpOrderID="" Code="81206620073443499601"/>
</DataField>

#21


引用 20 楼 DBA_Huangzj 的回复:
你只要这部分?

我要这样的
sql server导出查询结果到xml文件到硬盘
效果

#22


引用 20 楼 DBA_Huangzj 的回复:
你只要这部分?

全部

#23


求搞                 .啊

#24


真不会搞,没这方面的经验

#25


sql server导出查询结果到xml文件到硬盘帮你问下别人,不过别太大期望

#26


引用 25 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘帮你问下别人,不过别太大期望

跪谢啊,我爱你,就像老鼠爱大米。

#27


sql server导出查询结果到xml文件到硬盘下面有请唐版主接力

#28


引用 27 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘下面有请唐版主接力

发数据给我们亲爱的版主,跪谢

#29


发了.....

#30


呵呵 ,数据好多呢,看着 sql server导出查询结果到xml文件到硬盘

#31


引用 30 楼 yupeigu 的回复:
呵呵 ,数据好多呢,看着 sql server导出查询结果到xml文件到硬盘

Excel导入嘛,或者随便弄点数据就可以。

#32


额。。。

弄不出来

#33


等版主来把。

#34


求带走啊..

#35


sql server导出查询结果到xml文件到硬盘唐大神正在努力,稍安勿躁

#36


引用 35 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神正在努力,稍安勿躁

哥,我快不行了,安慰我

#37


你自慰吧....

#38


sql server导出查询结果到xml文件到硬盘你要是让我知道没必要这样做你却非要这样做的话就等死吧你

#39


sql server导出查询结果到xml文件到硬盘大神们搞不出来的东西别期待我这平时不用开发的人写得出来

#40


引用 38 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘你要是让我知道没必要这样做你却非要这样做的话就等死吧你

真有必要啊,我要导出一大堆的xml文件。

#41


看不明白LZ的表结构,这里用自己做的测试例子,供参考.

-- 主表  yshm.mid字段为主键
create table yshm(mid int,a varchar(10),b varchar(10),c varchar(10))

-- 明细表  yshd.mid字段对应yshm.mid字段
create table yshd(mid int,d varchar(10),e varchar(10),f varchar(10))

insert into yshm
 select 1,'a1','b1','c1' union all
 select 2,'a2','b2','c2' union all
 select 3,'a3','b3','c3'

insert into yshd
 select 1,'d1','e1','f1' union all  -- 1
 select 1,'d2','e2','f2' union all
 select 2,'d3','e3','f3' union all  -- 2
 select 3,'d4','e4','f4' union all  -- 3
 select 3,'d5','e5','f5'


declare @xmldata varchar(max),@mid int,@a varchar(10),@b varchar(10),@c varchar(10),@x varchar(max),@cmd varchar(8000)

select @xmldata='<?xml version="1.0" encoding="UTF-8"?>
                 <Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
                 <Event ID="StockIn">'

declare ap scroll cursor for select mid,a,b,c from yshm

open ap
fetch first from ap into @mid,@a,@b,@c
while(@@fetch_status<>-1)
begin
  select @xmldata=@xmldata
                 +'<Bill mid="'+rtrim(@mid)+'" cola="'+@a+'" colb="'+@b+'" colc="'+@c+'" >'
                 +'<DataField>',
         @x=''
  
  select @x=@x+'<Data cold="'+d+'" e="'+e+'" f="'+f+'" />' 
   from yshd where mid=@mid
   
  select @xmldata=@xmldata+@x+'</DataField></Bill>'

 fetch next from ap into @mid,@a,@b,@c
end

close ap
deallocate ap

select @xmldata=@xmldata+'</Event></Document>'

select cast(@xmldata as xml) 'xmldata'

/*
xmldata
--------------------------------------------------------------------------------------------------------
<Document xmlns:xsi="http://www1.drugadmin.com" License="license" SN="computer" Version="3.0">
  <Event ID="StockIn">
    <Bill mid="1" cola="a1" colb="b1" colc="c1">
      <DataField>
        <Data cold="d1" e="e1" f="f1" />
        <Data cold="d2" e="e2" f="f2" />
      </DataField>
    </Bill>
    <Bill mid="2" cola="a2" colb="b2" colc="c2">
      <DataField>
        <Data cold="d3" e="e3" f="f3" />
      </DataField>
    </Bill>
    <Bill mid="3" cola="a3" colb="b3" colc="c3">
      <DataField>
        <Data cold="d4" e="e4" f="f4" />
        <Data cold="d5" e="e5" f="f5" />
      </DataField>
    </Bill>
  </Event>
</Document>

(1 row(s) affected)
*/

#42


sql server导出查询结果到xml文件到硬盘唐大神出现了

#43


牛人出现了 sql server导出查询结果到xml文件到硬盘

#44


引用 41 楼 ap0405140 的回复:
看不明白LZ的表结构,这里用自己做的测试例子,供参考.

引用 42 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神出现了

看得我好晕,几乎看不懂.

#45


sql server导出查询结果到xml文件到硬盘给你还诸多要求

#46


引用 44 楼 yangsh0722 的回复:
Quote: 引用 41 楼 ap0405140 的回复:

看不明白LZ的表结构,这里用自己做的测试例子,供参考.

引用 42 楼 DBA_Huangzj 的回复:
sql server导出查询结果到xml文件到硬盘唐大神出现了

看得我好晕,几乎看不懂.


就是用了游标,最后把你要的那种格式的结果,给拼接了出来

#47


可以用while循环吗?

#48


引用 47 楼 yangsh0722 的回复:
可以用while循环吗?

用while实现也许比较麻烦喔,担心游标性能问题的话,可以用静态游标(cursor static).
导出xml文件的方法如下.

-- 主表  yshm.mid字段为主键
create table yshm(mid int,a varchar(10),b varchar(10),c varchar(10))
 
-- 明细表  yshd.mid字段对应yshm.mid字段
create table yshd(mid int,d varchar(10),e varchar(10),f varchar(10))

-- 中间表
create table xmltable(xmldata varchar(max))

insert into yshm
 select 1,'a1','b1','c1' union all
 select 2,'a2','b2','c2' union all
 select 3,'a3','b3','c3'
 
insert into yshd
 select 1,'d1','e1','f1' union all  -- 1
 select 1,'d2','e2','f2' union all
 select 2,'d3','e3','f3' union all  -- 2
 select 3,'d4','e4','f4' union all  -- 3
 select 3,'d5','e5','f5'


declare @xmldata varchar(max),@mid int,@a varchar(10),@b varchar(10),@c varchar(10),@x varchar(max),@cmd varchar(8000)
 
select @xmldata='<?xml version="1.0" encoding="UTF-8"?>
                 <Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
                 <Event ID="StockIn">'
 
declare ap cursor static for select mid,a,b,c from yshm
 
open ap
fetch first from ap into @mid,@a,@b,@c
while(@@fetch_status<>-1)
begin
  select @xmldata=@xmldata
                 +'<Bill mid="'+rtrim(@mid)+'" cola="'+@a+'" colb="'+@b+'" colc="'+@c+'" >'
                 +'<DataField>',
         @x=''
   
  select @x=@x+'<Data cold="'+d+'" e="'+e+'" f="'+f+'" />' 
   from yshd where mid=@mid
    
  select @xmldata=@xmldata+@x+'</DataField></Bill>'
 
 fetch next from ap into @mid,@a,@b,@c
end
 
close ap
deallocate ap
 
select @xmldata=@xmldata+'</Event></Document>'

truncate table xmltable
insert into xmltable(xmldata) values(@xmldata)

exec master..xp_cmdshell 'bcp "select cast(xmldata as xml) from DBAP.dbo.xmltable" queryout D:\yangsh.xml -S "." -U "sa" -P "001332@qq" -c -w ' 

D:\yangsh.xml 文件如下图
sql server导出查询结果到xml文件到硬盘

#49


写个类似的:


declare @xml nvarchar(max)

;with tt
as
(
select FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name,
       UpperCorpOrderID,
       Code
from
(
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443503824'
union all
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443470219'
union all
select FromCorpID='00000000000000043621', 
       ActDate='2014-01-16 15:32:44' ,
       Actor=N'蔡琳' ,
       CorpOrderID='2995975' ,
       BillID='20130002995975' ,
       Name='102' ,
       UpperCorpOrderID='' ,
       Code='81206620073443499601'
)t

)


select @xml = CAST(xx as nvarchar(max))
from
(
select * 
from
(
select 
       FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name,
       
       
       cast((select UpperCorpOrderID,Code
        from tt t2
        where t1.FromCorpID = t2.FromCorpID and
              t1.Actor = t2.Actor and
              t1.CorpOrderID = t2.CorpOrderID and
              t1.BillID = t2.BillID
        for xml raw('Data')--,root('')
        ) as xml) DataField
        
from tt t1
group by FromCorpID , 
       ActDate ,
       Actor  ,
       CorpOrderID ,
       BillID  ,
       Name
)a
for xml raw('Bill'),type
)b(xx)


select @xml = 
'<Document License="license" SN="computer" Version="3.0" xmlns:xsi="http://www1.drugadmin.com">
<Event ID="StockIn">' 
              +@xml +
              '</Event></Document>'

select cast(@xml as xml) as 'dataxml'
/*
<Document xmlns:xsi="http://www1.drugadmin.com" License="license" SN="computer" Version="3.0">
  <Event ID="StockIn">
    <Bill FromCorpID="00000000000000043621" ActDate="2014-01-16 15:32:44" Actor="蔡琳" CorpOrderID="2995975" BillID="20130002995975" Name="102">
      <DataField>
        <Data UpperCorpOrderID="" Code="81206620073443503824" />
        <Data UpperCorpOrderID="" Code="81206620073443470219" />
        <Data UpperCorpOrderID="" Code="81206620073443499601" />
      </DataField>
    </Bill>
  </Event>
</Document>
*/
    

#50


恩,写得很好,我是来看帖子的