在最近的一个项目中,有一个需求就是要查询数据库中前几个月的历史数据,但是由于自己考虑不全面造成了程序的bug,现在将这一块好好作一个总结,希望以后不再犯这种很低级的错误,首先贴出查询中用到的一个子函数,然后就此作出详细的分析:

 private string AddMonths(string originalTime, int months)
{
string returnString = string.Empty;
string[] dataAndTime = originalTime.Split(new char[] { ' ' });
if (dataAndTime.Length > 0)
{
string date = "";
if (!string.IsNullOrWhiteSpace(dataAndTime[0]))
{
date = dataAndTime[0];
string[] yearMonthDay = date.Split(new char[] { '/' });
int year = int.Parse(yearMonthDay[0]);
int month = int.Parse(yearMonthDay[1]);
int day = int.Parse(yearMonthDay[2]);
if (months != 0)
{
if (month > months)
{
month = month - months;
//判断该月总共有多少天
int days = DateTime.DaysInMonth(year, month);
if (day > days)
day = days;
returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1];
}
if (month ==months)
{
month = 12;
year = year - 1;
int days = DateTime.DaysInMonth(year, month);
if (day > days)
day = days;
returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1]; }
if (month < months)
{
month = month + 12 - months;
year = year - 1;
int days = DateTime.DaysInMonth(year, month);
if (day > days)
day = days;
returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1];
}
}
else
{
returnString = originalTime;
}
}
}
return returnString;
}

  这个函数中有两个参数,第一个originalTime代表的是从数据库中查询到的最近的日期,第二个参数就是months,表示从最近日期往前推多少个月,在我们的程序中首先通过分割字符串的方式来获取当前的年月日,就我们当前的月份month和查询周期months作比较,第一种情况就是当前月份大于查询周期,这种情况获取的最后月份就是month和months作差,在这里年不需要变化,但是必须注意到的一点是day的取值,举个例子从数据库中查询到的当前刚好是12月31号,此时如果查询周期为6个月,直接返回差值6月31号的话程序必然会出错,因为6月份没有31号,这点必须引起重视,所以我们在程序中才有了如下的判断,  

int days = DateTime.DaysInMonth(year, month)

if (day > days)

day = days;

   这里面有个函数DateTime.DaysInMonth(year, month)这个函数是用来判断某一年某一月总共有多少天,如果当前日期天数超过了查询后的日期当月的天数那么只能取当月的最大天数了,就像12月31号往前推6个月一定是6月30号而不是6月31号,这些简单的逻辑问题一定不能出错,这个是需要特别注意的。根据month和months的关系必须分三种情况来讨论,即:month>months和month=months以及month<months三种情况进行讨论一种都不能少,总之返回的日期必须合理年,月份必须在1到12之间,返回的天必须在当月的合理范围内,这个需要在写代码的时候十分注意,并及时作出总结,并未以后吸取经验和教训。

