使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
常常遇到需要向SQL Server插入批量数据,然后在存储过程中对这些数据进行进一步处理的情况。存储过程并没有数组、列表之类的参数类型,使用XML类型可妥善解决这个问题。
不过,SQL Server2005对标准xml的支持不足,很多地方需要特别处理。举一个例子说明一下。
这个场景是往存储过程里传递一个xml序列化了的List<Model>。
1.Model的代码如下,这是一个实体类
public class Model
{
/// <summary>
/// UIN
/// </summary>
[XmlElement("UIN")]
public long UIN { get; set; }
/// <summary>
/// 昵称
/// </summary>
[XmlElement("Name")]
public string Name { get; set; }
/// <summary>
/// 头像
/// </summary>
[XmlElement("Img")]
public string Img { get; set; }
/// <summary>
/// 访问时间
/// </summary>
[XmlElement("VisitTime")]
public DateTime VisitTime { get; set; }
}
然后我们需要将这个List<Model>序列化成一个xml的字符串。但是SQL Server对xml的命名空间识别是有问题的,.net默认的序列化会出现xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=http://www.w3.org/2001/XMLSchema
有网友给出了一个完美序列化Sql Server2005支持的xml的类(参考http://www.cnblogs.com/prime/archive/2012/10/11/SQLXML.html):
public static class DbXml
{
private static readonly XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces(); static DbXml()
{
//去掉 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Namespaces.Add(string.Empty, string.Empty);
}
/// <summary>
/// 把一个对象序列化成一个Xml字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string SerializeXml<T>(T obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, obj, Namespaces);
return Encoding.UTF8.GetString(stream.ToArray());
}
} public static T DeserializeXml<T>(string obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(obj))
{
return (T)serializer.Deserialize(reader);
}
}
}
使用的时候只需要:string xml = DbXml.SerializeXml<List<QQVisitorXml>>(list) 即可获取序列化后的xml字符串:
<?xml version="1.0"?>
<ArrayOfModel>
<Model>
<UIN>0</UIN>
<Name>name0</Name>
<Img>img0</Img>
<VisitTime>2009-07-17T00:00:00-05:00</VisitTime>
</Model>
<Model>
<UIN>1</UIN>
<Name>name1</Name>
<Img>img1</Img>
<VisitTime>2009-07-17T00:00:00-05:00</VisitTime>
</Model>
<Model>
<UIN>2</UIN>
<Name>name2</Name>
<Img>img2</Img>
<VisitTime>2009-07-17T00:00:00-05:00</VisitTime>
</Model>
</ArrayOfModel>
2.存储过程里,读取xml到一个临时表#temp里:
select c.value('(UIN)[1]','varchar(30)') as uin,
c.value('(Name)[1]','varchar(50)') as Name,
c.value('(Img)[1]','varchar(200)') as Img,
c.value('(VisitTime)[1]','datetime') as VisitTime
into #temp from @strxml.nodes('//Model') T(c) --@strxml是存储过程的xml参数
然后就可以对#temp按照普通表进行进一步处理。
我们试着执行这个存储过程。嗯?出错了?!
3.原来,XML的时间标准格式是”年-月-日T时:分:秒-时区” SQL Server2005不支持时区,所以它也不能支持xml的时间格式(倒是支持年-月-日T时:分:秒)。这个问题在SQL server 2008中得到改进,完整支持了xml的时间格式。但是我们数据库是2005,没办法,得想个办法解决。解决办法是把时间字转成字符串,然后截取 年-月-日T时:分:秒,最后再加上东八区的时区数,这样sql修正为:
select c.value('(UIN)[1]','varchar(30)') as uin,
c.value('(Name)[1]','varchar(50)') as Name,
c.value('(Img)[1]','varchar(200)') as Img,
dateadd(hour,8,convert(datetime,left(t.c.value('(VisitTime)[1]','varchar(30)'), 19),127)) as VisitTime
into #temp from @strxml.nodes('//Model') T(c) --@strxml是存储过程的xml参数
本地测试,成功!
4.放到服务器上测试,执行倒是成功了,可以一查看数据,又出问题了!服务器上插入数据表的时间,和我本地测试数据库的时间,相差8个小时!本地开发环境是windows8,服务器是windows server 2008。开发环境和服务器环境有差异,导致本地获取xml带时区,服务器不带时区。
过于依赖环境,就太危险了!果断放弃时间格式,修改Model中时间为字符串:
public class Model
{
/// <summary>
/// UIN
/// </summary>
[XmlElement("UIN")]
public long UIN { get; set; }
/// <summary>
/// 昵称
/// </summary>
[XmlElement("Name")]
public string Name { get; set; }
/// <summary>
/// 头像
/// </summary>
[XmlElement("Img")]
public string Img { get; set; }
/// <summary>
/// 访问时间
/// </summary>
[XmlIgnore] //xml序列化时跳过
public DateTime VisitTime { get; set; } [XmlElement("VisitTime")]
public string XVisitTime
{
get { return this.VisitTime.ToString("yyyy-MM-dd HH:mm:ss"); }
set { this.VisitTime = DateTime.Parse(value); }
}
}
在存储过程中把这个时间字符串转换成时间:
select c.value('(UIN)[1]','varchar(30)') as uin,
c.value('(Name)[1]','varchar(50)') as Name,
c.value('(Img)[1]','varchar(200)') as Img,
convert(datetime,c.value('(VisitTime)[1]','varchar(30)')) as VisitTime
into #temp from @strxml.nodes('//Model') T(c)
Ok。所有问题都解决了,畅快。
使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历的更多相关文章
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇 ...
- SQL Server 2008 批量插入数据时报错
前几天在SQL Server 2008同步产品数据时,总是提示二进制文本被截断的错误,但是经过检查发现数据都符合格式要求. 百思不得其解,单独插入一条条数据则可以插入,但是批量导入则报错. 批量导入代 ...
- SQL Server中批量替换数据
SQL Server数据库中批量替换数据的方法 SQL Server数据库操作中,我们可能会根据某写需要去批量替换数据,那么如何批量修改替换数据呢?本文我们就介绍这一部分内容,接下来就让我们一起来了解 ...
- SQL Server TVPs 批量插入数据
在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...
- 从TXT文本文档向Sql Server中批量导入数据
下面我们通过以下的简单的SQL语句即可实现数据的批量导入,代码如下: Bulk insert id From 'G:\文档\test.txt' With ( fieldterminator=',', ...
- 在Sql Server 2005中将主子表关系的XML文档转换成主子表“Join”形式的表
本文转载:http://www.cnblogs.com/Ricky81317/archive/2010/01/06/1640434.html 最近这段时间在Sql Server 2005下做了很多根据 ...
- SQL Server 2005 盛宴系列 经典教程
SQL Server 2005 盛宴系列 经典教程 [复制链接] 发表于 2007-3-27 14:08 | 来自 51CTO网页 [只看他] 楼主 TECHNET SQL serve ...
- 转载--SQL Server 2005的XQuery介绍
原文地址: http://bbs.51cto.com/thread-458009-1-1.html 引用: 摘要 本文介绍了SQL Server 2005能够支持的XQuery的各方面特性如FLW ...
- SQL Server 2005的XML数据修改语言(XML DML)
转:http://www.microsoft.com/china/msdn/library/data/sqlserver/XMLDML.mspx?mfr=true 作为对XQuery语言的扩展,XML ...
随机推荐
- PHP_保留两位小数而且四舍五入_保留两位小数而且不四舍五入
php保留两位小数而且四舍五入 $num = 123213.666666; echo sprintf("%.2f", $num); php保留两位小数而且不四舍五入 $num = ...
- 用python输出汉字字库
问题1:如果我们知道汉字编码范围是0x4E00到0x9FA5,怎么从十六进制的编码转成人类可读的字呢? 问题2:怎么把unicode编码的字写入文件呢,假设直接用open()的话,会提示Unicode ...
- 潜水JVM
原文地址:http://blog.jamesdbloom.com/JVMInternals.html(转载请注明出处和本文地址英文原文) 本文简要解析JVM的内部结构.下图显示了一个典型的一块JVM( ...
- 谷歌宣布Android auto目前的汽车系统汽车市场的影响
由于2007年.汽车导航产品已经得到长足的发展.其产品主要用于WinCE制.除了导航功能,通常有收音机,播放光盘.广播SD卡/U音频和视频盘,蓝牙手机,倒车后视功能.由于WinCE微软放弃系统,And ...
- 工作经常使用的SQL整理,实战篇(一)
原文:工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...
- Windows 8 应用开发 - 异步调用
原文:Windows 8 应用开发 - 异步调用 不论是桌面客户端还是Web应用通常会出现处理时间较长的操作,为了在这段时间内不影响用户与应用之间的交互体验,开发人员通常会使用异步调用技术,使 ...
- json2.js参考
json2.js使用參考 json2.js提供了json的序列化和反序列化方法,能够将一个json对象转换成json字符串,也能够将一个json字符串转换成一个json对象. <html> ...
- 活动图(Activity Diagram) - 项目分解文章
案例基础上登录用户进行操作的每个模块. 1. 员 (1) 列车顺序表 (2) 货车装卸报告(数据处理) (3) 货车装卸报告(查看) 2. 管理员 (1) password管理 (2) 查看日志 (3 ...
- Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文实现了一个后台由Spring+Mybatis+SpringMVC组成,分页采用Pag ...
- C++包括头文件<>和""差额
#include "book.h" #include<iostream.h> 在刚開始学习都会有这样的迷惑.有的程序用<>.有的却用"" ...