oracle 日期函数介绍:
在oracle中有很多关于日期的函数,如:
1、add_months()用于从一个日期值增加或减少一些月份
date_value:=add_months(date_value,number_of_months)
例:
SQL> select add_months(sysdate,12) "Next Year" from dual;
Next Year
----------
13-11月-04
SQL> select add_months(sysdate,112) "Last Year" from dual;
Last Year
----------
13-3月 -13
SQL>
2、current_date()返回当前会放时区中的当前日期
date_value:=current_date
SQL> column sessiontimezone for a15
SQL> select sessiontimezone,current_date from dual;
SESSIONTIMEZONE CURRENT_DA
--------------- ----------
+08:00 13-11月-03
SQL> alter session set time_zone='-11:00'
2 /
会话已更改。
SQL> select sessiontimezone,current_timestamp from dual;
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00 12-11月-03 04.59.13.668000 下午 -11:
00
SQL>
3、current_timestamp()以timestamp with time zone数据类型返回当前会放时区中的当前日期
timestamp_with_time_zone_value:=current_timestamp([timestamp_precision])
SQL> column sessiontimezone for a15
SQL> column current_timestamp format a36
SQL> select sessiontimezone,current_timestamp from dual;
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
+08:00 13-11月-03 11.56.28.160000 上午 +08:
00
SQL> alter session set time_zone='-11:00'
2 /
会话已更改。
SQL> select sessiontimezone,current_timestamp from dual;
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00 12-11月-03 04.58.00.243000 下午 -11:
00
SQL>
4、dbtimezone()返回时区
varchar_value:=dbtimezone
SQL> select dbtimezone from dual;
DBTIME
------
-07:00
SQL>
5、extract()找出日期或间隔值的字段值
date_value:=extract(date_field from [datetime_value|interval_value])
SQL> select extract(month from sysdate) "This Month" from dual;
This Month
----------
11
SQL> select extract(year from add_months(sysdate,36)) "3 Years Out" from dual;
3 Years Out
-----------
2006
SQL>
6、last_day()返回包含了日期参数的月份的最后一天的日期
date_value:=last_day(date_value)
SQL> select last_day(date'2000-02-01') "Leap Yr?" from dual;
Leap Yr?
----------
29-2月 -00
SQL> select last_day(sysdate) "Last day of this month" from dual;
Last day o
----------
30-11月-03
SQL>
7、localtimestamp()返回会话中的日期和时间
timestamp_value:=localtimestamp
SQL> column localtimestamp format a28
SQL> select localtimestamp from dual;
LOCALTIMESTAMP
----------------------------
13-11月-03 12.09.15.433000
下午
SQL> select localtimestamp,current_timestamp from dual;
LOCALTIMESTAMP CURRENT_TIMESTAMP
---------------------------- ------------------------------------
13-11月-03 12.09.31.006000 13-11月-03 12.09.31.006000 下午 +08:
下午 00
根据日期计算第几周:
//计算第几周
public int GetWeekOfCurrDate(DateTime dt)
{
int Week = 1;
int nYear = dt.Year;
System.DateTime FirstDayInYear = new DateTime(nYear, 1, 1);
System.DateTime LastDayInYear = new DateTime(nYear, 12, 31);
int DaysOfYear = Convert.ToInt32(LastDayInYear.DayOfYear);
int WeekNow = Convert.ToInt32(FirstDayInYear.DayOfWeek) - 1;
if (WeekNow < 0) WeekNow = 6;
int DayAdd = 6 - WeekNow;
System.DateTime BeginDayOfWeek = new DateTime(nYear, 1, 1);
System.DateTime EndDayOfWeek = BeginDayOfWeek.AddDays(DayAdd);
Week = 2;
for (int i = DayAdd + 1; i <= DaysOfYear; i++)
{
BeginDayOfWeek = FirstDayInYear.AddDays(i);
if (i + 6 > DaysOfYear)
{
EndDayOfWeek = BeginDayOfWeek.AddDays(DaysOfYear - i - 1);
}
else
{
EndDayOfWeek = BeginDayOfWeek.AddDays(6);
}
if (dt.Month == EndDayOfWeek.Month && dt.Day <= EndDayOfWeek.Day)
{
break;
}
Week++;
i = i + 6;
}
return Week;
}
//本周是本年第几周
private int DatePart(System.DateTime dt)
{
int weeknow = Convert.ToInt32(dt.DayOfWeek);//今天星期几
int daydiff = (-1) * (weeknow+1);//今日与上周末的天数差
int days = System.DateTime.Now.AddDays(daydiff).DayOfYear;//上周末是本年第几天
int weeks = days/7;
if(days%7 != 0)
{
weeks++;
}
//此时,weeks为上周是本年的第几周
return (weeks+1);
}
//本周起止日期
private string WeekRange(System.DateTime dt)
{
int weeknow = Convert.ToInt32(dt.DayOfWeek);
int daydiff = (-1) * weeknow;
int dayadd = 6-weeknow;
string dateBegin = System.DateTime.Now.AddDays(daydiff).Date.ToString("MM月dd日");
string dateEnd = System.DateTime.Now.AddDays(dayadd).Date.ToString("MM月dd日");
return dateBegin + " - " +dateEnd;
}
获取某年指定周的开始日期和结束日期的通用方法:
获取某年指定周的开始日期和结束日期的通用方法
/**//// <summary>
/// 获取一年中指定的一周的开始日期和结束日期。开始日期遵循ISO 8601即星期一。
/// </summary>
/// <remarks>Write by vrhero</remarks>
/// <param name="year">年(1 到 9999)</param>
/// <param name="weeks">周(1 到 53)</param>
/// <param name="weekrule">确定首周的规则</param>
/// <param name="first">当此方法返回时,则包含参数 year 和 weeks 指定的周的开始日期的 System.DateTime 值;如果失败,则为 System.DateTime.MinValue。如果参数 year 或 weeks 超出有效范围,则操作失败。该参数未经初始化即被传递。</param>
/// <param name="last">当此方法返回时,则包含参数 year 和 weeks 指定的周的结束日期的 System.DateTime 值;如果失败,则为 System.DateTime.MinValue。如果参数 year 或 weeks 超出有效范围,则操作失败。该参数未经初始化即被传递。</param>
/// <returns>成功返回 true,否则为 false。</returns>
public static bool GetDaysOfWeeks(int year, int weeks, CalendarWeekRule weekrule, out DateTime first, out DateTime last)
{
//初始化 out 参数
first = DateTime.MinValue;
last = DateTime.MinValue;
//不用解释了吧
if (year < 1 | year > 9999)
return false;
//一年最多53周地球人都知道
if (weeks < 1 | weeks > 53)
return false;
//取当年首日为基准为什么?容易得呗
DateTime firstCurr = new DateTime(year, 1, 1);
//取下一年首日用于计算
DateTime firstNext = new DateTime(year + 1, 1, 1);
//将当年首日星期几转换为数字星期日特别处理ISO 8601 标准
int dayOfWeekFirst = (int)firstCurr.DayOfWeek;
if (dayOfWeekFirst == 0) dayOfWeekFirst = 7;
//得到未经验证的周首日
first = firstCurr.AddDays((weeks - 1) * 7 - dayOfWeekFirst + 1);
//周首日是上一年日期的情况
if (first.Year < year)
{
switch (weekrule)
{
case CalendarWeekRule.FirstDay:
//不用解释了吧
first = firstCurr;
break;
case CalendarWeekRule.FirstFullWeek:
//顺延一周
first = first.AddDays(7);
break;
case CalendarWeekRule.FirstFourDayWeek:
//周首日距年首日不足4天则顺延一周
if (firstCurr.Subtract(first).Days > 3)
{
first = first.AddDays(7);
}
break;
default:
break;
}
}
//得到未经验证的周末日
last = first.AddDays(7).AddSeconds(-1);
//周末日是下一年日期的情况
if (last.Year > year)
{
switch (weekrule)
{
case CalendarWeekRule.FirstDay:
last = firstNext.AddSeconds(-1);
break;
case CalendarWeekRule.FirstFullWeek:
//不用处理
break;
case CalendarWeekRule.FirstFourDayWeek:
//周末日距下一年首日不足4天则提前一周
if (firstNext.Subtract(first).Days < 4)
{
first = first.AddDays(-7);
last = last.AddDays(-7);
}
break;
default:
break;
}
}
return true;
}
关于按周统计数据:
关于按周统计数据(Oracle)
方法1:使用to_char函数
select sum(sal) ,
to_char(HIREDATE,'yyyy')||':'||to_char(HIREDATE,'IW') week_sn
from scott.emp
group by to_char(HIREDATE,'yyyy')||':'||to_char(HIREDATE,'IW');
格式'IW'返回当前日期是当年的第几周
方法2:使用next_day()函数
select sum(sal) ,
NEXT_DAY(trunc(HIREDATE),'星期一')-7 weekstart,
NEXT_DAY(trunc(HIREDATE),'星期一') weekend
from scott.emp
group by NEXT_DAY(trunc(HIREDATE),'星期一');
上面这个例子是在中文字符集下使用,如果在英文字符集下则使用:
select sum(sal) ,
NEXT_DAY(trunc(HIREDATE),'Monday')-7 weekstart,
NEXT_DAY(trunc(HIREDATE),'Monday') weekend
from scott.emp
group by NEXT_DAY(trunc(HIREDATE),'Monday');
两种方法比较,第二种方法能够方便的给出周开始和周结束日期,更方便些。
临时表:
需要创建一个临时表,请举例说明,谢谢!
---------------------------------------------------------------
是TEMPORARY
CREATE GLOBAL TEMPORARY TABLE flight_schedule (
startdate DATE,
enddate DATE,
cost NUMBER)
---------------------------------------------------------------
create proecdure name_pro
as
str varchar2(100);
begin
str:='CREATE GLOBAL TEMPORARY TABLE TABLENAME ON COMMIT PRESERVE ROWS as select * from others_table';
execute immediate str;
end;
/
可以把临时表指定为事务相关(默认)或者是会话相关:
ON COMMIT DELETE ROWS:指定临时表是事务相关的,Oracle在每次提交后截断表。
ON COMMIT PRESERVE ROWS:指定临时表是会话相关的,Oracle在会话中止后截断表。
=================
可以创建以下两种临时表:
1。会话特有的临时表
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
ON COMMIT PRESERVE ROWS;
========
对全局临时表的总结
在临时表上的操作比在一般的表上的操作要快。因为:
1创建临时表不需要往编目表中插入条目,临时表的使用也不需要访问编目表,因此也没有对编目表的争用。
2仅有创建临时表的app才可存取临时表,所以在处理临时表时没有锁。
3如果指定NOT LOGGED选项,在处理临时表时不记日志。所以如果有仅在数据库的一个会话中使用的大量临时数据,把这些数据存入临时表能大大提高性能。
DECLARE GLOBAL TEMPORARY TABLE TT(C1 INT, C2 CHAR(20));
在CONNECT RESET命令后,临时表不再存在。
建临时表是动态编译的,所以对临时表的使用也必须放在DECLARE CURSER 后面
CREATE PROCEDURE INSTT2(P1 INT, P2 CHAR(20))
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TT(C1 INT, C2 CHAR(20)) %
INSERT INTO SESSION.TT VALUES(P1, P2);
BEGIN
DECLARE C1 CURSOR WITH RETURN FOR SELECT * FROM SESSION.TT;
END;
END %
2。事务特有的临时表
CREATE GLOBAL TEMPORARY <TABLE_NAME> (<column specification>)
ON COMMIT DELETE ROWS;
在Oracle中,全局临时表并不会删除,实际上你只需要建立一次,以后直接应用就行了,这与MS和Sybase不一样。实际上在断开数据库连接时,临时表中数据自动清空,不同的Session之间是隔离的,不许要当心相互影响,不过如果起用了连接共享的话,你要用On Commit delete rows使数据仅在事物内部有效。
3建立临时表
临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效.
建立方法:
1) ON COMMIT DELETE ROWS 定义了建立事务级临时表的方法.
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT DELETE ROWS;
EXAMPLE:
SQL> CREATE GLOBAL TEMPORARY TABLE admin_work_area
2 (startdate DATE,
3 enddate DATE,
4 class CHAR(20))
5 ON COMMIT DELETE ROWS;
SQL> create table permernate( a number);
SQL> insert into admin_work_area values(sysdate,sysdate,'temperary table');
SQL> insert into permernate values(1);
SQL> commit;
SQL> select * from admin_work_area;
SQL> select * from permernate;
A
1
2)ON COMMIT PRESERVE ROWS 定义了创建会话级临时表的方法.
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT PRESERVE ROWS;
EXAMPLE:
会话1:
SQL> drop table admin_work_area;
SQL> CREATE GLOBAL TEMPORARY TABLE admin_work_area
2 (startdate DATE,
3 enddate DATE,
4 class CHAR(20))
5 ON COMMIT PRESERVE ROWS;
SQL> insert into permernate values(2);
SQL> insert into admin_work_area values(sysdate,sysdate,'session temperary');
SQL> commit;
SQL> select * from permernate;
A
----------
1
2
SQL> select * from admin_work_area;
STARTDATE ENDDATE CLASS
---------- ---------- --------------------
17-1ÔÂ -03 17-1ÔÂ -03 session temperary
会话2:
SQL> select * from permernate;
A
----------
1
2
SQL> select * from admin_work_area;
未选择行.
会话2看不见会话1中临时表的数据.
根据上面的信息实现存储过程:
CREATE OR REPLACE PACKAGE BODY TodayALL_zjz IS
--第一层主页统计信息--数据
PROCEDURE GetIndexTj(Index_OUT OUT MYCURSOR) AS
BEGIN
--单维数组
DECLARE
--
fa integer;
--
pa integer;
--
zhtf integer;
--
djclry integer;
--
kywp integer;
--
blzz integer;
--
lgzs integer;
-- mydate date;
strdate varchar(8);
strdate1 varchar(12);
strdate2 varchar(12);
begin
strdate := TO_CHAR(SYSDATE, 'YYYYMMDD');
strdate1 := TO_CHAR(SYSDATE, 'YYYYMMDD') + '0000';
strdate2 := TO_CHAR(SYSDATE + 1, 'YYYYMMDD') + '0000';
--结果1
SELECT count(*) into blzz FROM ZZRK.JB_TAB WHERE FZRQ = strdate;
--结果2
SELECT count(*)
into lgzs
FROM lgy.lgy_gnlkjbxx
WHERE RZSJ >= strdate1
and RZSJ < strdate2;
OPEN Index_OUT FOR
SELECT blzz,lgzs
END;
END;
end;
调用存储过程:
/// <summary>
/// 得到统计数据集
/// </summary>
/// <param name="cmdText"></param>
/// <param name="Stime"></param>
/// <param name="Etime"></param>
/// <param name="Type"></param>
private DataSet GetTjData(string cmdText, string Stime, string Etime, string Type)
{
DataSet ds = new DataSet();
OracleConnection Con = new System.Data.OracleClient.OracleConnection(AppConfig.ZHCX);
Con.Open();
OracleCommand cmd = new OracleCommand(cmdText, Con);
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter[] parm ={
new OracleParameter("Stime", OracleType.DateTime),
new OracleParameter("Etime", OracleType.DateTime),
new OracleParameter("Type", OracleType.Int16),
new OracleParameter("cur_OUT", OracleType.Cursor) };
parm[0].Value = DateTime.Parse(Stime);
parm[1].Value = DateTime.Parse(Etime).AddDays(1);
parm[2].Value = int.Parse(Type);
parm[3].Direction = ParameterDirection.Output;
foreach (OracleParameter op in parm)
{
cmd.Parameters.Add(op);
}
OracleDataAdapter oda = new OracleDataAdapter(cmd);
oda.Fill(ds);
Con.Close();
return ds;
}