从Oracle数据库中查询前几个月数据时需要注意的一些问题的更多相关文章

  1. 两种方法将oracle数据库中的一张表的数据导入到另外一个oracle数据库中

    oracle数据库实现一张表的数据导入到另外一个数据库的表中的方法有很多,在这介绍两个. 第一种,把oracle查询的数据导出为sql文件,执行sql文件里的insert语句,如下: 第一步,导出sq ...

  2. 一个简单的批量更新oracle 数据库中 最近的服务商名称的数据

    有一个需求是这样的,我们需要更新数据库中的数据,数据时这样的 1.大约50万以上 2. 数据中有较多的重复数据 3. 需要将表中最近的代理商的名称赋值给行中的服务商名称 4. 代理商的名称可能有多个, ...

  3. oracle数据库只查询前n条

    select * from  (select * from   tablename order by createdate desc)  aaa -- 按创建时间倒排序 where rownum &l ...

  4. 从Oracle数据库中查询与某一时间点最接近的记录

    select * from data_taskregionschedule WHERE regioncode='HYL' and updatetime-to_date('2018-05-15','yy ...

  5. SQL Server 从数据库中查询去年的今天的数据的sql语句

    因为最近的项目的一个小功能需要实现当前数据和历史的今天做一个对比.在网上也查了很久,很多都是实现一个月内的,一年内的所有数据,昨晚突然就找到了下面的实现方法,在SQL Server2008中试了一下, ...

  6. 从mysql数据库中查询最新的一条数据的方法

    第一种方法 SELECT * from a where id = (SELECT max(id) FROM a); 第二种方法: select * FROM 表名 ORDER BY id DESC L ...

  7. Oracle数据库中有关记录个数的查询

    一.查询表中全部的记录个数 可用两种方法,一种是在oracle的系统表中统计,另一种需要写存储过程统计,方法分别如下. 1.系统表中统计: SELECT sum(num_rows) FROM user ...

  8. Oracle数据库中字段定义为Char类型,Hibernate用该字段进行动态绑定参数查询,获取不到结果的问题

    一.问题背景 产生环境:oracle数据库,hibernate操作 定义了一个表 create table STORE_INFORMATION ( id CHAR(32) not null, name ...

  9. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

随机推荐

  1. 【适合核显电脑的环境配置】Tensorflow教程-Windows 10下安装tensorflow CPU with Anaconda

    安装TensorFlow 1.5.0 CPU版本 :仅支持CPU的TensorFlow. 如果您的系统没有NVIDIA GPU,则必须安装此版本. 1.首先下载和安装Anaconda TensorFl ...

  2. ASP.Net Web API 输出缓存 转载 -- Output caching in ASP.NET Web API

    一.Nuget安装相关dll Web API 2 : Install-Package Strathweb.CacheOutput.WebApi2 Web API 1 : Install-Package ...

  3. 第5章 Java中的锁

    5.1 Lock接口 并发编程安全性需要使用到锁,synchronized是一种隐式的获得与释放锁的关键字,除此之外还有Lock接口及其实现类,该接口及实现类提供了显示获取和释放锁的方式. 除了上述编 ...

  4. masm的调试命令(debug)

    -u命令:查看汇编代码: -t命令:执行下一条语句 -g + 的内存:跳转到该内存所对应的语句(再用t命令执行该条命令) -r命令:查看寄存器的内容(后可直接接寄存器的名称,就只查看该寄存器的内容) ...

  5. truffle框架的简单使用

    truffle 给大家介绍一下这个框架怎么使用,其实把这个框架就是你们看我之前有一个教程是教你们怎么用remix-ide来连接私有链,编译,配置合约,然后进行调用的,truffle其实就是把这个步骤放 ...

  6. hadoop学习笔记肆--元数据管理机制

    1.首先,认识几个名词 (1).NameNode中读.写.以及DataNode映射等信息叫做“元数据” ,NameNode元数据存放位置有.内存.fsimage.edits log三个位置. (2). ...

  7. jacoco+ant安装部署篇(统计代码覆盖率,适用自动化测试)

    1:什么是jacoco? JaCoCo是一个开源的覆盖率工具(官网地址:http://www.eclemma.org/JaCoCo/),它针对的开发语言是java,其使用方法很灵活,可以嵌入到Ant. ...

  8. vue是一个渐进式的框架,如何理解“渐进式”

    每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式.使用vue,你可以在原有大系统的上面,把一两个组件改用它实现 ...

  9. display:inline-block 来解决盒子高度不一样,造成的盒子浮动

    <style> ul{ width: 320px; //给父元素添加这两个属性 font-size: 0px; text-align: center/left; } li{ width: ...

  10. 浅谈一类无关序列有前缀和性质的统计问题的离线解法 BZOJ3626

    每次询问[l,r]区间,但所有信息是按另一种序列给出的,因此无法使用区间数据结构做这种题.将每个询问改为[1,x],考虑离线,则从1~n依次修改并查询即可. BZOJ3626 给定一颗树,每次询问给定 ...