阅读更多

1顶
0踩

编程语言

原创新闻 Java 8 的日期与时间问题解决方案

2017-12-06 16:58 by 副主编 jihong10102006 评论(0) 有12199人浏览

来源:Gitbook

作者:寒月

 

写在前面

 

日常的工作中,我们也许会遇到 “判断 Unix 时间是否为 0 点” 的问题。我们也许会构建以下代码:

 

boolean at0Clock(long unixTimeStamp) {
  return unixTimeStamp % 86400 == 0;
}

  我们做一个单元测试(使用 junit 单元测试框架):

 

@Test
void testAt0Clock() {
  Calendar calendar = Calendar.getInstance();

  //
  // 设置日期与时间 2017-11-11T00:00:00
  //
  calendar.set(Calendar.YEAR, 2017);
  calendar.set(Calendar.MONTH, 10);  // November
  calendar.set(Calendar.DATE, 11);
  calendar.set(Calendar.HOUR, 0);
  calendar.set(Calendar.MINUTE, 0);
  calendar.set(Calendar.SECOND, 0);
  calendar.set(Calendar.MILLISECOND, 0);

  Assert.assertEquals(true, Main.at0Clock(calendar.getTimeInMillis() / 1000));
}

 感兴趣的读者可以试一试,单元测试是否通过。无论通过与否,也请尝试执行以下代码:

 

void printTimeZone() {
  TimeZone timeZone = Calendar.getInstance().getTimeZone();
  System.out.println(timeZone.getID() + " " + timeZone.getDisplayName());
}

 作者位于上海,单元测试 testAt0Clock() 不通过,执行代码 printTimeZone() 的输出:

Asia/Shanghai 中国标准时间

 关于单元测试 testAt0Clock() 不通过的原因,我们有必要先了解若干基础的概念:“Unix 时间”、“时区”。

 

Unix 时间、时区

 

Unix 时间

 

Wikipedia 中关于 Unix 时间 定义为:

Unix time is a system for describing a point in time, defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, minus the number of leap seconds that have taken place since then.

 根据定义:Unix 时间表示自 1970-01-01T00:00:00Z(Z 即表示 UTC 时间,请参阅 ISO 8601)所经过的秒数,并且移除期间的 “闰秒”(例如:1998-12-31T23:59:60Z)。Unix 时间体系中,每天固定 86400 秒。

 

Java 中的 Unix 时间

Java 确保:每天 24 小时、每小时 60 分、每分钟 60 秒。

 

Java 中获取 “当前” 时间的方法,其底层实现,全部由 java.lang.System.currentTimeMillis() 提供自 UTC 1970-01-01T00:00:00 的毫秒数。java.lang.System.currentTimeMillis() 作为 native 方法,其实现与 JVM 所在的机器相关(通常使用 NTP 协议保持更新)。

 

本文中,我们将 java.lang.System.currentTimeMillis() 的返回值,称为毫秒级精度的 “Unix 时间”。

时区

时区作为地理概念,表示 “遵守统一时间标准的一个地区”。Wikipedia 中关于 时区 定义为:

A time zone is a region of the globe that observes a uniform standard time for legal, commercial, and social purposes.

 

使用与 UTC 的偏移来表示时区,例如:中国所在时区为 UTC+08:00(又称为 Chinese Standard Time,即 “中国标准时间”;tz 时区数据库 中,表示为 Asia/Shanghai)

 

“偏移”,即为表示与 UTC 的时间差。例如:1970-01-01T00:00:00Z == 1970-01-01T00:08:00+08:00(+08:00 表示位于 UTC+08:00 时区)。

 

关于 boolean at0Clock(long unixTimeStamp)

 

完成 “Unix 时间” 和 “时区” 的阅读,相信读者对于 boolean at0Clock(long unixTimeStamp) 的单元测试不通过的原因,已经有了自己的答案。

 

