使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历   原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇到需要向SQL Server插入批量数据,然后在存储过程中对这些数据进行进一步处理的情况。

使用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。所有问题都解决了,畅快。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
4月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
55 1
|
5月前
|
XML 数据采集 存储
使用Java和XPath在XML文档中精准定位数据
在数据驱动的时代,从复杂结构中精确提取信息至关重要。XML被广泛用于数据存储与传输,而XPath则能高效地在这些文档中导航和提取数据。本文深入探讨如何使用Java和XPath精准定位XML文档中的数据,并通过小红书的实际案例进行分析。首先介绍了XML及其挑战,接着阐述了XPath的优势。然后,提出从大型XML文档中自动提取特定产品信息的需求,并通过代理IP技术、设置Cookie和User-Agent以及多线程技术来解决实际网络环境下的数据抓取问题。最后,提供了一个Java示例代码,演示如何集成这些技术以高效地从XML源中抓取数据。
212 7
使用Java和XPath在XML文档中精准定位数据
|
2月前
|
SQL 存储 缓存
SQL Server 数据太多如何优化
11种优化方案供你参考,优化 SQL Server 数据库性能得从多个方面着手,包括硬件配置、数据库结构、查询优化、索引管理、分区分表、并行处理等。通过合理的索引、查询优化、数据分区等技术,可以在数据量增大时保持较好的性能。同时,定期进行数据库维护和清理,保证数据库高效运行。
|
3月前
|
XML Web App开发 数据格式
HTML 页面显示 XML 数据
10月更文挑战第2天
|
3月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
785 0
|
4月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
79 1
|
4月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL Java 数据库连接
JDBC连接SQL Server2008 完成增加、删除、查询、修改等基本信息基本格式及示例代码
这篇文章提供了使用JDBC连接SQL Server 2008数据库进行增加、删除、查询和修改操作的基本步骤和示例代码。
|
5月前
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
167 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
5月前
|
Java 测试技术 容器
从零到英雄:Struts 2 最佳实践——你的Web应用开发超级变身指南!
【8月更文挑战第31天】《Struts 2 最佳实践:从设计到部署的全流程指南》深入介绍如何利用 Struts 2 框架从项目设计到部署的全流程。从初始化配置到采用 MVC 设计模式,再到性能优化与测试,本书详细讲解了如何构建高效、稳定的 Web 应用。通过最佳实践和代码示例,帮助读者掌握 Struts 2 的核心功能,并确保应用的安全性和可维护性。无论是在项目初期还是后期运维,本书都是不可或缺的参考指南。
62 0