接纳XML向SQL Server 二〇〇七批量写入数据——一回关于XML时间格式的折腾经历

行使XML向SQL Server
二零零五批量写入数据——三遍关于XML时间格式的灾害经历

 

原文:利用XML向SQL Server
2007批量写入数据——叁遍关于XML时间格式的横祸经历

每每境遇要求向SQL
Server插入批量多少,然后在储存进程中对那个数据开始展览进一步处理的情景。存款和储蓄进程并没有数组、列表之类的参数类型,使用XML类型可安妥化解那几个难题。

而是,SQL
Server二〇〇五对标准xml的帮衬不足,很多地点要求尤其处理。举一个例子说美素佳儿下。

那一个地方是往存储进度里传递二个xml系列化了的List<Model>。

1.Model的代码如下,那是四个实体类

图片 1😉

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; }
}

图片 2😉

下一场大家要求将那一个List<Model>体系化成2个xml的字符串。不过SQL
Server对xml的命名空间识别是有题指标,.net暗中认可的连串化会现出xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema

有网络朋友给出了二个两全体系化Sql
Server二〇〇五援救的xml的类(参考http://www.cnblogs.com/prime/archive/2012/10/11/SQLXML.html):

 

图片 3😉

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);
        }
    }
}

图片 4😉

应用的时候只需求:string xml =
DbXml.SerializeXml<List<QQVisitorXml>>(list)
即可获取连串化后的xml字符串:

图片 5😉

<?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>

图片 6😉

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
Server二零零五不帮衬时区,所以它也不能够援助xml的光阴格式(倒是援助年-月-日T时:分:秒)。那几个难题在SQL
server
二〇〇八中赢得革新,完整协助了xml的大运格式。可是大家数据库是二〇〇五,不可能,得想个办法化解。化解办法是把时光字转成字符串,然后截取
年-月-日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.放到服务器上测试,执行倒是成功了,能够一查看数据,又出难点了!服务器上插入数据表的时间,和本身本地质测量试数据库的时刻,相差七个时辰!本地开发环境是windows8,服务器是windows
server
贰零零玖。开发条件和服务器环境有出入,导致本地获得xml带时区,服务器不带时区。

过火注重环境,就太危险了!果断放任时间格式,修改Model中时间为字符串:

图片 7😉

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); }
    }
}

图片 8😉

在存款和储蓄进程中把这几个日子字符串转换到时间:

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。全部标题都化解了,笑容可掬。

相关文章