Calendar 的实现:首先,根据年、月、日、时、分、秒计算获得自 1970-01-01 00:00:00 经过的秒数;然后,减去当前时区的 UTC 偏移,得到 Unix 时间。因此,对于运行于 “中国标准时间” 的系统,正确的 >boolean at0Clock(long unixTimeStamp) 实现:

 

boolean at0Clock(long unixTimeStamp) {
  return (unixTimeStamp + 8 * 3600) % 86400 == 0;
}

 Java 8 以前的方案

 

承载日期与时间的类型

 

java.util.Date

 

使用 java.util.Date 表示日期与时间,其承载了毫秒级精度的 Unix 时间,除此之外的功能(包括:承载 “年、月、日、时、分、秒” 字段,格式化,字符串解析),均标记为 @Deprecated

 

java.util.Date 实现了 Comparable 接口,并提供 boolean before(Date) / boolean after(Date) 方法。

 

特别说明:java.util.DateString toString() 方法,使用系统的时区。

 

void printDate(java.util.Date date) {
  //
  // date 表示日期与时间,输出:
  //   1. Unix 时间(毫秒)
  //   2. EEE MMM dd HH:mm:ss zzz yyyy 格式输出
  //
  System.out.println(String.format("%d - %s", date.getTime(), date.toString()));
}

void usingDate() {
  java.util.Date now = new java.util.Date();  // 当前时间
  printDate(now);

  java.util.Date date = new java.util.Date(1511193600 * 1000L);  // Unix 时间:1511193600 * 1000(毫秒)
  printDate(date);  // 输出:1511193600000 - Tue Nov 21 00:00:00 CST 2017

  date.setTime(0 * 1000L);  // 设置时间,Unix 时间:0 * 1000(毫秒)
  printDate(date);  // 输出:0 - Thu Jan 01 08:00:00 CST 1970
}

 此外,Java 提供了 java.sql.Datejava.sql.Timejava.sql.Timestamp,作为 java.util.Date 的子类,用于 JDBC 中,分别代表 SQL 的 DATETIMETIMESTAMP 类型,其中 java.sql.Timestamp 的精度是纳秒。

 

java.util.Calendar

 

使用抽象类 java.util.Calendar 表示日期与时间,java.util.GregorianCalendar 是其常见的非抽象子类。

 

相比较于 java.util.Datejava.util.Calendar 除了承载毫秒级的 Unix 时间,还承载了时区信息(默认使用系统的时区),并且,提供了诸多接口:“年、月、日、时、分、秒” 字段的获取与设置,时区设置,日期与时间的偏移调整。

 

java.util.Calendar 实现了 Comparable 接口,并提供:boolean before(Object) / boolean after(Object) 方法。

 

void printCalendar(Calendar calendar) {
  //
  // date 表示时间和日期,输出:
  //   1. Unix 时间(毫秒)
  //   2. 格式化输出 yyyy-MM-dd HH:mm:ss
  //
  System.out.println(String.format("%d -> %04d-%02d-%02d %02d:%02d:%02d", calendar.getTime().getTime(),
    calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE),
    calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)));
}

void usingCalendar() {
  Calendar calendar = Calendar.getInstance();  // 当前时间
  printCalendar(calendar);

  calendar.setTime(new Date(1511193600 * 1000L + 12));  // Unix 时间:1511193600 * 1000 + 12(毫秒)
  printCalendar(calendar);  // 输出:1511193600012 -> 2017-11-21 00:00:00

  //
  // 设置日期与时间 2017-10-31T00:00:00
  //
  calendar.set(2017, Calendar.OCTOBER, 31, 0, 0, 0);
  printCalendar(calendar);  // 输出:1509379200012 -> 2017-10-31 00:00:00

  //
  // 设置时区
  //
  calendar.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo"));
  printDate(calendar.getTime());  // 输出:1509379200012 - Tue Oct 31 00:00:00 CST 2017
  printCalendar(calendar);  // 输出:1509379200012 -> 2017-10-31 01:00:00

  calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
  printDate(calendar.getTime());  // 1509379200012 - Tue Oct 31 00:00:00 CST 2017

  calendar.set(Calendar.SECOND, 0);
  printDate(calendar.getTime());  // 1509382800012 - Tue Oct 31 01:00:00 CST 2017
  printCalendar(calendar);  // 1509382800012 -> 2017-10-31 01:00:00

  //
  // 设置 & 调整
  //
  calendar.add(Calendar.MINUTE, 60);
  printCalendar(calendar);  // 1509382800012 -> 2017-10-31 02:00:00

  calendar.roll(Calendar.DATE, 1);
  printCalendar(calendar);  // 1506794400012 -> 2017-10-01 02:00:00
}

 格式化输出 & 字符串解析

 

