存储过程导出csv文件,利用xml对csv文件内容进行批量处理

参考文章:

Bcp使用心得: http://www.cnblogs.com/puke/archive/2013/06/05/3119378.html

定时导出csv文件: http://www.dearda.com/index.php/archives/1283


导出csv文件

A  全局临时表

if OBJECT_ID('tempdb..##table') is not null
drop table ##table

/*
*	S1 创建全局临时表
*/

create table ##table(
A varchar(32),
B numeric(10,2),
C numeric(10,2),
D integer
)
/*
*	S2 插入全局临时表##table
*/
insert ##table(A,B,C,D)
select 
A,
B,
cast(0 as numeric),--强制转换成numeric
0
from tableName
where sth
group by sth
/*
*	S4 返回结果
*/

select * from ##table

---导出csv文件
EXEC master..xp_cmdshell 'bcp "select * from tempdb..##table" queryout "D:\test.csv"  -c -q -S"服务器地址" -U"用户名" -P"密码"'

注:临时表为temdb..#table ;全局临时表为tempdb.##table;此处临时表报错,需要用全局临时表


输出的csv表名设成当前日期的话 可以这样做

declare @bcp varchar(255)
set @bcp='bcp "select * from tempdb..##table" queryout "D:'+convert(char(8),GETDATE(),112)+'.csv"  -c -q -S"1.1.1" -U"sa" -P"1"'
EXEC master..xp_cmdshell @bcp
注: 此时不能设@bcp为varchar(max)
http://blog.csdn.net/imlmy/article/details/23933007


导出的csv文件在-S后面的服务器地址里面的D盘找得到


B  已经存在的表

EXEC master..xp_cmdshell 'bcp "select * from 数据库名.dbo.表名" queryout "D:\test.csv"  -c -q -S"服务器地址" -U"用户名" -P"密码"'

读取csv文件

            var filePath = @"D:\test.csv";  //判断是否有该文件
            if (!System.IO.File.Exists(filePath))
            {
                flag = false;
                return Json(new { Result = false, Message = "csv文件不存在!", Flag = flag }, JsonRequestBehavior.AllowGet);
            }

            //当有文件的时候 对csv文件内容进行处理
            FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            StreamReader sr = new StreamReader(fs, Encoding.UTF8);

            //csv中每一行的数据
            string strLine = "";
			
	    //记录每行中各字段的内容
            string[] aryLine = null; 
            IList<tableName> ioList = new List<tableName>();

            while ((strLine = sr.ReadLine()) != null)
            {
                /// TODO 需要查看下载的csv是否有标题
                aryLine = strLine.Split('\t');
                if (aryLine[2] != "0" && aryLine[2] != "0" && aryLine[3] != "0") 
                {
                    tableName IO = new tableName();
                    IO.A = aryLine[0];
                    IO.B = Convert.ToDecimal(aryLine[1]);
                    IO.C = Convert.ToDecimal(aryLine[2]);
                    IO.D = Convert.ToInt32(aryLine[3]);
                    ioList.Add(IO);
                }
              
            }
            sr.Close();
            fs.Close();

注:此处为读取本地csv文件,远程服务器上文件的读取比较复杂,需要调查一下


存储过程中对csv文件进行操作

写成xml文件形式传入存储过程

       //将List写成xml文件形式
            StringBuilder xml = new StringBuilder();
            xml.Append("<InOut>");
            foreach (var item in list)
            {
                xml.Append("<R>");
                xml.Append(string.Format("<A>" + item.AgentID + "</A>"));
                xml.Append(string.Format("<B>" + item.OpenCharge + "</B>"));
                xml.Append(string.Format("<C>" + item.CloseCharge + "</C>"));
                xml.Append(string.Format("<D>" + item.Customers + "</D>"));
                xml.Append("</R>");
            }
            xml.Append("</InOut>");
传入存储过程

/*
*	S1 创建临时表
*/
create table #table(
A varchar(32),
B numeric(10,2),
C numeric(10,2),
D integer
)

/*
*	S2 插入临时表数据
*/
--xml文件为空时返回

if(@XML is null or LEN(LTRIM(RTRIM(@XML)))=0)
RETURN

--将xml中数据插入到临时表中
declare @IdHandel int
exec sp_xml_preparedocument @IdHandel OUTPUT,@XML 

insert #table(A,B,C,D) 
select
*
from
	openxml(@IdHandel,'/InOut/R',2)
	with
	(
		A varchar(32),
		B numeric(10,2),
		C numeric(10,2),
		D integer
	) 
exec sp_xml_removedocument @IdHandel
set @totalCount=0
使用游标进行重复操作

	 --循环
	while @@FETCH_STATUS<>-1--FETCH 语句失败或此行不在结果集中
	begin
		if(@@FETCH_STATUS<>-2)--被提取的行不存在
		begin try
			begin tran --事务
				if(STH)
				 begin
					 --操作
				 end
			commit tran
		end try
		begin catch
			if(@@TRANCOUNT>0)
			begin
				rollback tran
			end
		end catch

		fetch next from Name
		into @A, @B, @C, @D
		SET @totalCount=@totalCount+1
	end





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值