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

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 使用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
目录
相关文章
|
2月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
47 1
|
20天前
|
SQL 存储 缓存
SQL Server 数据太多如何优化
11种优化方案供你参考,优化 SQL Server 数据库性能得从多个方面着手,包括硬件配置、数据库结构、查询优化、索引管理、分区分表、并行处理等。通过合理的索引、查询优化、数据分区等技术,可以在数据量增大时保持较好的性能。同时,定期进行数据库维护和清理,保证数据库高效运行。
|
1月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
1月前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
1月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言
|
1月前
|
SQL 监控 数据处理
SQL数据库数据修改操作详解
数据库是现代信息系统的重要组成部分,其中SQL(StructuredQueryLanguage)是管理和处理数据库的重要工具之一。在日常的业务运营过程中,数据的准确性和及时性对企业来说至关重要,这就需要掌握如何在数据库中正确地进行数据修改操作。本文将详细介绍在SQL数据库中如何修改数据,帮助读者更好
235 4
|
1月前
|
SQL 关系型数据库 MySQL
SQL批量插入测试数据的几种方法?
SQL批量插入测试数据的几种方法?
95 1
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
87 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
40 0
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
48 0
下一篇
无影云桌面