通过抽象类 java.text.DateFormat 及其非抽象子类 java.text.SimpleDateFormat,能够快速地进行日期与时间的格式化输出和字符串解析。关于日期与时间字段(年、月、日、时、分、秒、时区)格式化 & 解析的模式,请参阅 Java doc

 

void formatAndParse() throws ParseException {
  DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss XXX");  // XXX 即为 “时区”

  //
  // 格式化
  //
  Calendar calendar = Calendar.getInstance();
  calendar.setTime(new Date(0));
  System.out.println(dateFormat.format(calendar.getTime()));  // 输出:1970-01-01T08:00:00 +08:00

  //
  // 解析
  //
  String raw = "2017-11-30T00:00:00 +00:00";
  Date date = dateFormat.parse(raw);
  System.out.println(dateFormat.format(date));  // 输出:2017-11-30T08:00:00 +08:00
}

 可能存在的问题

 

概念定义:

 

  1. java.util.Date 仅承载 Unix 时间,与名称 “Date” 不相符
  2. 未区分 “Unix 时间” 与 “可理解的日期与时间”
  3. 缺少不携带时区信息的 “本地时间” 模型
  4. 未区分 “时区” & “UTC 偏移”
  5. 无 “时间段” 模型

 

编程模型:

 

  1. 承载日期与时间的类型,全部 “mutable”
  2. java.util.Calendar:月份表达范围 0-11
  3. java.text.DateFormat:非线程安全

 

更多的内容,请参考:Java 8 日期与时间方案(JSR 310)提案者的访谈

 

Java 8 的方案 (JSR 310)

 

承载日期与时间的类型

 

承载日期与时间的类型主要包括:java.time.Instantjava.time.LocalDate / java.time.LocalTime / java.time.LocalDateTimejava.time.ZonedDateTime,全部是 “immutable” 类型。

 

Instant

 

java.time.Instant 承载纳秒级精度的 Unix 时间,其 String toString() 方法基于 ISO-8601 进行格式化。Instant 不承载时区信息。

 

Instant now = Instant.now();
System.out.println(now);

Instant instant = Instant.ofEpochSecond(1511193600L);
System.out.println(instant);  // 输出:2017-11-20T16:00:00Z

instant = Instant.ofEpochMilli(15111936001206L);
System.out.println(instant);  // 输出:2448-11-16T16:00:01.206Z

instant = Instant.ofEpochSecond(1511193600L, 276);
System.out.println(instant);  // 输出:2017-11-20T16:00:00.000000276Z

 LocalDate / LocalTime / LocalDateTime

 

java.time.LocalDate 用于表示 “本地日期”,无 “时间”。LocalDate 不承载时区信息。

 

LocalDate now = LocalDate.now();  // 使用系统所在时区,由当前的 Unix 时间构建
System.out.println(now);

LocalDate date = LocalDate.of(2017, 11, 25);
System.out.println(date);  // 输出:2017-11-25

date = LocalDate.of(2017, Month.DECEMBER, 20);
System.out.println(date);  // 输出:2017-11-20

 java.time.LocalTime 用于表示 “本地时间”,无 “日期”。LocalTime 不承载时区信息。

 

 

LocalTime now = LocalTime.now();  // 使用系统所在时区,由当前的 Unix 时间构建
System.out.println(now);

LocalTime time = LocalTime.of(11, 20);
System.out.println(time);  // 输出:11:20

time = LocalTime.of(13, 20, 12);
System.out.println(time);  // 输出:13:20:12

time = LocalTime.of(13, 20, 12, 1);
System.out.println(time);  // 输出:13:20:12.000000001

 java.time.LocalDateTime 用于表示 “本地日期与时间”。LocalDateTime 不承载时区信息。

 

 

LocalDate 实例与 LocalTime 实例能够共同构建 LocalDateTime 实例,由 LocalDateTime 实例能够获取 LocalDate 实例与 LocalTime 实例。

 

LocalDateTime now = LocalDateTime.now();  // 使用系统所在时区,由当前的 Unix 时间构建
System.out.println(now);

LocalDateTime dateTime = LocalDateTime.of(2017,11,20,13,47);
System.out.println(dateTime);  // 输出:2017-11-20T13:47

dateTime = LocalDateTime.of(2017,11,20,13,47, 20);
System.out.println(dateTime);  // 输出:2017-11-20T13:47:20

dateTime = LocalDateTime.of(2017,11,20,13,47, 20, 1);
System.out.println(dateTime);  // 输出:2017-11-20T13:47:20.000000001

//
// LocalDate & LocalTime -> LocalDateTime
//
LocalDate date = LocalDate.of(2017, 11, 20);
LocalTime time = LocalTime.of(16, 32, 25, 6);

dateTime =  date.atTime(time);
System.out.println(dateTime);  // 输出:2017-11-20T16:32:25.000000006

dateTime = date.atTime(17,11,21);
System.out.println(dateTime);  // 输出:2017-11-20T17:11:21

dateTime = time.atDate(date);
System.out.println(dateTime);  // 输出:2017-11-20T16:32:25.000000006

//
// LocalDateTime -> LocalDate & LocalTime
//
dateTime = LocalDateTime.of(2017,11,20,13,47, 20, 1);

date = dateTime.toLocalDate();
System.out.println(date);

time = dateTime.toLocalTime();
System.out.println(time);

 由于 LocalDateTime 不承载时区信息,因此,其不能与 Instant 相互转换,必须提供时区信息。

 

 

LocalDateTime localDateTime = LocalDateTime.of(2017,11,25,13,6,7);
System.out.println(localDateTime);  // 输出:2017-11-30T14:56:07

Instant instant = localDateTime.toInstant(ZoneOffset.of("+08:00"));
System.out.println(instant);  // 输出:2017-11-25T05:06:07Z

LocalDateTime localDateTimeFromInstant = instant.atZone(ZoneId.of("Asia/Tokyo")).toLocalDateTime();
System.out.println(localDateTimeFromInstant);  // 输出:2017-11-25T14:06:07

LocalDateTime localDateTime = LocalDateTime.of(2017,11,30,14,56,7);
System.out.println(localDateTime);  // 输出:2017-11-30T14:56:07

 ZonedDateTime

 

java.time.ZonedDateTime 用于表示位于特定 “时区” 的 “日期与时间”,其 “时区” 信息使用 tz 时区数据库 表示(明确与 UTC 偏移区分)。

 

ZonedDateTime 的时区调整方法非常明确,区分:保持 “Unix 时间” 固定进行时区调整和保持 “本地日期与时间” 固定进行时区调整。 (相比较于 java.util.Calendar,更加清晰)

 

LocalDateTime localDateTime = LocalDateTime.of(2017, 11, 11,14,57,21);
System.out.println(localDateTime);  // 输出:2017-11-11T14:57:21

ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime);  // 输出:2017-11-11T14:57:21+08:00[Asia/Shanghai]
System.out.println(zonedDateTime.toInstant().getEpochSecond());

zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime);  // 输出:2017-11-11T15:57:21+09:00[Asia/Tokyo]
System.out.println(zonedDateTime.toInstant().getEpochSecond());

zonedDateTime = zonedDateTime.withZoneSameLocal(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime);  // 输出:2017-11-11T15:57:21+09:00[Asia/Tokyo]
System.out.println(zonedDateTime.toInstant().getEpochSecond());

 java.time.OffsetDateTimejava.time.OffsetTime 使用相对于 UTC 的偏移承载 “时区” 信息,本文中不予展开阐述。

承载时间段的类型

 

承载时间段的类型主要包括:java.time.Periodjava.time.Duration,全部是 “immutable” 类型。

 

Period / Duration

 

java.time.Period 承载基于日期的时间段,例如:1 年 1 月 1 日。

 

Period period = Period.of(1, 1, 1);

LocalDate date = LocalDate.of(2017,11,12);
System.out.println(date);  // 输出:2017-11-12

date = date.plus(period);
System.out.println(date); // 输出:2018-12-13

LocalDate beginDate = LocalDate.of(2017, 11,12);
LocalDate endDate = LocalDate.of(2019, 12,11);

period = Period.between(beginDate, endDate);
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getDays() + " days");  // 2 years, 0 months, 29 days

 java.time.Duration 承载基于秒的时间段(提供纳秒级精度)。

 

 

Duration duration = Duration.ofSeconds(86401);

LocalDateTime dateTime = LocalDateTime.of(2017,11,12,0,0,0);
System.out.println(dateTime);  // 2017-11-12T00:00

dateTime = dateTime.minus(duration);
System.out.println(dateTime);  // 2017-11-10T23:59:59

LocalDateTime beginDateTime = LocalDateTime.of(2017, 11,12,0,0,0,12);
LocalDateTime endDateTime = LocalDateTime.of(2017, 11,12,0,1,1);
duration = Duration.between(beginDateTime, endDateTime);

System.out.println(duration.getSeconds() + " seconds, " + duration.getNano() + " nanos");  // 60 seconds, 999999988 nanos

 核心接口

 

TemporalTemporalAccessorTemporalAdjusterTemporalAmount

 

 

类图所示,java.time.temporal 提供的接口:

 

  1. TemporalField:日期与时间 “字段”,例如:2017-11-18 中的 18 “天”
  2. TemporalUnit:时间 “单位”,例如:1 年 13 天的 13 “天”
  3. TemporalAccessor:“时间相关” 对象的 “只读” 接口
  4. Temporal:“时间相关” 对象的 “读写” 接口,继承自 TemporalAccessor
  5. TemporalAdjusterTemporal 类型对象 “设置 & 调整” 的函数式接口
  6. TemporalAmount:时间段

java.time 提供的类:

 

  1. InstantLocalDateLocalTimeLocalDateTimeZonedDateTime:实现 TemporalTemporalAdjuster 接口
  2. DurationPeriod:实现 TemporalAmount 接口

 

 

//
// 调整日期与时间:通过 <code>Temporal</code> 接口
//
Duration duration = Duration.of(88, ChronoUnit.SECONDS);
localDateTime = localDateTime.plus(duration);
System.out.println(localDateTime);  // 输出:2017-11-30T14:57:35

//
// 调整日期与时间:通过 <code>Temporal</code> 接口
//
LocalDateTime nextDay = localDateTime.with(temporal -> temporal.plus(1, ChronoUnit.DAYS));
System.out.println(nextDay);  // 输出:2017-12-01T14:57:35

//
// 调整日期与时间:通过 <code>TemporalAdjuster</code> 接口
//
localDateTime = (LocalDateTime) nextDay.adjustInto(localDateTime);
System.out.println(localDateTime);  // 输出:2017-12-01T14:57:35

//
// 获取日期与时间字段值:通过 <code>TemporalAccessor</code> 接口
//
System.out.println("nextDay = " + nextDay.get(ChronoField.YEAR) + " 年 " + nextDay.get(ChronoField.MONTH_OF_YEAR) + " 月 " + nextDay.get(ChronoField.DAY_OF_MONTH) + " 日");
// 输出:nextDay = 2017 年 12 月 1 日

格式化输出 & 字符串解析

 

java.time.format.DateTimeFormatter 能够进行 TemporalAccessor 类型(包括:LocalDateLocalTimeLocalDateTimeZonedDateTime)的格式化输出。同时,LocalDateLocalTimeLocalDateTimeZonedDateTime 提供了静态的 parse 方法,能够进行字符串解析。

 

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy 年 MM 月 dd 日");

ZonedDateTime zonedDateTime = Instant.ofEpochSecond(1511463192L).atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(formatter.format(zonedDateTime));  // 输出:2017 年 11 月 24 日

LocalDate localDate = LocalDate.parse("2017 年 11 月 25 日", formatter);
System.out.println(localDate);  // 输出:2017-11-25

 LocalDateLocalTimeLocalDateTimeZonedDateTime 允许基于类型的默认格式进行格式化输出和字符串解析。

 

 

类型 默认格式示例
Instant 2017-11-23T10:15:30.00Z
LocalDate 2017-11-23
LocalTime 10:15:30
LocalDateTime 2017-11-23T10:15:30
ZonedDateTime 2017-11-23T10:15:30+01:00[Asia/Shanghai]

写在结束

 

通过本文的内容,期望读者能够对于日期与时间相关的概念能有基础的理解,也期望读者能够掌握 Java 提供的涉及日期与时间的类及接口。

