📄 第三章 pl-sql数据类型 - pl-sql用户指南与参考 - whatiswhat.htm
字号:
<P>LOB类型中可以存储了LOB定位器,它能够指向存放于外部文件中的"大对象",in-line (inside
the row)或out-of-line (outside the
row)的形式。BLOB、CLOB、NCLOB或BFILE类型的数据库字段存储了定位器。其中BLOB、CLOB和NCLOB的数据存在数据库中,
in-line (inside the row)或out-of-line (outside the
row)的形式,而BFILE数据存在数据库之外的操作系统文件中。</P>
<P>PL/SQL是通过定位器来操作LOB的。例如,当我们查询出一个BLOB值,只有定位器被返回。如果在事务中得到定位器,LOB定位器就会包含事务的ID号,这样我们就不能在另外一个事务中更新LOB内容了。同样,我们也不能在一个会话中操作另外一个会话中的定位器。
</P>
<P>从9i开始,我们也可以把CLOB类型转成CHAR和VARCHAR2类型或是把BLOB转成RAW,反之亦然,这样,我们就能在大多数SQL和PL/SQL语句和函数中使用LOB类型了。要读、写和分段的操作LOB,我们可以使用Oracle系统包DBMS_LOB。</P>
<UL>
<LI>BFILE </LI></UL>
<P>BFILE数据类型用于存储二进制对象,它将存储的内容放到操作系统的文件中,而不是数据库内。每个BFILE变量都存储一个文件定位器,它指向服务器上的一个大的二进制文件。定位器包含目录别名,该别名给出了文件全路径。</P>
<P>BFILE类型是只读的,而且它的大小要依赖于系统,不能超过4G。我们的DBA要确保给定的BFILE存在且Oracle有读取它的权限。</P>
<P>BFILE并不参与事务,是不可恢复,不能被复制。能够被打开的BFILE最大数是由Oracle初始化参数SESSION_MAX_OPEN_FILES决定的。
</P>
<UL>
<LI>BLOB、CLOB和NCLOB </LI></UL>
<P>BLOB数据类型可以在数据库中存放不超过4G的大型二进制对象;CLOB和NCLOB可以在数据库中分别存储大块CHAR类型和NCHAR类型的字符数据,都支持定宽和变宽字符集。同BFILE一样,这三个类型也都储存定位器,指向各自类型的一个大数据块。数据大小都不能超过4G。BLOB、
CLOB和NCLOB都可以在事务中使用,能够被恢复和复制。DBMS_LOB包可以对它们更改过的内容进行提交或回滚操作。BLOB、CLOB和
NCLOB的定位器都可以跨事务使用,但不能跨会话使用。 </P>
<P class=title2>5、布尔类型</P>
<P>布尔类型能存储逻辑值TRUE、FALSE和NULL(NULL代表缺失、未知或不可用的值)。只有逻辑操作符才允许应用在布尔变量上。</P>
<P>数据库SQL类型并不支持布尔类型,只有PL/SQL才支持。所以就不能往数据库中插入或从数据库中检索出布尔类型的值。
</P>
<P class=title2>6、Datetime和Interval类型</P>
<P>Datetime就是日期时间类型,而Interval指的是时间的间隔。Datetime和Interval类型都由几个域组成,下表是对每个域及其它们对应的有效值描述:
</P>
<TABLE id=table-list>
<TBODY>
<TR>
<TH id=table-list-head>域名称</TH>
<TH id=table-list-head>有效日期时间值</TH>
<TH id=table-list-head>有效间隔值</TH></TR>
<TR>
<TD>YEAR</TD>
<TD>-4712 到 9999 (不包括0)</TD>
<TD>任意非零整数</TD></TR>
<TR>
<TD>MONTH</TD>
<TD>01 到 12</TD>
<TD>0 到 11</TD></TR>
<TR>
<TD vAlign=top>DAY</TD>
<TD>01 到 31 (根据当地的历法规则,<BR>受MONTH和YEAR值的限制</TD>
<TD>任意非零整数</TD></TR>
<TR>
<TD>HOUR</TD>
<TD>00 到 23</TD>
<TD>0 到 23</TD></TR>
<TR>
<TD>MINUTE</TD>
<TD>00 到 59</TD>
<TD>0 到 59</TD></TR>
<TR>
<TD vAlign=top>SECOND</TD>
<TD>00 到 59.9(n),<BR>9(n)是秒小数部分的精度</TD>
<TD>0 to 59.9(n),<BR>9(n)间隔秒的小数部分的精度</TD></TR>
<TR>
<TD vAlign=top>TIMEZONE_HOUR</TD>
<TD>-12 到 14 (随日光节约时间的变化而变化)</TD>
<TD vAlign=top>不可用</TD></TR>
<TR>
<TD>TIMEZONE_MINUTE</TD>
<TD>00 到 59</TD>
<TD>不可用</TD></TR>
<TR>
<TD vAlign=top>TIMEZONE_REGION</TD>
<TD>查看视图V$TIMEZONE_NAMES</TD>
<TD>不可用</TD></TR>
<TR>
<TD vAlign=top>TIMEZONE_ABBR</TD>
<TD>查看视图V$TIMEZONE_NAMES</TD>
<TD>不可用</TD></TR></TBODY></TABLE>
<P>除了TIMESTAMP WITH LOCAL TIMEZONE以外,剩下的都是SQL92所支持的。
</P>
<UL>
<LI>DATE </LI></UL>
<P>DATE数据类型能够存储定长的日期时间。日期部分默认为当月的第一天;时间部分为午夜时间。函数SYSDATE能够返回当前的日期和时间。
</P>
<P>提示:如果只进行日期的等值比较,忽略时间部分,可以使用函数TRUNC(date_variable)。
</P>
<P>有效的日期范围是从公元前4721年1月1日到公元9999年12月31日。儒略日(Julian
date)是自公元前4712年1月1日起经过的天数。我们可以使用日期模式"J"配合函数TO_DATE和TO_CHAR来把日期值转换成等值的儒略日。</P>
<P>在日期表达式中PL/SQL会自动地将格式为默认日期格式的字符值转成DATE类型值。默认的日期格式由Oracle的初始化参数
NLS_DATE_FORMAT决定的。例如,默认格式可能是"DD-MON-YY",它包含两位数字表示一个月中的第几日,月份名称的缩写和两位记年用的数字。</P>
<P>我们可以对日期进行加减运算。例如,下面的语句就能返回员工自被雇用日起,至今所经过的天数:</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>SELECT</STRONG> <STRONG>SYSDATE</STRONG> - hiredate <BR> <STRONG>INTO</STRONG> days_worked <BR> <STRONG>FROM</STRONG> emp<BR> <STRONG>WHERE</STRONG> empno = 7499;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>在算术表达式中,PL/SQL会将整数文字当作"日"来处理,如"SYSDATE +
1"就代表明天的时间。</P>
<UL>
<LI>TIMESTAMP </LI></UL>
<P>TIMESTAMP是对DATE的扩展,包含了年月日时分秒,语法如下: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>TIMESTAMP</STRONG>[(precision)]
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>precision是可选参数,用于指定秒的小数部分数字个数。参数precision不可以是常量或变量,其有效范围是0到9,默认值是6。默认的时间戳(timestamp)格式是由Oracle初始化参数NLS_TIMESTAMP_FORMAT决定的。
</P>
<P>在下面的例子中,我们声明了一个TIMESTAMP类型的变量,然后为它赋值:</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>DECLARE</STRONG><BR> checkout <STRONG>TIMESTAMP</STRONG> ( 3 );<BR><STRONG>BEGIN</STRONG><BR> checkout := <EM>'1999-06-22 07:48:53.275'</EM>;<BR> ...<BR><STRONG>END</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>这个例子中,秒的小数部分是0.275。</P>
<UL>
<LI>TIMESTAMP WITH TIME ZONE </LI></UL>
<P>TIMESTAMP WITH TIME
ZONE扩展了TIMESTAMP,能够表现时区位移(time-zone
displacement)。时区位移在本地时间和通用协调时间(UTC)中是不同的。语法如下: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>TIMESTAMP</STRONG>[(precision)] <STRONG>WITH</STRONG> <STRONG>TIME</STRONG> <STRONG>ZONE</STRONG>
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>precision的用法同TIMESTAMP语法中的precision。默认格式由Oracle初始化参数NLS_TIMESTAMP_TZ_FORMAT决定。</P>
<P>下例中,我们声明一个TIMESTAMP WITH TIME ZONE类型的变量,然后为其赋值: </P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>DECLARE</STRONG><BR> LOGOFF <STRONG>TIMESTAMP</STRONG> ( 3 ) <STRONG>WITH</STRONG> <STRONG>TIME</STRONG> <STRONG>ZONE</STRONG>;<BR><STRONG>BEGIN</STRONG><BR> LOGOFF := <EM>'1999-10-31 09:42:37.114 +02:00'</EM>;<BR> ...<BR><STRONG>END</STRONG>;
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>例子中时区位移是+02:00。我们还可以使用符号名称(symbolic
name)来指定时区位移,名称可以是完整形式也可以是缩写形式,如"US/Pacific"和"PDT",或是组合的形式。例如,下面的文字全都表现同一时间。第三种形式最可靠,因为它指定了切换到日光节约时间时的规则。</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><STRONG>TIMESTAMP</STRONG> <EM>'1999-04-15 8:00:00 -8:00'</EM><BR><STRONG>TIMESTAMP</STRONG> <EM>'1999-04-15 8:00:00 US/Pacific'</EM><BR><STRONG>TIMESTAMP</STRONG> <EM>'1999-10-31 01:30:00 US/Pacific PDT'</EM>
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<P>我们可以在数据词典V$TIMEZONE_NAMES的TIMEZONE_REGION和TIMEZONE_ABBR字段中找到相应的时区名称和它的缩写。如果两个TIMESTAMP
WITH TIME
ZONE值在通用协调时间中的值一样,那么系统就会认为它们的值相同而忽略它们的时区位移。下例两个值被认为是相同的,因为在通用协调时间里,太平洋标准时间8:00
AM和(美国)东部时区11:00 AM是相同的:</P>
<BLOCKQUOTE>
<TABLE>
<TBODY>
<TR>
<TD
noWrap><EM>'1999-08-29 08:00:00 -8:00'</EM><BR><EM>'1999-08-29 11:00:00 -5:00'</EM>
</TD></TR></TBODY></TABLE></BLOCKQUOTE>
<UL>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -