工具 : PLSQL Developer
要求:
给定一个时间(date 类型, yyyy-MM-dd HH:mm:ss),求过了n个星期后,此时间的下一个月的时间.
CREATE OR REPLACE FUNCTION FN_RECURSIVE_DATE(EXEC_TIME IN DATE, -- 执行时间
V_CYCLE IN NUMBER, -- n周
OUT_DATE OUT DATE) -- 执行时间执行n周后的下一个月时间
RETURN DATE AS
/*按周期赠送,按周的递归函数,找到配置的执行时间的下一个月*/
V_EXEC_DAY NUMBER(2); -- 执行时间EXEC_TIME中的天
V_EXEC_MONTH NUMBER(2); -- 执行时间EXEC_TIME中的月份
V_EXEC_YEAR VARCHAR2(4); -- 执行时间EXEC_TIME中的年份
V_DAYS NUMBER(4); -- 总天数
V_STR_EXEC_TIME VARCHAR2(20); -- 执行时间EXEC_TIME的字符串表示方式
V_SPACE_INDEX NUMBER(2); -- 执行时间EXEC_TIME中空格所在索引
V_OTHERS_TIME VARCHAR2(20); -- EXEC_TIME的格式' HH:mm:ss'
V_MAX_DAY NUMBER(2); -- 某个月的最大天数
V_CUR_YEAR VARCHAR2(4); -- 当前年份
V_CUR_MONTH NUMBER(2); -- 当前月份
V_N_EXEC_YEAR NUMBER(4); -- V_EXEC_YEAR 的number格式
V_NEXT_MONTH NUMBER(2); -- 下一月
V_N_CUR_YEAR NUMBER(4); -- v_cur_year 的number格式
BEGIN
-- 取出execTime的day
V_EXEC_DAY := FN_GET_DAY_OF_DATE(EXEC_TIME, V_EXEC_DAY);
-- 取出执行时间execTime中的月份
V_EXEC_MONTH := F_GET_MONTH(EXEC_TIME, V_EXEC_MONTH);
-- execTime 的年份
V_EXEC_YEAR := FN_GET_YEAR_OF_DATE(EXEC_TIME, V_EXEC_YEAR);
-- n周的天数+执行时间中的day
V_DAYS := V_EXEC_DAY + V_CYCLE * 7;
-- 将exec_time转成string格式
V_STR_EXEC_TIME := TO_CHAR(EXEC_TIME, 'yyyy-mm-dd hh24:mi:ss');
-- 找出exec_time中空格的位置
V_SPACE_INDEX := INSTR(V_STR_EXEC_TIME, ' ', 1, 1);
-- ' HH:mm:ss'
V_OTHERS_TIME := SUBSTR(V_STR_EXEC_TIME, V_SPACE_INDEX);
-- 某个月的最大天数
V_MAX_DAY := FN_MAXDAYOFMONTH(V_EXEC_MONTH, V_EXEC_YEAR, V_MAX_DAY);
IF V_DAYS > V_MAX_DAY THEN
/* 如果总天数大于该月的最大天数 */
V_EXEC_MONTH := V_EXEC_MONTH + 1;
IF V_EXEC_MONTH > 12 THEN
V_EXEC_MONTH := 1;
V_EXEC_YEAR := TO_CHAR(TO_NUMBER(V_EXEC_YEAR) + 1);
END IF;
-- end of IF V_EXEC_MONTH > 12
V_EXEC_DAY := V_DAYS - V_MAX_DAY;
-- 获取当前月份
V_CUR_MONTH := F_GET_MONTH(SYSDATE, V_CUR_MONTH);
-- 执行年份的number格式
V_N_EXEC_YEAR := TO_NUMBER(V_EXEC_YEAR);
V_NEXT_MONTH := V_CUR_MONTH + 1;
IF V_NEXT_MONTH > 12 THEN
V_NEXT_MONTH := 1;
V_N_EXEC_YEAR := V_N_EXEC_YEAR + 1;
END IF;
-- end of IF v_next_month > 12
-- 获取当前年份
V_CUR_YEAR := FN_GET_YEAR_OF_DATE(SYSDATE, V_CUR_YEAR);
V_N_CUR_YEAR := TO_NUMBER(V_CUR_YEAR);
IF (V_N_CUR_YEAR = V_N_EXEC_YEAR OR V_N_CUR_YEAR + 1 = V_N_EXEC_YEAR) AND
V_NEXT_MONTH = V_EXEC_MONTH THEN
/* 是下一个月 */
V_STR_EXEC_TIME := V_EXEC_YEAR || '-' || V_EXEC_MONTH || '-' ||
V_EXEC_DAY || V_OTHERS_TIME;
OUT_DATE := TO_DATE(V_STR_EXEC_TIME, 'yyyy-mm-dd hh24:mi:ss');
RETURN OUT_DATE;
END IF;
ELSE
/* 没到下一个月 */
-- 这里的day写的是 V_DAYS (相加后的总天数) , 不然会出现死循环
V_STR_EXEC_TIME := V_EXEC_YEAR || '-' || V_EXEC_MONTH || '-' ||
V_DAYS || V_OTHERS_TIME;
OUT_DATE := TO_DATE(V_STR_EXEC_TIME, 'yyyy-mm-dd hh24:mi:ss');
-- 递归调用
RETURN FN_RECURSIVE_DATE(OUT_DATE, V_CYCLE, OUT_DATE);
END IF;
-- end of if V_DAYS > V_MAX_DAY
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('execute FN_RECURSIVE_DATE fail!' || SQLERRM);
END;
/
执行:
在工具 PLSQL Developer 的Command Window 中输入以下的代码:
VAR v_date DATE;
EXEC :v_date := FN_RECURSIVE_DATE(SYSDATE,2,:v_date);
执行结果如下所示:
- 大小: 17.1 KB
分享到:
相关推荐
PL/SQL Developer是一个集成开发环境,专门面向Oracle数据库存储程序单元的开发。如今,有越来越多的商业逻辑和应用逻辑转向了Oracle Server,因此,PL/SQL编程也成了整个开发过程的一个重要组成部分。PL/SQL ...
SQL基本命令 PL/SQL使用的数据库操作语言还是基于SQL的,所以熟悉SQL是进行PL/SQL编程的基础。SQL语言的分类情况大致如下: 1) 数据定义语言(DDL):Create,Drop,Grant,Revoke,… 2) 数据操纵语言(DML):...
因此可以在将申明发送到甲骨文系统去执行之前使用PL/SQL区段和副程序来组合SQL申明,没有PL/SQL,甲骨文需要就每次处理SQL申明,在网络环境中,这将影响交通流量,而且增加响应时间。PL/SQL区段只被编译一次并且以可...
12.1.5 避免或者减少递归调用 341 12.1.6 ROWID优化应用 347 12.2 设法避免外因影响 350 12.2.1 Hint改写确保执行计划正确 350 12.2.2 避免子查询的错误执行计划 350 12.2.3 所在环境的资源不足等问题 351 ...
12.1.5 避免或者减少递归调用 341 12.1.6 ROWID优化应用 347 12.2 设法避免外因影响 350 12.2.1 Hint改写确保执行计划正确 350 12.2.2 避免子查询的错误执行计划 350 12.2.3 所在环境的资源不足等问题 351 ...
2.4.2 pl/sql程序结构 33 第3章 创建、修改和删除表 37 3.1 表的基础知识 37 3.1.1 表的基本结构 37 3.1.2 表的种类 38 3.2 sql数据类型 39 3.2.1 字符型数据 39 3.2.2 数字型数据 40 3.2.3 日期数据类型 41...
《精通SQ:结构化查询语言详解》全面讲解SQL语言,提供317个典型应用,读者可以随查随用,针对SQL Server和Oracle进行讲解,很有代表性。 全书共包括大小实例317个,突出了速学速查的特色。《精通SQ:结构化查询语言...
在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块,不过有一点不同的是,触发器是隐式调用的,并不能接收参数。 触发器优点 (1)触发器能够实施的检查和操作比主键和外键约束、...
), interpreted (然后 PL/SQL 模块将被编译为 PL/SQL 字节代码格式), debug (PL/SQL 模块将用探测调试符号来编译), non_debug。 默认值: " interpreted, non_debug " plsql_native_linker: 说明: 此参数指定链接...
10.2.5 将子查询因子化应用到PL/SQL中 270 10.3 递归子查询 273 10.3.1 一个CONNECT BY的例子 274 10.3.2 使用RSF的例子 275 10.3.3 RSF的限制条件 276 10.3.4 与CONNECT BY的不同点 276 10.4 复制CONNECT BY...
5.4 递归函数调用 239 5.5 C++/CLI编程 241 5.5.1 接受数量可变实参的函数 242 5.5.2 main( )的实参 243 5.6 小结 244 5.7 练习 245 第6章 程序结构(2) 246 6.1 函数指针 246 6.1.1 声明函数指针 ...
--(函数round() 进行四舍五入操作) 35、select round(23.232, 2) from dual; --(四舍五入后保留的小数位数 0 个位 -1 十位) 36、select to_char(sal, '$99,999.9999')from emp; --(加$符号加入千位分隔符,保留...
3.6.10 可以在递归函数中嵌入SQL么? ..................................................................................10 3.6.11 我可以在任意版本的Oracle中使用任意版本的预编译器么?.........................
{1.11.3}递归调用}{41}{subsection.1.11.3} {1.12}Java API}{41}{section.1.12} {1.13}Linux命令}{41}{section.1.13} {1.13.1}基本查看、移动}{41}{subsection.1.13.1} {1.13.2}权限}{42}{subsection.1.13.2} ...