来自: Gitbook
1
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 参数OPEN_CURSOR

    参考文章:http://www.itpub.net/thread-19466-1-1.htmlhttp://java.**.com/others/718640.html官方文档:B14237-04 OPEN_CURSORS s...

  • SAP 通过游标(OPEN CURSOR)读取数据

    SAP 通过游标(OPEN CURSOR)读取数据

  • oracle open_cursors参数配置

    oracle open_cursors参数配置 查看游标打开最大值设置 SQL&gt; show parameter open_cursors; oracle 默认open_cursors 为300 设置open_cursors值 alter system set open_cursors = 1000; alter system set open_cursors = 1000 scope = spfile; 若不带scope 对应默认scope为both 扩展了解 spfile参数的三种scope

  • oracle open_cursors的含义及ORA-01000: 超出打开游标的最大数模拟

    Property Description Parameter type Integer Default value 50 Modifiable ALTER SYSTEM Range of values 0 to 65535 Basic Yes OPEN_CURSO

  • 使用SELECT和OPEN CURSOR读取product数据的一些讨论

    Created by Jerry Wang, last modified on Mar 10, 2014 OPEN CURSOR: After the OPEN CURSOR statement, the database cursor is positioned in front of the first line of the result set. FETCH: This statemen...

  • 菜鸟oracle10-CURSOR加锁

    实际工作中需要用到游标锁所以就google了又google,找到一些资料,下面贴出来一篇觉得还不错的文章: from http://hi.baidu.com/eebevkrtwgbgxzd/item/224ad35f525ec0cfd2e10c14 如下代码: declare -- query emp.name cursor cur_emp ...

  • oracle修改open_cursors,oracle的open_cursors问题探究

    今天老魏遇到了一个这样的问题,在google之后,发现讲open_cursors参数调大一些,就可以避免这样的问题(具体操作方法,可以自行百度/google)。老魏在学习的时候,对这个游标的概念有点傻傻分不清,于是花费了一些时间,想把这个问题搞懂。对于这个问题的实践,我参考了asktom上面,tom大师的回复。我先阐述一下最开始的设想,我认为每执行一条sql语句,都会占用一个opencursor,...

  • oracle游标耗资源,Oracle游标泄露(open_cursor耗尽)

    前言编者注,本文的知识点较多,请补充足够正能量后阅读,看完会让你质疑你的DBA生涯,作者的水平代表着国内Oracle TroubleShooting最高水平。很早就想把ORA-1000的问题,总结成一个话题。机缘巧合,最近恰好遇上几个此类问题,特分享分析过程出来供大家参考。首先,ORA-1000报错是什么意思呢?我们来看看官方的解释:1.png非常简单,单个进程打开的游标数超过了最大值,也就是超过...

  • OPEN_CURSOR学习一

     哪些连接没有关闭可以通过下面的语句来查询:select * from v$open_cursor where user_name=**http://www.itpub.net/thread-996539-1-1.htmlopen的cusor只有在所有引用了它的session都disconnect的情况下,才会关闭cursor。可以试一下。select count(*) from v$

  • linux查看open_cursors,关于open cursor 的释放问题

    Oracle 10.2.0.4 , Linux AS 5.3, RAC , 4 nodesopen_cursors 原来设置为 1000 , 3 个节点, 2个用于OLTP 事务, 1 个用于报表查询 ,没有发生过 ora-01000 的错误上周加入了一个节点, 变成 4 节点, 除了应该修改的 cluster 方面的参数有修改外, 其他保持不变, 然后OLTP 段的节点变成3 个节点, 报表...

  • open cursor for

    oracle中open cursor for 和for cursor in的区别如下:open cursor for 是直接打开游标查询结果,适用于单表查询,结果集一般不会太大。for cursor in是从大量数据中循环获取满足条件的记录,放入游标1、open cursor for 用法:CREATE OR REPLACE PROCEDURE AMLS.TEST(C_RES OUT SYS_RE

  • open_cursor数量

    一个案例[@more@]首先登陆到DB.cmd sqlplus xx/xx@xxxxSQL*Plus: Release 9.2.0.1.0 - Production on 星期一 1月 10 16:25:45 2005Cop...

  • open_cursors参数设置调优

    ORACLE服务端CACHING CURSOR的功能,我们称为软关闭,即使你隐式关闭游标、或者close cursor也不会真正硬关闭这个游标,以便下次执行相同语句时,不需要重复打开。 对于临时游标,下次调用不同语句时就被硬关闭,但是对于存储对象中的游标(SQL),那么通常只有在OPEN CURSOR满才会去硬关闭。 这里的OPEN CURSOR满是什么意思?怎么才算满? show pa...

  • ABAP Using a Cursor to Read Data

    ABAP Using a Cursor to Read Data

  • 理解游标CURSOR,OPEN_CURSORS参数 以及视图V$OPEN_CURSOR, V$SESSION_CACHED_CURSOR

    游标概念:  游标的作用就是用于临时存储从数据库中提取的数据块,由系统或用户以变量的形式定义。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。 Cursor游标分两种,一种是Shared cursor,位于SGA的一种library cache object,通常我们所说的

  • Cursor identified in Fetch statement is not open

    在weblogic9.1和9.2版本中使用其自带的数据库驱动连接db2V9.5时,流程解析发布报错:   经过测试,应该是weblogic自身提供的驱动版本问题。 解决方案如下: 1. 将db2安装目录下的驱动copy到目录:%WL_HOME%\server\lib\ 2. 修改%WL_HOME%\common\bin下的commEnv.cmd文件,在WEBLOGIC_CLASSPA...

  • 当open cursor时就执行cursor的声明.Test open Cursor!

    测试目的:Open Curosor时,是否就是执行cursor声明. create table test_tab (col1 varchar2(20)) declare x_out varchar2(100);x_out1 varchar2(100);cursor cur_col1is select col1 from test_tab;cursor cur_col11is sel

  • ABAP OPEN SQL里OPEN CURSOR和SELECT的比较

    OPEN CURSOR After the OPEN CURSOR statement, the database cursor is positioned in front of the first line of the result set. FETCH This statement extracts the requested rows (using the addition I...

Global site tag (gtag.js) - Google Analytics