﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-鹰翔宇空-文章分类-datebase</title><link>http://www.blogjava.net/TrampEagle/category/9792.html</link><description>学习和生活
</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 10:32:08 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 10:32:08 GMT</pubDate><ttl>60</ttl><item><title>JSP连接mysql数据库攻略</title><link>http://www.blogjava.net/TrampEagle/articles/51213.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 07 Jun 2006 14:37:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/51213.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/51213.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/51213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/51213.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/51213.html</trackback:ping><description><![CDATA[
		<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
				<p align="left">引自：<a href="http://www.7880.com/info/Article-83e62ca0.html">http://www.7880.com/info/Article-83e62ca0.html</a><br /><br /><br />　连续几天安装配置和连接Mysql数据库，今天终于成功了，回想这几天，真的是甜酸苦辣都有，单mysql就重装了不下10次，而在eclipse上编写的连接数据库的程序总是报错．我都已经down了oracal准备放弃mysql了，不过．．．就象电视剧演的那样，转机总是在这个时候出现，先是看到了saulzy关于mysql4.1.11版本的安装介绍，接着又找到了一款不错的mysql 界面插件，最后在网友的帮助下把mysql的JDBC驱动配好并连通了．一连5天，日子真不好过阿，不过这个过程中，我也觉得自己学到不少东西，呵呵，反正都撑过来了，就要继续往前走．现在，就这几天弄的总结一下，希望对同是正在学习JAVA技术的同道中人能有帮助．<br /><br />　　(相关链接："配置Eclpise+tomcat并实现JSP的编写与部署")<br /><br /><strong>一． 软件下载<br /></strong>　　Mysql<br />　　下载版本：4.1.11<br />　　<a href="http://dev.mysql.com/downloads/mysql/4.1.html" target="_blank">http://dev.mysql.com/downloads/mysql/4.1.html</a><br /><br />　　JDBC驱动<br />　　下载版本：3.1.8<br />　　<a href="http://dev.mysql.com/downloads/connector/j/3.1.html" target="_blank">http://dev.mysql.com/downloads/connector/j/3.1.html</a><br /><br />　　Mysql界面插件:mysql-front<br />　　下载版本镜像：HongKong（我下回来安装就是中文版了）<br />　　<a href="http://www.mysqlfront.de/download.html" target="_blank">http://www.mysqlfront.de/download.html</a><br /><br /><strong>二． 软件安装<br /></strong>　　1.安装mysql<br />　　请参阅相关文章，推荐文章：<a href="http://blog.csdn.net/saulzy/archive/2005/04/23/359648.aspx" target="_blank">http://blog.csdn.net/saulzy/archive/2005/04/23/359648.aspx</a><br /><br />　　2.JDBC驱动：mysql-connector-java-3.1.8<br />　　这只是一个压缩包，并不需要安装，只要将其解压，我么使用的是文件夹mysql-connector-java-3.1.8里的文件：mysql-connector-java-3.1.8-bin.jar．<br /><br />　　3. Mysql界面插件:mysql-front<br />　　这是一个安装程序，按照提示安装就可以了．<br /><br /><strong>三． 环境配置</strong><br />　首先，我要说明的是我现在tomcat的安装路径是: D:\Program Files\Java\Tomcat；JDK的安装路径是：D:\Program Files\Java\j2sdk。<br /><br />　　在这里，需要配置环境变量的是JDBC驱动．在配置前先要把刚才说到的mysql-connector-java-3.1.8-bin.jar本地硬盘某处（我放的地方：D:\Program Files\Java\mysqlforjdbc），然后根据你放的地方，配置classpath，我的配置是这样的：</p>
				<p>　　D:\Program files\Java\j2sdk\lib\tools.jar;</p>
				<p>　　D:\Program Files\Java\j2sdk\lib\mysql-connector-java-3.1.8-bin-g.jar;</p>
				<p>　　D:\Program Files\Java\mysqlforjdbc\mysql-connector-java-3.1.8-bin.jar<br />　　配置这个的目的是让你的java应用程序找到连接mysql的驱动．<br /><br />　　配置完环境变量后还有很重要一步就是为JSP连接数据库配置驱动，这个其实很简单，就是把mysql-connector-java-3.1.8-bin.jar拷到某些文件夹里就行了，我在网上看了很多资料问了很多人，各种说法都有，我综合了一下，为了保险，我都全做了，呵呵，反正就是拷一个400K的文件而已，现列出要把mysql-connector-java-3.1.8-bin.jar拷进去的文件夹，如下：<br />　　D:\Program Files\Java\Tomcat\common\lib<br />　　D:\Program Files\Java\Tomcat\shared\lib<br /><br /><strong>四． 数据库的使用<br /></strong><br />　　Mysql安装完毕以后，还有一些要注意的地方（推荐文章）：<a href="http://blog.csdn.net/saulzy/archive/2005/04/23/359811.aspx" target="_blank">http://blog.csdn.net/saulzy/archive/2005/04/23/359811.aspx</a></p>
				<p>　　就象在文章提到的，mysql安装好后最重要一样就是要看数据库有没有作为系统服务启动了，所以在大家进行数据库操作前，应要看看，在操作系统的开始－＞运行－＞输入services.msc，确定你在安装时你设置的关于mysql的那个服务已经启动，这样你在操作数据库时不会报连接不上的错误．</p>
				<p>　　上面提到了一个较方便的mysql界面插件，但是这个界面是我在已经开始使用mysql后才找到的，刚开始我是在dos下用命令行进行操作的．虽然那个界面也可以进行建库啊，设定权限等操作，但是，我觉得懂得在使用命令行也是一个很重要的技能，所以我先从命令行开始说，怎样简单使用mysql．到后面会谈及mysql－front的使用．<br /><br />　　现在我想在mysql里建一个数据库shujuku，以及在数据库里建一个表biao．具体的命令如下（假设mysql我是刚安装好的）<br /><br />　　1. 进入dos状态（记住命令行的要运行在mysql的安装目录下的bin目录的）</p>
				<p>　　2. 连接mysql<br />　　输入：mysql –h localhost –u root –p<br />　　输入在安装时已设好的密码，就近入了mysql的命令编辑界面了。<br /><br />　　3. 使用mysql的基本命令(在mysql命令行编辑每输入完命令后最后一定要有分号，不然会报错)<br />　　显示数据库：show databases;<br />　　使用数据库：use 数据库名；<br /><br />　　4．建库<br />　　命令：create database shujuku;<br /><br />　　5.为数据库设置权限（用户和密码）<br />　　命令：grant all privileges on shujuku.* to test@localhost identified by “123456”;<br />　　当你执行完这个命令以后，只要你再以用户名：test,密码：123456登录时你就只可以对shujuku这个数据库操作，这样避开使用root，对数据库的安全有很大帮助．<br /><br />　　6.建表<br />　　命令：create table biao(id int(8) primary key,name varchar(10));<br /><br />　　剩下来的与标准sqsl命令基本上是一样的，具体操作略<br />　　值得一提的是，你在命令行上输入＂？＂，就会有mysql命令的简单帮助，如下：<br /><br />　　呵呵，那样，我们还可以知道退出，就是＂exit＂，呵呵！<br /><br /><strong>五． 关于mysql-front的使用<br /></strong>　　我找了好几个mysql的界面工具，觉得最简洁方便还是mysql-front，可惜的是要收费，不过还好有试用期，呵呵，可以先感受感受一下，最重要一点是mysql-front有简体中文版的，英文不好的我用起来就舒服多了．下面简单说说使用吧．</p>
				<p>　　首先，安装就不用说了，有向导，而且很简单．安装好后第一次运行时会跳出来一个要求添加对话的框，在这里你可以添加例如上面已经设定好的shujuku，过程如下:<br />　　当你在注册的复选框里填上你在上面mysql设定好的用户名和密码后，在选择数据库框里就有shujuku 的数据库了，选上，按确定．进入mysql-fron后，你就会看到下面的界面，这是你就可以进行操作了．<br /><br />　　要说明的是，你还可以把root用户也加进去，这要你在mysql-fron的界面上选设置－＞对话－＞新建，再按上面进行就可以，出了root你还可以加入更多的用户，方法还是一样的，设置不同的用户，是方便对不同数据库进行管理，呵呵，root是权限最高的，可不要随便让别人使用你的root用户，保正你数据库的安全．<br /><br /><strong>六． JSP连接mysql<br /></strong>　　现在就是尝试用jsp连接mysql了<br />　　我在eclipse里建了个test_mysql.jsp页面，代码如下：</p>
				<p class="code">&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<br /><br />&lt;%@ page language="java" %&gt;<br /><br />&lt;%@ page import="com.mysql.jdbc.Driver" %&gt;<br /><br />&lt;%@ page import="java.sql.*" %&gt;<br /><br />&lt;%<br /><br />//驱动程序名<br /><br />String driverName="com.mysql.jdbc.Driver";<br /><br />//数据库用户名<br /><br />String userName="cl41";<br /><br />//密码<br /><br />String userPasswd="123456";<br /><br />//数据库名<br /><br />String dbName="db";<br /><br />//表名<br /><br />String tableName="dbtest";<br /><br />//联结字符串<br /><br />String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&amp;password="+userPasswd;<br /><br />Class.forName("com.mysql.jdbc.Driver").newInstance();<br /><br />Connection connection=DriverManager.getConnection(url);<br /><br />Statement statement = connection.createStatement();<br /><br />String sql="SELECT * FROM "+tableName;<br /><br />ResultSet rs = statement.executeQuery(sql); <br /><br />//获得数据结果集合<br /><br />ResultSetMetaData rmeta = rs.getMetaData();<br /><br />//确定数据集的列数，亦字段数<br /><br />int numColumns=rmeta.getColumnCount();<br /><br />// 输出每一个数据值<br /><br />out.print("id"); <br /><br />out.print("|");<br /><br />out.print("num");<br /><br />out.print("&lt;br&gt;");<br /><br />while(rs.next()) {<br /><br />out.print(rs.getString(1)+" "); <br /><br />out.print("|");<br /><br />out.print(rs.getString(2));<br /><br />out.print("&lt;br&gt;"); <br /><br />} <br /><br />out.print("&lt;br&gt;");<br /><br />out.print("数据库操作成功，恭喜你"); <br /><br />rs.close(); <br /><br />statement.close(); <br /><br />connection.close(); <br /><br />%&gt;</p>
				<p align="left">　　然后把test­_mysql.jsp部署到tomcat处，如何部署可参考"配置Eclpise+tomcat并实现JSP的编写与部署"，在浏览器中就可以看到结果了。<br /></p>
		</blockquote>
<img src ="http://www.blogjava.net/TrampEagle/aggbug/51213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-06-07 22:37 <a href="http://www.blogjava.net/TrampEagle/articles/51213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从sybase的存储过程转向oracle的存储过程的不同点</title><link>http://www.blogjava.net/TrampEagle/articles/51022.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 07 Jun 2006 01:30:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/51022.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/51022.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/51022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/51022.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/51022.html</trackback:ping><description><![CDATA[
		<p>引自：<a href="http://www.itpub.net/23129.html">http://www.itpub.net/23129.html</a><br /><br /><font face="Verdana">1. ORACLE存储过程的参数不能限定位数，参数类型定位为<br />CHAR(5)是非法的，只能定义为CHAR,具体位数限定有调用时的实参决定，这一点确实与SYBASE有很大不同；<br />2.游标在PL/SQL中作用极大，游标的概念渗透到整个PL/SQL的核心，连INSERT,UPDATE等语句都隐含了一个隐式游标SQL,类似SYBASE的@@ROWCOUNT等系统变量，在ORACLE中定义为游标属性SQL%ROWCOUNT;<br />3.ORACLE中显示一个变量的语句为SELECT V_VAR FROM DUAL;<br />与SYBASE不同的是必须加FROM DUAL;<br />4.SYBASE存储过程可以通过类似SELECT * FROM T_TABLE来返回数据集，在ORACLE中似乎不能，所有不带INTO的SELECT 语句在ORACLE存储过程中是非法的。这一点变化带来最大麻烦，应为POWERBUILDER调用SYBASE存储过程很喜欢这种方式。<br /><br />5、在存储过程中声明参数不用加 DECLARE<br /><br />6、在每个块中只有一个 DECLARE<br /><br />7、参数名不用加 @ 后缀<br /><br />8、每条语句后要加分号<br /><br />9、变量附值不同：<br />myvalue:='abc'; <br />select @myvalue='abc'<br /><br />SELECT EMPNO into :emp from EMP WHERE ...;<br />SELECT @emp=EMPNO from emp WHERE...<br /><br />10、在TRIGGER 中出现exception 不用加ROLLBACK命令<br /><br />11、oracle 不使用 read locks ,无论是 read-consistent 还是 serializable 事务所以要注意SELECT FOR UPDATE的使用<br /><br />移植方案<br /><br />一.后台存储过程利用conv72从SYBASE转换到ORACLE。<br /><br />USAGE: conv72 [-P -F -M] &lt;input_file_name&gt;<br />-P指存储过程，-F指函数<br />例如：conv72 -P filename.sql<br />转换后,产生文件名字是filename.sql.sql<br /><br /><br /><br />二.转换后的调整。<br /><br /><br />（一）后台存储过程的调整<br /><br />1、NULL <br />ORACLE对NULL 的条件判断只能用： 变量 IS NULL 和变量 IS NOT NULL；<br />对NULL 的附值只能用：变量 := NULL；<br />因此需要对所有存储过程中有关 NULL 的操作做上述相应调整。<br /><br />2、StoO_error:=0;<br />所有存储过程中，凡是对数据库做有效操作之前，包括UPDATE，DELETE，INSERT以及<br />执行子存储过程或函数，都有必要将ORACLE转化过程中自动加上的变量StoO_error清<br />零，即在操作之前加上 StoO_error:=0; 。<br /><br />3、WHEN NO_DATA_FOUND THEN StoO_error :=0;<br />所有存储过程中，对数据库做有效操作之后，通常会用IF StoO_error != 0 THEN来<br />检验操作成功与否。对于空操作，即WHERE 子句条件不满足时，ORACLE会产生例外，<br />而SYBASE 不会出错。因此为了一致，在 EXCEPTION 中 应加入<br />WHEN NO_DATA_FOUND THEN StoO_error :=0;<br /><br />4、示例：<br />StoO_error :=0;/*操作之前加上 StoO_error:=0*/<br /><br />BEGIN<br />DELETE BOAD <br />WHERE (EXCH_ID = i_exch_id) AND (SWT_ID = i_swt_id) <br />AND (FRAME_NBR = i_frame_nbr) AND (SHELF_NBR = i_shelf_nbr) <br />AND (BOAD_NBR = i_boad_nbr);<br />StoO_rowcnt := SQL%ROWCOUNT;<br />EXCEPTION<br />WHEN NO_DATA_FOUND THEN <br />StoO_error :=0;<br />WHEN OTHERS THEN<br />StoO_error := SQLCODE;<br />END;<br /><br />IF StoO_error != 0 THEN<br />BEGIN<br />ROLLBACK TO SAVEPOINT aa;<br />i_status := -1 ;<br />RETURN /* */;<br />END;<br />END IF;<br />5、事务设计<br />ORACLE的存储过程中，COMMIT 语句将会把此前未提交的所有事务都提交，且对于<br />已提交的事务，无论在后台存储过程中，还是在前台 PB 的脚本中，都无法回滚。<br />这与SYBASE 不同，因此事务应该结合后台存储过程与前台 PB 脚本设计。<br /><br />6、事务的调整<br />在ORACLE中，没有SYBASE中事务嵌套数的概念，在后台的存储过程中，遇到<br />COMMIT时，将把整个事务（包括前台和后台）全部提交。而在SYBASE中，只<br />有当事物数为最低级时（设计都在前台）才能提交。<br /><br />由于所有事务都在前台提交，<br />因此把后台存储过程中所有的COMMIT全部注释掉。<br /><br /><br /><br />7、时间参数调整<br /><br />如果该存储过程的输入参数为DATE型时，在POWERBUILDER中创建存储过程<br />时，将引发错误。<br /><br />为了解决此问题，<br /><br />在后台，将这种存储过程的DATE型输入参数 <br />全部改为VARCHAR2型。<br />在存储过程中，将VARCHAR2转化为DATE，为了前后台一致，<br />采用统一的转化格式。<br /><br />i_start_DATE:=TO_DATE(i_start_string,'YYYY/MM/DD HH24:MI:SS');<br />i_end_date :=TO_DATE(i_end_string, 'YYYY/MM/DD HH24:MI:SS');<br /><br />在前台POWERBUILDER中，将DATE或者DATETIME型变量转化为STRING型，<br />也采用上述统一格式，再作为存储过程的参数。<br /><br />v_STRING=STRING(v_DATE, 'YYYY/MM/DD HH:MM:SS')<br />v_STRING=STRING(v_DATETIME,'YYYY/MM/DD HH:MM:SS')<br /><br /><br />（二）用于数据窗口的后台存储过程的修改<br /><br />1、通过特定表返回时，WHERE子句的处理<br /><br /><br />TABLE: TEST<br /><br />COLUMN: NAME VARCHAR2(20);<br />AGE NUMBER;<br />BIRTH DATE;<br />REMARKS VARCHAR2(30);<br /><br />最后的返回语句如下，WHERE子句的处理中，对字符型和日期型进行转义处理<br /><br />PBDBMS.PUT_LINE('SELECT NAME,AGE,BIRTH,REMARKS ')<br />PBDBMS.PUT_LINE(' FROM TEST ');<br />str_where:=' WHERE NAME='|| ''''||VAR_NAME||''''<br />||'AND AGE =' || TO_CHAR(VAR_AGE)<br />||'AND BIRTH=' || ''''||TO_CHAR(VAR_BIRTH)||'''';<br />PBDBMS.PUT_LINE(str_where);<br /><br />注意：<br />如果NUMBER型变量是该存储过程的输入参数，则要对他进行<br />单独处理<br />IF VAR_AGE IS NULL THEN<br />CONV:=' AND AGE IS NULL ';<br />ELSE<br />CONV:=' AND AGE = ' || TO_CHAR(VAR_AGE);<br />END IF; <br /><br /><br />2、最后数据的返回通过表DUAL进行<br /><br />有两种方式：<br />（1）、用PBDBMS.PUT_LINE。无法处理返回值为空值的情况<br />使用方法见底下示例：<br />注意：对不同变量类型进行了不同处理。<br /><br />（2）、用PBDBMS.PUT<br />该过程已经过修改，可对各种变量类型进行处理，不在需要在程序中对<br />不同类型进行不同处理，同时也可适应NULL值的情况。<br />使用方法见底下示例：<br />注意：直接使用该参数，多个变量返回时注意中间加PUT(',');<br /><br />另外：PBDBMS包中行最大长度为255，而PUT函数不换行，因此估计<br />长度快到255时，使用PUT_LINE(',')来实现换行目的。<br /><br />PROCEDURE AAA<br />(I_SO_NBR VARCHAR2) <br />IS<br />I_NUM INTEGER;<br />i_date date;<br />I_NAME VARCHAR2(50);<br />I_COV VARCHAR2(100);<br />I_COV2 VARCHAR2(100);<br />BEGIN<br />/* 第一种方式*/<br />I_COV:= ' SELECT '||''''||I_NAME||''''||','||TO_CHAR(I_NUM)||','||''''||TO_CHAR(I_DATE)||'''';<br />I_COV2:=' FROM DUAL';<br /><br />PBDBMS.PUT_LINE(i_cov);<br />PBDBMS.PUT_LINE(I_cov2);<br /><br />/*第二种方式*/<br />PBDBMS.PUT_LINE('SELECT ');<br />PBDBMS.PUT(I_NAME);<br />PBDBMS.PUT(',');/* 如长度将超过255，此处用PUT_LINE('，')进行换行*/<br /><br />PBDBMS.PUT(I_NUM);PBDBMS.PUT(',');<br />PBDBMS.PUT(I_DATE);<br />PBDBMS.PUT_LINE(' FROM DUAL');<br /><br />END;<br /><br /><br /><br />（三）前台脚本中嵌入式SQL语句的调整<br /><br />1、ORACLE 存储过程前台脚本调用方式：<br />DECLARE sosp_cust_i PROCEDURE FOR sosp_cust_i <br />(:name,:reg_nbr,:li_cust_cat_id,<img alt="吐舌" src="http://www.itpub.net/images/smilies/13.gif" border="0" />osition, <br />null,<img alt="吐舌" src="http://www.itpub.net/images/smilies/13.gif" border="0" />arent_id) ;<br />execute sosp_cust_i;<br /><br /><br />SYBASE 存储过程前台脚本调用方式：<br />DECLARE sosp_cust_i PROCEDURE FOR sosp_cust_i <br />@name = :ls_name, <br />@reg_nbr = :ls_regnbr, <br />@cat_id = :ii_cust_cat, <br />@position = null, <br />@type_id = :ii_cust_type, <br />@parent_id = :ll_parent_id ;<br />execute sosp_cust_i;<br /><br /><br />2、前台脚本中嵌入式的SQL语句中<br />(1)NULL<br />ORACLE对NULL 的条件判断只能用： 字段名 IS NULL 和 字段名?IS NOT NULL；<br />而不能用：字段名 = NULL 和 字段名?&lt;&gt; NULL?<br />若有上述情况，应做相应调整。 <br />如：select * from so_charge where receipt_nbr = null;<br />应改为：select * from so_charge where receipt_nbr is null;<br /><br />(2)""-&gt;'' <br />ORACLE对字符串使用单引号，而SYBASE单引号、双引号均可<br />因此若有如select * from so where state="A";的语句<br />应改为select * from so where state='A';<br /><br />(3)insert -&gt; insert into<br />SYBASE允许使用insert tablename...,而ORACLE必须使用<br />insert into tablename...,若有上述情况，应做相应调整。<br /><br />(4)+ --&gt; ||<br />字符串连接，SYBASE使用'+'，而ORACLE使用'||'。?<br /><br />(5)getdate() --&gt; sysdate<br />取系统时间，SYBASE使用getdate()，而ORACLE使用sysdate。</font></p>
<img src ="http://www.blogjava.net/TrampEagle/aggbug/51022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-06-07 09:30 <a href="http://www.blogjava.net/TrampEagle/articles/51022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sybase基础知识 </title><link>http://www.blogjava.net/TrampEagle/articles/51017.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 07 Jun 2006 01:21:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/51017.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/51017.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/51017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/51017.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/51017.html</trackback:ping><description><![CDATA[
		<table class="border" cellspacing="0" cellpadding="2" width="100%" align="center" border="0">
				<tbody>
						<tr class="tdbg_leftall" align="middle">
								<td colspan="2">［ 作者：陈苏文    转贴自：http://www.chinaunix.net    点击数：9525    文章录入：<a href="http://unix-cd.com/article/ShowUserInfo.asp?UserID=2399"><font color="#3d5a83">sdccf</font></a> ］</td>
						</tr>
						<tr>
								<td colspan="2">
										<table cellspacing="5" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td valign="top" height="200">下面通过实例来对Select的通常用法加以介绍。 <br />例1：选择所有的列，语法为select * from table_list <br />如：select * from publishers <br />例2：选择指定的列，语法为 <br />select column_name[,column_name]… <br />from table_name <br />如：select pub_id,pub_name from publishers <br />例3：重命名查询结果中的列，语法为 <br />select column_heading= column_name <br />from table_name <br />如：select Publisher=pub_name,pub_id <br />from publishers <br />例4：select列表中的计算值，可以对select列表中的数值数据进行计算，下面列出了算术运算符。 <br /><br />符号运算 <br />+加 <br />-减 <br />/除 <br />*乘 <br />%取模 <br />如select title_id,total_sales,total_sales*2 from titles <br />例5：使用distinct消除重复的查询结果 <br />可选的关键词消除select语句的结果中的重复行。若不指定distinct，缺省值为all，将检索出包含重复行的所有行数据。 <br />如：select distinct au_id from titleauthor <br />例6：选择行——where语句 <br />select语句中的确切指定要检索哪些行的准则，其一般格式为： <br />select select_list from table_list where search_conditions <br />where子句中的搜索条件（或称限制）包括： <br />·比较运算符（＝，＜，＞，!=等＝ <br />如：where advance*2＞total_sales*price <br />·范围（between和not between） <br />如：where total_sales between 5000 and 10000 <br />·列表（in和not in） <br />如：where state in(“CA”,”IN”,”MD”) <br />·匹配字符（like和not like） <br />如：where phone like “0535%” <br />·未知值（is null和is not null） <br />如：where advance is null <br />·以上各项的组合（and, or） <br />如：where advance＜5000 or total_sales between 500 and 1000 <br />例7：用集合函数小结查询结果 <br />集合函数用特定列的数据来计算小结值。 <br />集合函数结 果 <br />Sum([all|distinct]expression)数值列中（不重复）值的总和 <br />Avg([all|distinct]expression)数值列中（不重复）值的平均 <br />count([all|distinct]expression)列中（不重复）非空值的数目 <br />Count(*)选定的行数 <br />Max(expression)Expression的最大值 <br />Min(expression)Expression的最小值 <br />如：select avg(advance),sum(total_sales) <br />from titles <br />where type=”as” <br />select count(*) from titles <br />select avg(distinct price) from titles <br />select max(price) from books <br />例8：分组组织查询结果——group by 子句 <br />group by 子句用在select语句中将一张表分成若干组。 <br />如：select type, advance from titles group by type <br />例9：选择分组数据——having子句 <br />having为group by 子句设置条件，与where为select语句设置条件一样。Having搜索条件与where相同，但having可包括集合函数，而where不能包括。 <br />下列语句使用带集合函数having子句的例子。它把title表中的行按类型分组，但去掉了那只包含一本书的分组。 <br />Select type from titles group by type having count(*)&gt;1 <br />下面是一个不带集合函数的having子句的例子。它把title表中的行按类型分组，但去掉了那些不以字母“p”开头的类型。 <br />Select type from titles group by type having type like “p%” <br />例10：查询结果排序——order by子句 <br />Order by子句允许按一列或多列对查询结果排序。每个排序可以是升序的（asc）或降序的(desc)。若不特别指明，则按升序进行。下列查询返回按pub_id排序的结果： <br />Select pub_id,type,title_id from titles order by pub_id <br />例11：连接——从多张表中检索数据 <br />连接两张或两张以上的表是这样一个过程：比较指定字段中的数据，根据比较结果用符合条件的行组成一张新表。 <br />举例： <br />select publishers.pub_id,publishers.pub_name,authors.* <br />from publishers,authors <br />where publishers.city=authors.city <br />例12：分组计算子句 <br />Compute是Sybase对SQL标准中Group子句的扩充，可以将其看作带聚集计算的Group子句。例如： <br />Select type,price,advance <br />From titles <br />Order by type <br />Compute sum(price),sum(advance) by type <br />2．Insert语句 <br />用Insert命令向数据库中添加行有两种方法：使用关键词values或使用select语句。 <br />Insert语句的基本语法为： <br />Insert[into]表名[（字段列表）] <br />{values（值列表）|select_statement} <br />举例：insert into publishers <br />values(‘1622’,’Jardin,Inc.’,’Camden’,’NJ’) <br />Insert into publishers(pub_id,pub_name) <br />values(‘1756’,’The Health Center’) <br />Insert authors select * from newauthors <br />Insert authors(au_id,address,au_lname,au_fname) <br />Select * from newauthors <br />3．Delect语句 <br />Delect可以对一行或多行进行操作。 <br />Delect语句的基本语法为： <br />Delect 表名 <br />[from 表名列表] <br />[where条件表达式] <br />举例：Delect publishers <br />where pub_name=”Jardin,Inc.” <br />Delect titles <br />From authors, titles <br />Where titles.title_id=authors.title_id <br />4．Update语句 <br />可以使用Update命令来改动表中的单个行、一组行或所有行。 <br />Update语句的基本语法为： <br />Update表名 <br />Set column_name1={expression1|null|(select_statement)} <br />[,column_name2={expression2|null|(select_statement)}] <br />[……] <br />[from 表名列表] <br />[where 条件表达式] <br />举例： <br />update authors set_au_lname=”Health”,aufname=”Goodbody” <br />where au_lname=”Bloth” <br />update titles <br />set total_sales=total_sales + qty <br />from titles,sales <br />where titles.title_id=sales.title_id <br />六、Sybase预定义函数 <br />1．聚集函数 <br />sum([all|distinct]表达式) <br />avg([all|distinct]表达式) <br />count([all|distinct]表达式) <br />count(*) <br />max(表达式) <br />min(表达式) <br />2．字符串函数 <br />upper(字符表达式) <br />lower(字符表达式) <br />char(整型表达式) <br />char_length(字符表达式) <br />ltrim(字符表达式) <br />rtrim(字符表达式) <br />…… <br />3．数学函数 <br />abs(精确小数型表达式) <br />floor(精确小数型表达式)求小于或等于给定表达式值的最大整数（取底） <br />rand([整数型] <br />round(精确小数型表达式,整数) <br />sign(精确小数型表达式) <br />power(精确小数型表达式,整数幂) <br />…… <br />4．日期函数 <br />getdate() <br />datepart(日期部分，日期) <br />datediff(日期部分，日期1,日期2) <br />dateadd(日期部分，数值表达式，日期) <br />5．类型转换函数 <br />convert(数据类型，表达式[，格式]) <br />6．系统函数 <br />db_name([数据库ID]) <br />host_name() <br />isnull(表达式1,表达式2) <br />…… <br />七、数据控制语言 <br />用来控制数据的安全性，如权限控制语句GRANT和REVOKE等。 <br /><br /><br />第七讲 数据库编程基础 <br /><br />一、批处理 <br />SQL Server可以处理作为一批而提交的多个SQL语句，既可以是交互式的，也可以是一个文件。批处理SQL语句由批结束标志终止，该标志指示SQL Server从前面开始执行该批处理语句，对于独立的SQL实用程序isql而言，其批结束标志为单独占一行的“go”。 <br />举例：选择表title及表authors的行数 <br />select count(*) from titles <br />select count(*) from authors <br />go <br />二、流程控制语言 <br />1．变量声明与赋值 <br />全局变量由系统预定义，以符号@@打头。 <br />局部变量声明使用Declare语句，这个变量必须以符号@开头，后跟一个标识符。 <br />Declare @变量名 数据类型[，@变量名 数据类型，……] <br />变量赋值使用Select语句，未赋值的变量其值为Null。 <br />举例： <br />Declare @msg char(50) <br />Select @msg=’How are you?’ <br />Select @msg=emp_name from employee <br />Where emp_id=12345678 <br />2．SQL语句块 <br />Begin <br />Statement Block/*多个顺序执行的SQL 语句*/ <br />End <br />3．条件语句 <br />If 条件表达式 <br />语句（块） <br />Else <br />语句（块） <br />举例： <br />if(select max(id) from sysobjects)&lt;50 <br />print ‘数据库里没有用户创建的对象‘ <br />else <br />select name,type,id from sysobjects where id&gt;50 <br />4．循环语句 <br />While 条件表达式 <br />语句（块） <br />●两个特殊的循环控制语句： <br />Continue 执行下一次循环 <br />Break 退出当前循环 <br />举例： <br />While(select avg(price) from titles)&gt;$20 <br />Begin <br />Update titles set price=price/2 <br />If(select avg(price) from titles)&lt;$40 <br />Break <br />Else <br />Continue <br />End <br />5．其它控制语句 <br />◇Return语句——无条件结束当前过程，并可返回给调用者的一个状态值：Return[整数表达式] <br />◇Print语句 <br />◇RaiseError语句 <br />◇Waitfor语句 <br />三、存储过程 <br />存储过程是存储在服务器端的一类数据库对象，它实质上是一段用SQL语言编写的程序，它在服务器端预先经过编译，并确定出执行计划，因此与同样功能的批处理语句相比，它的执行速度较快。 <br />基本语法： <br />Create Procedure[owner.]过程名 <br />[@参数名 数据类型[=默认值][Output]] <br />[，@参数名 数据类型[=默认值][Output]] <br />[……] <br />AS <br />Begin <br />SQL语句（块） <br />End <br />存储过程是数据库对象，和表、索引是一个级别的；是SQL语句和控制流语言的集合，存储过程在首次运行时被编译，并驻留在过程高速缓存的内存中，所以存储过程的招待非常快。存储过程可以带参数，可以调用其他过程，返回状态值，返回参数值，并且可以在远程SQL Server执行。可以在远程SQL Server执行对数据库设计有特别重要的意义。SQL Server提供的存储过程称为系统过程。 <br />存储过程大大增强了SQL的能力、效率和灵活性，经过编译的存储过程极大地改善SQL语句和批处理的性能。 <br />存储过程有很多优点： <br />●存储过程在第一次执行时编译，并存储在过程高速缓存的内存中。编译时系统对其进行优化，以选择最佳的路径来访问数据集中的数据，这种优化考虑了数据集的实际数据结构。因此存储过程大大提高了系统的性能。 <br />●存储过程可以跨服务器运行。这一点是通过触发器来实现的，当然，首先存储过程要能登录到该远程服务器。 <br />●应用程序也能执行存储过程，从而实现服务器和客户之间的协同作业。 <br />●存储过程减少了网络的交通。这是因为存储过程的文本存储在数据库里，调用存储过程时通过网络的只是存储过程的过程名。 <br />●利用存储过程可以提供一个附加的安全层。 <br />如（该例子取自pubs2数据库）： <br />Create proc titleid_proc(@title_id varchar(80)) <br />As <br />Begin <br />Select @title_id=lower(@title_id)+”%” <br />Select title,title_id,price <br />Form titles <br />Where lower(title_id) like @title_id <br />Return @@rowcount <br />End <br />注意例子中的黑体部分，这实际上是一条赋值语句。该存储过程有返回值。 <br />存储过程可以变得非常复杂。我们认为，创建存储过程还是要遵循“最简单就是最好”的原则。建议在创建存储过程时采用缩进风格，否则创建的存储过程三天之后连自己都看不懂。 <br />需要对存储过程作些说明： <br />●Create procedure 语句不能和其他语句在同一个批命令里。 <br />●Create procedure 语句不能包括下列语句： <br />use <br />Create View <br />Create default <br />Create rule <br />Create trigger <br />Create procedure <br />不能使用use语句好理解，存储过程是针对数据库的，不能在一个数据库里访问另外的数据库。如果在存储过程里访问另外的数据库，则数据库表的参照完整性难于得到保障。 <br />从另外几条语句看，在存储过程里一般不能创建新的数据库对象。但可以创建表和索引，以及和表相关联的键，表是临时表，在存储过程结束后不能看见创建的临时表；否则的话每运行一次存储过程就创建一个表，结果可想而知。 <br />存储过程里不能创建一个对象，删除它；然后又在同一存储过程里用相同的名字创建新的对象。实际上，SQL Server在存储过程运行时而不是在编译时创建对象的。 <br />●如果存储过程调用另外的存储过程，则第二个存储过程可以调用在第一个存储过程里创建的对象。 <br />●存储过程包含的最多参数为255个，对存储过程里的局部和全局变量没有限制。 <br />最后讨论一下系统存储过程。系统存储过程以sp_开头，当然用户创建的存储过程也可以以sp_开头；?/span&gt; </td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/TrampEagle/aggbug/51017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-06-07 09:21 <a href="http://www.blogjava.net/TrampEagle/articles/51017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sybase存储过程的建立和使用</title><link>http://www.blogjava.net/TrampEagle/articles/51016.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 07 Jun 2006 01:19:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/51016.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/51016.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/51016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/51016.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/51016.html</trackback:ping><description><![CDATA[存储过程的特点 <br /><br />　　Sybase的存储过程是集中存储在SQL Server中的预先定义且已经编译好的事务。存储过程由SQL语句和流程控制语句组成。它的功能包括:接受参数;调用另一过程;返回一个状态值给调用过程或批处理,指示调用成功或失败;返回若干个参数值给调用过程或批处理,为调用者提供动态结果;在远程SQL Server中运行等。 <br /><br />　　 <br /><br />　　存储过程的性能特点如下: <br /><br />　　·存储过程是预编译过的,这就意味着它与普通的SQL语句或批处理的SQL语句不同,当首次运行一个存储过程时,SQL Server的查询处理器对其进行分析,在排除了语法错误之后形成存储在系统中的可执行方案。由于查询处理的大部分工作已经完成,所以存储过程执行速度很快。 <br /><br />　　·存储过程和待处理的数据都放在同一台运行SQL Server的计算机上,使用存储过程查询当地的数据,效率自然很高。 <br /><br />　　·存储过程一般多由Client端通过存储过程的名字进行调用,即跨网传送的只是存储过程的名字及少量的参数(如果有的话),而不是构成存储过程的许多SQL语句,因此可以减少网络传输量,加快系统响应速度。 <br /><br />　　·存储过程还有着如同C语言子函数那样的被调用和返回值的方便特性。 <br /><br />　　所以,存储过程大大增强了SQL语言的功能、效率和灵活性。掌握和应用好存储过程,对进一步发挥Sybase数据库系统的强大功能有着重要的意义。 <br /><br />　　 <br /><br />　　存储过程的语法规则 <br /><br />　　建立存储过程的语法规则为: <br /><br />　　CREATE PROCedure[owner.]procedurename[;number] <br /><br />　　[[(]@parameter_name datatype[=default][OUTput] <br /><br />　　[,@parameter_name datatype[=default][OUTput]]...[)]] <br /><br />　　[WITH RECOMPILE] <br /><br />　　AS SQL_statements <br /><br />　　使用存储过程的语法规则为: <br /><br />　　[EXECute][@return-status=] <br /><br />　　[[[server.]database.]owner.]procedurename[;number] <br /><br />　　[[@parameter_name=]value¦[@parameter_name=]@varialbe[OUTput] <br /><br />　　[,[@parameter_name=]value¦[@parameter_name=]@variable[OUTput]...]] <br /><br />　　[WITH RECOMPILE] <br /><br />　　下面简要介绍这两个命令的常用选项以及建立和使用存储过程的要点,关于选项的更为详细的说明请参考有关手册。 <br /><br />　　·[[[server.]database.]owner.]procedure_name:存储过程的名字。 <br /><br />　　·@parameter_name datatype[=default][OUTput]:形式参数(形参)的名称、类型。df ault是赋予的缺省值(可选),OUTput指定本参数为输出参数(可选)。形参是存储过程中的自变量,可以有多个,名字必须以@打头,最长30个字符。 <br /><br />　　·SQL_statements:定义存储过程功能的SQL语句。 <br /><br />　　·@return_status:接受存储过程返回状态值的变量。 <br /><br />　　·[@parameter_name=]value:实际参数(实参),@parameter_name为实参的名称(可选)。如果某个实参以@parameter_name=value提供,那么随后的实参也都要采用这一形式提供。 <br /><br /><br /><br />　　·[@parameter_name=]@varialbe[OUTput]:将变量@varialbe中的值作为实参传递给形参@parameter_name(可选),如果变量@varialbe是用来接受返回的参数值,则选项OUTput不可缺少。 <br /><br />　　 <br /><br />　　存储过程的建立和使用,我们将通过几个例子进行介绍。 <br /><br />　　假设有一个用下述语句生成的技能工资表RS-LS-GZ-JiNeng: <br /><br />　　create table RS_LS_GZ_JiNeng　　　　 /*技能工资表*/ <br /><br />　　(GeRen_id char(4),　　　　　　　　 /*个人代码 */ <br /><br />　　RiQi smalldatetime,　　　　　　　　 /*执行日期 */ <br /><br />　　YuanYin_id char(1) null,　　　　　　 /*变动原因代码 */ <br /><br />　　JinE smallmoney)　　　　　　　　　　 /*技能工资金额 */ <br /><br />　　该表存储着某单位员工多年来技能工资的历史档案。 <br /><br />　　例1.如果要查询全体员工的技能工资变动历史,则可先建立一个存储过程p-RsGz-JiNeg-All: <br /><br />　　create procedure p_RsGz_JiNeng_All as <br /><br />　　select * <br /><br />　　from RS_LS_GZ_JiNeng <br /><br />　　order by GeRenid,RiQi <br /><br />　　然后用批处理语句调用存储过程p_RsGz_JiNeng_All进行查询: <br /><br />　　execute p_RsGz_JiNeng_All <br /><br />　　本例只显示查询到的数据,无输入、输出参量,是最简单的一个存储过程。 <br /><br />　　例2.如果要查询某人技能工资的变动历史,可建立另一个存储过程p_RsGz_JiNeng: <br /><br />　　create procedure p_RsGz_JiNeng @c_GeRenId char(4) <br /><br />　　as <br /><br />　　select *from RS_LS_GZ_JiNeng <br /><br />　　where GeRen_id=@c_GeRenId <br /><br />　　order by RiQi <br /><br />　　之后用批处理语句调用存储过程p_Rs_Gz_JiNeng进行查询: <br /><br />　　declare @GeRenId char(4) <br /><br />　　select @GeRenId="0135" /*设要查询员工的个人代码为"0135" */ <br /><br />　　execute p_RsGz_JeNeng @c_GeRenId=@GeRenId <br /><br />　　存储过程p_RsGz_JiNeng中定义了一个形参@c_GeRenId,是字符型变量。在调用该过程的批处理中,既可以用具体的值也可以用变量作为实参。用变量作实参(如本例)时,必须用del are语句加以说明。值得注意的是,在批处理的调用过程语句中,@c_GeRenId=@GeRenId中的@ c_GeRenId是存储过程p_RsGz_JiNeng中的形参名,不是批处理中的变量,所以不能将它列入d eclare语句的变量单中。 <br /><br />　　例3.如果要计算当月工资,就必须从工资历史中查出员工距离当前最近的一次技能工资变动的结果: <br /><br />　　create procedure p_RsGz_JiNeng_Slt <br /><br />　　(@c_GeRenId char(4),@sm_JinE smallmoney output) <br /><br />　　as <br /><br />　　select @sm_JinE=JinE <br /><br />　　from RS_LS_GZ_JiNeng <br /><br />　　where RiQi=(select max(RiQi) <br /><br />　　from RS_LS_GZ_JiNeng <br /><br />　　where GeRenid=@c-GeRenId)/*找出历史记录中距离当前最近的日期*/ <br /><br />　　调用存储过程p_RsGz_JiNeng_Slt进行查询: <br /><br />　　declare @GeRenId char(4),@JinE smallmoney <br /><br />　　select @GeRenid="0135"/*设要查询员工的个人代码为"0135"*/ <br /><br />　　select @JinE=0 <br /><br />　　execute p_RsGz_JiNeng_slt @c_GeRenId=@GeRenId,@sm_JinE=@ JinE output <br /><br />　　这里,变量 @JinE用来存储过程形参@sm_JinE传回的金额。在调用过程语句中,@sm_JiE = @JinE output中的output不可省略。否则,变量@JinE将得不到形参传回的数值而始终为零(等于初值)。 <br /><br />　　例4.查到了个人代码为"0135"员工的技能工资就显示其历史纪录,查不到则显示一条出错信息。 <br /><br />　　create procedure p_RsGz_JiNeng_Rtn <br /><br />　　@c_GeRenId char(4) <br /><br />　　as <br /><br />　　declare @ErrCode smallint <br /><br />　　select @ErrCode=0 <br /><br />　　if exists(select* from RS-LS-GZ-JiNeng <br /><br />　　 where GeRenid=@c-GeRenId) <br /><br />　　 begin <br /><br />　　　　select * <br /><br />　　　　from RS_LS_GZ_JiNeng <br /><br />　　　　whrer GeRen_id=@c_GeRenId <br /><br />　　　　order by RiQi <br /><br />　　　　return @ErrCode <br /><br />　　 end <br /><br />　　esle <br /><br />　　 begin <br /><br />　　　　select @ErrCode=1 <br /><br />　　　　return @ErrCode <br /><br />　　 end <br /><br />　　调用存储过程p_RsGz_JiNeng_Rtn: <br /><br />　　declare @GeRenId char(4),@RtnCode smallint <br /><br />　　select @GeRenId="0135" <br /><br />　　select @RtnCode=0 <br /><br />　　execute @RtnCode=p_RsGz_JiNeng_Rtn @c_GeRenId=@GeRenId <br /><br />　　if @RtnCode=1 <br /><br />　　 print"No this one!" <br /><br />　　存储过程p_RsGz_JiNeng_Rtn向调用者返回一个存储在变量@ErrCode里的值,这个值被称为状态值,它向调用者反映存储过程执行的成败状态。在本例中,如果查不到指定员工技能工资的任何记录时,就认为"查无此人",返回出错状态值1。否则,返回成功状态值0。 <br /><br />　　调用过程的批处理语句使用变量@RtnCode存储返回的状态值,一旦检出存储过程p_RsG_ JiNeng_Rtn返回了错误标志(@RtnCode=1),就显示一条信息"No this one!"。 <br /><br />　　小结 <br /><br />　　上述四个例子简要介绍了存储过程常用的几种形式,从中我们已经可以领略到它的编程特色以及使用上的灵活性和方便性。 <br /><br />　　虽然上述例子在调用存储过程时都是用SQL的批处理语句实现的,但并不意味着这是唯一的方法。例如在存储过程中调用存储过程(即所谓过程嵌套)的现象就很常见。另外,在其它Sybase数据库开发系统 (如PowerBuilder)的 script语句中调用Sybase的存储过程也非常普遍。<img src ="http://www.blogjava.net/TrampEagle/aggbug/51016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-06-07 09:19 <a href="http://www.blogjava.net/TrampEagle/articles/51016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JAVA中的动态代理实现数据库连接池</title><link>http://www.blogjava.net/TrampEagle/articles/45566.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 10 May 2006 15:23:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/45566.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/45566.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/45566.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/45566.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/45566.html</trackback:ping><description><![CDATA[附：其实，很多时候，原理大家也都很清楚，但是很多人就是懒的总结出来，我就是一个例子，看到这篇文章后，转载于此，一是学习，二是鞭策。下面是原文。<br /><br />原文引自：<a href="http://www-128.ibm.com/developerworks/cn/java/l-connpoolproxy/">http://www-128.ibm.com/developerworks/cn/java/l-connpoolproxy/</a><br /><br /><br /><br /><blockquote>作者通过使用JAVA中的动态代理实现数据库连接池，使使用者可以以普通的jdbc连接的使用习惯来使用连接池。</blockquote><!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES--><p>数据库连接池在编写应用服务是经常需要用到的模块，太过频繁的连接数据库对服务性能来讲是一个瓶颈，使用缓冲池技术可以来消除这个瓶颈。我们可以在互联网上找到很多关于数据库连接池的源程序，但是都发现这样一个共同的问题：这些连接池的实现方法都不同程度地增加了与使用者之间的耦合度。很多的连接池都要求用户通过其规定的方法获取数据库的连接，这一点我们可以理解，毕竟目前所有的应用服务器取数据库连接的方式都是这种方式实现的。但是另外一个共同的问题是，它们同时不允许使用者显式的调用Connection.close()方法，而需要用其规定的一个方法来关闭连接。这种做法有两个缺点：</p><p>第一：改变了用户使用习惯，增加了用户的使用难度。</p><p>首先我们来看看一个正常的数据库操作过程：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">int executeSQL(String sql) throws SQLException
{
	Connection conn = getConnection();	//通过某种方式获取数据库连接
	PreparedStatement ps = null;
	int res = 0;
	try{
		ps = conn.prepareStatement(sql);
		res = ps.executeUpdate();
}finally{
try{
ps.close();
}catch(Exception e){}
try{
	conn.close();//
}catch(Exception e){}
}
return res;
}
</font></code></pre></td></tr></tbody></table><br /><p>使用者在用完数据库连接后通常是直接调用连接的方法close来释放数据库资源，如果用我们前面提到的连接池的实现方法，那语句conn.close()将被某些特定的语句所替代。</p><p>第二：使连接池无法对之中的所有连接进行独占控制。由于连接池不允许用户直接调用连接的close方法，一旦使用者在使用的过程中由于习惯问题直接关闭了数据库连接，那么连接池将无法正常维护所有连接的状态，考虑连接池和应用由不同开发人员实现时这种问题更容易出现。</p><p>综合上面提到的两个问题，我们来讨论一下如何解决这两个要命的问题。</p><p>首先我们先设身处地的考虑一下用户是想怎么样来使用这个数据库连接池的。用户可以通过特定的方法来获取数据库的连接，同时这个连接的类型应该是标准的java.sql.Connection。用户在获取到这个数据库连接后可以对这个连接进行任意的操作，包括关闭连接等。</p><p>通过对用户使用的描述，怎样可以接管Connection.close方法就成了我们这篇文章的主题。</p><p>为了接管数据库连接的close方法，我们应该有一种类似于钩子的机制。例如在Windows编程中我们可以利用Hook API来实现对某个Windows API的接管。在JAVA中同样也有这样一个机制。JAVA提供了一个Proxy类和一个InvocationHandler，这两个类都在java.lang.reflect包中。我们先来看看SUN公司提供的文档是怎么描述这两个类的。</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">public interface InvocationHandler

InvocationHandler is the interface implemented by the invocation handler of a proxy instance. 

Each proxy instance has an associated invocation handler. 
When a method is invoked on a proxy instance, 
the method invocation is encoded and dispatched to the invoke method of its invocation handler.
</font></code></pre></td></tr></tbody></table><br /><p>SUN的API文档中关于Proxy的描述很多，这里就不罗列出来。通过文档对接口InvocationHandler的描述我们可以看到当调用一个Proxy实例的方法时会触发Invocationhanlder的invoke方法。从JAVA的文档中我们也同时了解到这种动态代理机制只能接管接口的方法，而对一般的类无效，考虑到java.sql.Connection本身也是一个接口由此就找到了解决如何接管close方法的出路。</p><p>首先，我们先定义一个数据库连接池参数的类，定义了数据库的JDBC驱动程序类名，连接的URL以及用户名口令等等一些信息，该类是用于初始化连接池的参数，具体定义如下：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">public class ConnectionParam implements Serializable
{
	private String driver;				//数据库驱动程序
	private String url;					//数据连接的URL
	private String user;					//数据库用户名
	private String password;				//数据库密码
	private int minConnection = 0;		//初始化连接数
	private int maxConnection = 50;		//最大连接数
	private long timeoutValue = 600000;//连接的最大空闲时间
	private long waitTime = 30000;		//取连接的时候如果没有可用连接最大的等待时间
</font></code></pre></td></tr></tbody></table><br /><p>其次是连接池的工厂类ConnectionFactory，通过该类来将一个连接池对象与一个名称对应起来，使用者通过该名称就可以获取指定的连接池对象，具体代码如下：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">/**
 * 连接池类厂，该类常用来保存多个数据源名称合数据库连接池对应的哈希
 * @author liusoft
 */
public class ConnectionFactory
{
	//该哈希表用来保存数据源名和连接池对象的关系表
	static Hashtable connectionPools = null;
	static{
		connectionPools = new Hashtable(2,0.75F);
	} 
	/**
	 * 从连接池工厂中获取指定名称对应的连接池对象
	 * @param dataSource	连接池对象对应的名称
	 * @return DataSource	返回名称对应的连接池对象
	 * @throws NameNotFoundException	无法找到指定的连接池
	 */
	public static DataSource lookup(String dataSource) 
		throws NameNotFoundException
	{
		Object ds = null;
		ds = connectionPools.get(dataSource);
		if(ds == null || !(ds instanceof DataSource))
			throw new NameNotFoundException(dataSource);
		return (DataSource)ds;
	}

	/**
	 * 将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池
	 * @param name		对应连接池的名称
	 * @param param	连接池的配置参数，具体请见类ConnectionParam
	 * @return DataSource	如果绑定成功后返回连接池对象
	 * @throws NameAlreadyBoundException	一定名字name已经绑定则抛出该异常
	 * @throws ClassNotFoundException		无法找到连接池的配置中的驱动程序类
	 * @throws IllegalAccessException		连接池配置中的驱动程序类有误
	 * @throws InstantiationException		无法实例化驱动程序类
	 * @throws SQLException				无法正常连接指定的数据库
	 */
	public static DataSource bind(String name, ConnectionParam param)
		throws NameAlreadyBoundException,ClassNotFoundException,
				IllegalAccessException,InstantiationException,SQLException
	{
		DataSourceImpl source = null;
		try{
			lookup(name);
			throw new NameAlreadyBoundException(name);
		}catch(NameNotFoundException e){
			source = new DataSourceImpl(param);
			source.initConnection();
			connectionPools.put(name, source);
		}
		return source;
	}
	/**
	 * 重新绑定数据库连接池
	 * @param name		对应连接池的名称
	 * @param param	连接池的配置参数，具体请见类ConnectionParam
	 * @return DataSource	如果绑定成功后返回连接池对象
	 * @throws NameAlreadyBoundException	一定名字name已经绑定则抛出该异常
	 * @throws ClassNotFoundException		无法找到连接池的配置中的驱动程序类
	 * @throws IllegalAccessException		连接池配置中的驱动程序类有误
	 * @throws InstantiationException		无法实例化驱动程序类
	 * @throws SQLException				无法正常连接指定的数据库
	 */
	public static DataSource rebind(String name, ConnectionParam param)
		throws NameAlreadyBoundException,ClassNotFoundException,
				IllegalAccessException,InstantiationException,SQLException
	{
		try{
			unbind(name);
		}catch(Exception e){}
		return bind(name, param);
	}
	/**
	 * 删除一个数据库连接池对象
	 * @param name
	 * @throws NameNotFoundException
	 */
	public static void unbind(String name) throws NameNotFoundException
	{
		DataSource dataSource = lookup(name);
		if(dataSource instanceof DataSourceImpl){
			DataSourceImpl dsi = (DataSourceImpl)dataSource;
			try{
				dsi.stop();
				dsi.close();
			}catch(Exception e){
			}finally{
				dsi = null;
			}
		}
		connectionPools.remove(name);
	}
	
}
</font></code></pre></td></tr></tbody></table><br /><p>ConnectionFactory主要提供了用户将将连接池绑定到一个具体的名称上以及取消绑定的操作。使用者只需要关心这两个类即可使用数据库连接池的功能。下面我们给出一段如何使用连接池的代码：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">	String name = "pool";
	String driver = " sun.jdbc.odbc.JdbcOdbcDriver ";
	String url = "jdbc:odbc:datasource";
	ConnectionParam param = new ConnectionParam(driver,url,null,null);
	param.setMinConnection(1);
	param.setMaxConnection(5);
	param.setTimeoutValue(20000);
	ConnectionFactory.bind(name, param);
	System.out.println("bind datasource ok.");
	//以上代码是用来登记一个连接池对象，该操作可以在程序初始化只做一次即可
	//以下开始就是使用者真正需要写的代码
	DataSource ds = ConnectionFactory.lookup(name);
	try{
		for(int i=0;i&lt;10;i++){
			Connection conn = ds.getConnection();
			try{
				testSQL(conn, sql);
			}finally{
				try{
					conn.close();
				}catch(Exception e){}
			}
		}
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		ConnectionFactory.unbind(name);
		System.out.println("unbind datasource ok.");
		System.exit(0);
	}
</font></code></pre></td></tr></tbody></table><br /><p>从使用者的示例代码就可以看出，我们已经解决了常规连接池产生的两个问题。但是我们最最关心的是如何解决接管close方法的办法。接管工作主要在ConnectionFactory中的两句代码：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">source = new DataSourceImpl(param);
source.initConnection();
</font></code></pre></td></tr></tbody></table><br /><p>DataSourceImpl是一个实现了接口javax.sql.DataSource的类，该类维护着一个连接池的对象。由于该类是一个受保护的类，因此它暴露给使用者的方法只有接口DataSource中定义的方法，其他的所有方法对使用者来说都是不可视的。我们先来关心用户可访问的一个方法getConnection</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">/**
 * @see javax.sql.DataSource#getConnection(String,String)
 */
	public Connection getConnection(String user, String password) throws SQLException 
	{
		//首先从连接池中找出空闲的对象
		Connection conn = getFreeConnection(0);
		if(conn == null){
			//判断是否超过最大连接数,如果超过最大连接数
			//则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接
			if(getConnectionCount() &gt;= connParam.getMaxConnection())
				conn = getFreeConnection(connParam.getWaitTime());
			else{//没有超过连接数，重新获取一个数据库的连接
				connParam.setUser(user);
				connParam.setPassword(password);
				Connection conn2 = DriverManager.getConnection(connParam.getUrl(), 
				user, password);
				//代理将要返回的连接对象
				_Connection _conn = new _Connection(conn2,true);
				synchronized(conns){
					conns.add(_conn);
				}
				conn = _conn.getConnection();
			}
		}
		return conn;
	}
	/**
	 * 从连接池中取一个空闲的连接
	 * @param nTimeout	如果该参数值为0则没有连接时只是返回一个null
	 * 否则的话等待nTimeout毫秒看是否还有空闲连接，如果没有抛出异常
	 * @return Connection
	 * @throws SQLException
	 */
	protected synchronized Connection getFreeConnection(long nTimeout) 
		throws SQLException
	{
		Connection conn = null;
		Iterator iter = conns.iterator();
		while(iter.hasNext()){
			_Connection _conn = (_Connection)iter.next();
			if(!_conn.isInUse()){
				conn = _conn.getConnection();
				_conn.setInUse(true);				
				break;
			}
		}
		if(conn == null &amp;&amp; nTimeout &gt; 0){
			//等待nTimeout毫秒以便看是否有空闲连接
			try{
				Thread.sleep(nTimeout);
			}catch(Exception e){}
			conn = getFreeConnection(0);
			if(conn == null)
				throw new SQLException("没有可用的数据库连接");
		}
		return conn;
	}
</font></code></pre></td></tr></tbody></table><br /><p>DataSourceImpl类中实现getConnection方法的跟正常的数据库连接池的逻辑是一致的，首先判断是否有空闲的连接，如果没有的话判断连接数是否已经超过最大连接数等等的一些逻辑。但是有一点不同的是通过DriverManager得到的数据库连接并不是及时返回的，而是通过一个叫_Connection的类中介一下，然后调用_Connection.getConnection返回的。如果我们没有通过一个中介也就是JAVA中的Proxy来接管要返回的接口对象，那么我们就没有办法截住Connection.close方法。</p><p>终于到了核心所在，我们先来看看_Connection是如何实现的，然后再介绍是客户端调用Connection.close方法时走的是怎样一个流程，为什么并没有真正的关闭连接。</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">/**
 * 数据连接的自封装，屏蔽了close方法
 * @author Liudong
 */
class _Connection implements InvocationHandler
{
	private final static String CLOSE_METHOD_NAME = "close";
	private Connection conn = null;
	//数据库的忙状态
	private boolean inUse = false;
	//用户最后一次访问该连接方法的时间
	private long lastAccessTime = System.currentTimeMillis();
	
	_Connection(Connection conn, boolean inUse){
		this.conn = conn;
		this.inUse = inUse;
	}
	/**
	 * Returns the conn.
	 * @return Connection
	 */
	public Connection getConnection() {
		//返回数据库连接conn的接管类，以便截住close方法
		Connection conn2 = (Connection)Proxy.newProxyInstance(
			conn.getClass().getClassLoader(),
			conn.getClass().getInterfaces(),this);
		return conn2;
	}
	/**
	 * 该方法真正的关闭了数据库的连接
	 * @throws SQLException
	 */
	void close() throws SQLException{
		//由于类属性conn是没有被接管的连接，因此一旦调用close方法后就直接关闭连接
		conn.close();
	}
	/**
	 * Returns the inUse.
	 * @return boolean
	 */
	public boolean isInUse() {
		return inUse;
	}

	/**
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
	 */
	public Object invoke(Object proxy, Method m, Object[] args) 
		throws Throwable 
	{
		Object obj = null;
		//判断是否调用了close的方法，如果调用close方法则把连接置为无用状态
		if(CLOSE_METHOD_NAME.equals(m.getName()))
			setInUse(false);		
		else
			obj = m.invoke(conn, args);	
		//设置最后一次访问时间，以便及时清除超时的连接
		lastAccessTime = System.currentTimeMillis();
		return obj;
	}
		
	/**
	 * Returns the lastAccessTime.
	 * @return long
	 */
	public long getLastAccessTime() {
		return lastAccessTime;
	}

	/**
	 * Sets the inUse.
	 * @param inUse The inUse to set
	 */
	public void setInUse(boolean inUse) {
		this.inUse = inUse;
	}
}
</font></code></pre></td></tr></tbody></table><br /><p>一旦使用者调用所得到连接的close方法，由于用户的连接对象是经过接管后的对象，因此JAVA虚拟机会首先调用_Connection.invoke方法，在该方法中首先判断是否为close方法，如果不是则将代码转给真正的没有被接管的连接对象conn。否则的话只是简单的将该连接的状态设置为可用。到此您可能就明白了整个接管的过程，但是同时也有一个疑问：这样的话是不是这些已建立的连接就始终没有办法真正关闭？答案是可以的。我们来看看ConnectionFactory.unbind方法，该方法首先找到名字对应的连接池对象，然后关闭该连接池中的所有连接并删除掉连接池。在DataSourceImpl类中定义了一个close方法用来关闭所有的连接，详细代码如下：</p><table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1"><tbody><tr><td><pre><code class="section"><font face="Lucida Console">	/**
	 * 关闭该连接池中的所有数据库连接
	 * @return int 返回被关闭连接的个数
	 * @throws SQLException
	 */
	public int close() throws SQLException
	{
		int cc = 0;
		SQLException excp = null;
		Iterator iter = conns.iterator();
		while(iter.hasNext()){
			try{
				((_Connection)iter.next()).close();
				cc ++;
			}catch(Exception e){
				if(e instanceof SQLException)
					excp = (SQLException)e;
			}
		}
		if(excp != null)
			throw excp;
		return cc;
	}
</font></code></pre></td></tr></tbody></table><br /><p>该方法一一调用连接池中每个对象的close方法，这个close方法对应的是_Connection中对close的实现，在_Connection定义中关闭数据库连接的时候是直接调用没有经过接管的对象的关闭方法，因此该close方法真正的释放了数据库资源。</p><p>以上文字只是描述了接口方法的接管，具体一个实用的连接池模块还需要对空闲连接的监控并及时释放连接，详细的代码请参照附件。</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/45566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-05-10 23:23 <a href="http://www.blogjava.net/TrampEagle/articles/45566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hsql的入门</title><link>http://www.blogjava.net/TrampEagle/articles/40267.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Mon, 10 Apr 2006 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/40267.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/40267.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/40267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/40267.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/40267.html</trackback:ping><description><![CDATA[来源：中国软件 作者： jwsh1984 <br /><br />原文引自：<a href="http://www.webs520.com/read.php?wid=1047">http://www.webs520.com/read.php?wid=1047</a><br /><br /><span class="pg" id="xydwtext">   前言：该文章只是简单介绍一下hsql的入门内容，如果想仔细了解的话，参考官方帮助文档最为有用。<br /><br />一、简介：<br />hsql数据库是一款纯Java编写的免费数据库，许可是BSD-style的协议，如果你是使用Java编程的话，不凡考虑一下使用它，相对其他数据库来说，其体积小，才563kb。仅一个hsqldb.jar文件就包括了数据库引擎，数据库驱动，还有其他用户界面操作等内容。在Java开源世界里，hsql是极为受欢迎的（就Java本身来说），JBoss应用程序服务器默认也提供了这个数据库引擎。由于其体积小的原因，又是纯Java设计，又支持SQL99，SQL2003大部分的标准，所以也是作为商业应用程序展示的一种选择。请到以下地址下载hsql： <a href="http://prdownloads.sourceforge.net/hsqldb/hsqldb_1_7_3_3.zip?download">http://prdownloads.sourceforge.net/hsqldb/hsqldb_1_7_3_3.zip?download</a><br /><br />二、使用hsql数据库：<br />1、hsql数据库引擎有几种服务器模式：常用的Server模式、WebServer模式、Servlet模式、Standlone模式、Memory-Only数据库。<br />2、最为常用的Server模式：<br />1)首先却换到lib文件夹下，运行java -cp hsqldb.jar org.hsqldb.Server -database.0 db/mydb -dbname.0 xdb<br />执行命令后，将会在db文件夹下创建一个数据库mydb，别名（用于访问数据库）是xdb，如果存在mydb数据库，将会打开它。<br />2)运行数据库界面操作工具：java -cp hsqldb.jar org.hsqldb.util.DatabaseManager<br />在Type选项里选上相应的服务器模式，这里选择HSQL Database Engine Server模式；Driver不用修改；URL修改为jdbc:hsqldb:hsql://localhost/xdb （主要这里xdb就是上面我们设置的别名）;user里设置用户名，第一次登录时，设置的是管理员的用户名，password设置密码。然后点击Ok。<br />3)第一次运行数据库引擎，创建数据库完毕。好了，你可以打开db文件夹，会发现里面多了几个文件。<br />mydb.properties文件：是关于数据库的属性文件。<br />mydb.script：hsql主要保存的表（这里按hsql的说法是Memory表，就是最为常用的），里面的格式都是文本格式，可以用文本查看，里面的语句都是sql语句，熟悉sql语句的话，你也可以手动修改它。每次运行数据库引擎的话都是从这里加载进内存的。<br />mydb.lck表示数据库处于打开状态。<br />其他的请参看hsqldb包里的手册。<br /><br />3、WebServer模式和Server运行模式基本一样，只是支持了Http等协议，主要用于防火墙，默认端口是9001。启动Server，java -cp hsqldb.jar org.hsqldb.WebServer ...剩余的和上面的一致。<br /><br />4、Servlet模式可以允许你通过Servlet容器来访问数据库，请查看<tt class="filename"><font face="新宋体">hsqlServlet.java的源代码，和WebServer类似。<br /><br />5、另一个值得思考的模式是</font></tt>Standalone模式：不能通过网络来访问数据库，主要是在一个JVM中使用，那样的话，访问的速度会更加快。虽然文档里面提到主要是用于开发时使用，但是我们可以假设一下，该方法不需要一个引擎类的东西，而类似于打开文件的方式，返回一个Connection对象：<br />Connection c = DriverManager.getConnection("jdbc:hsqldb:file:mydb", "sa", "");<br />将会在当前目录找到mydb数据库相关文件，打开并返回一个Connection对象。该方式有点好处就是可以不使用引擎，在需要的时候操作数据。所以那些对数据库不是特别有要求的，但又需要一个操作数据库的方式的话，可以使用这种方法。对于那些不想额外在数据库引擎花费金钱的话，可以使用这种方法。但是不推荐使用该方法。记得Hibernate里SessionFactory可以使用openSession(Connecttion c)来获得一个Session对象的，因此，在测试或者实际应用的话都可以这样使用。<br /><br />6、Memory-Only 数据库：顾名思义，主要是内存中使用，不用于保存数据。可以用于在内存中交换数据。<br /><br />三、具体的链接与操作的话，和一般的JDBC操作一样。而相应的Server模式的话，连接地址主要你运行数据库界面操作工具时，在URL一栏时默认已经设好了，自己实习一下，对比其中参数。<br /></span><img src ="http://www.blogjava.net/TrampEagle/aggbug/40267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-04-10 17:03 <a href="http://www.blogjava.net/TrampEagle/articles/40267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何彻底删除Oracle</title><link>http://www.blogjava.net/TrampEagle/articles/33146.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 02 Mar 2006 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/33146.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/33146.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/33146.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/33146.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/33146.html</trackback:ping><description><![CDATA[摘自：<A href="http://searchdatabase.techtarget.com.cn/askexperts/231/2201731.shtml?ticket=ST-40901-Hvt7v4aSdpshclGwi9aA">http://searchdatabase.techtarget.com.cn/askexperts/231/2201731.shtml?ticket=ST-40901-Hvt7v4aSdpshclGwi9aA</A><BR><BR>
<P>　　软件环境:</P>
<P>　　1、<A class=bluekey href="http://www.yesky.com/key/1632/146632.html" target=_blank>Windows 2000</A>+ORACLE 8.1.7</P>
<P>　　2、ORACLE安装路径为:C:\ORACLE</P>
<P>　　实现方法:</P>
<P>　　1、 开始-&gt;设置-&gt;控制面板-&gt;管理工具-&gt;服务 停止所有Oracle服务。</P>
<P>　　2、 开始-&gt;程序-&gt;Oracle - OraHome81-&gt;Oracle Installation Products-&gt; Universal <A class=bluekey href="http://www.yesky.com/key/3060/148060.html" target=_blank>Installer</A> 卸装所有Oracle产品，</P>
<P>　　但Universal Installer本身不能被删除</P>
<P>　　3、 运行regedit，选择HKEY_LOCAL_MACHINE\<A class=bluekey href="http://www.yesky.com/key/511/160511.html" target=_blank>SOFTWARE</A>\ORACLE，按del键删除这个入口。</P>
<P>　　4、 运行regedit，选择HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\<A class=bluekey href="http://www.yesky.com/key/1996/161996.html" target=_blank>Services</A>，滚动 这个列表，删除所有Oracle入口。</P>
<P>　　5、 运行refedit， HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application， 删除所有Oracle入口。</P>
<P>　　6、 开始-&gt;设置-&gt;控制面板-&gt;系统-&gt;高级-&gt;环境变量 删除环境变量CLASSPATH和PATH中有关Oracle的设定</P>
<P>　　7、 从桌面上、STARTUP(启动)组、程序菜单中，删除所有有关Oracle的组和图标</P>
<P>　　8、 删除\Program Files\Oracle目录</P>
<P>　　9、 重新启动计算机，重起后才能完全删除Oracle所在目录</P>
<P>　　10、 删除与Oracle有关的文件，选择Oracle所在的缺省目录C:\Oracle，</P>
<P>　　删除这个入 口目录及所有子目录，并从Windows 2000目录(一般为C:\WINNT)下</P>
<P>　　删除以下文 件ORACLE.INI、oradim73.INI、oradim80.INI、oraodbc.ini等等。</P>
<P>　　11、 WIN.INI文件中若有[ORACLE]的标记段，删除该段</P>
<P>　　12、 如有必要，删除所有Oracle相关的ODBC的DSN</P>
<P>　　13、 到事件查看器中，删除Oracle相关的日志</P>
<P>　　说明: 如果有个别DLL文件无法删除的情况，则不用理会，重新启动，开始新的安装，</P>
<P>　　安装时，选择一个新的目录，则，安装完毕并重新启动后，老的目录及文件就可以删除掉了。</P></A><img src ="http://www.blogjava.net/TrampEagle/aggbug/33146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-03-02 10:58 <a href="http://www.blogjava.net/TrampEagle/articles/33146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle触发器在MIS 开发中的应用</title><link>http://www.blogjava.net/TrampEagle/articles/32623.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Mon, 27 Feb 2006 05:23:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32623.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32623.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32623.html</trackback:ping><description><![CDATA[<P>引自：<A href="http://64.233.179.104/search?q=cache:8yAnO65MhwEJ:www.ahetc.gov.cn/cit/200108/06.doc+oracle+%E8%A7%A6%E5%8F%91%E5%99%A8&amp;hl=zh-CN&amp;ct=clnk&amp;cd=2">http://64.233.179.104/search?q=cache:8yAnO65MhwEJ:www.ahetc.gov.cn/cit/200108/06.doc+oracle+%E8%A7%A6%E5%8F%91%E5%99%A8&amp;hl=zh-CN&amp;ct=clnk&amp;cd=2</A><BR><BR></P>
<P align=center><FONT face=宋体 size=3><B style="COLOR: black; BACKGROUND-COLOR: #ffff66">Oracle</B><B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>在MIS 开发中的应用</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>周海涛&nbsp;&nbsp; 吴良刚</FONT></P>
<P align=justify><FONT face=宋体 size=2>摘要:本文介绍了<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B><B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>的概念和类型,总结了<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B><B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>在开发MIS中的应用,并提供了实例以供参考.</FONT></P>
<P align=justify><FONT face=宋体 size=2>关键词:MIS 、<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器&nbsp;</B> <B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</FONT></P></B>
<P align=justify><FONT face=宋体 size=2>１．引言</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>本人在做一个大型的MIS系统（前台用powerbuild工具，后台用<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B>数据库）时，常碰到一些有关数据冗长性，批量删除和动态信息方面的问题，由此发现数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>简单易用。现将有关开发和应用中的一些体会总结成文，供同行参考。</FONT></P>
<P align=justify><FONT face=宋体 size=2>２．<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>的概念和类型。</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>（database triggers）是响应插入、更新或删除等数据库事件而执行的过程。它定义了当一些数据库相关事件发生时应采取的动作。可用于管理复杂的完整性约束，或监控对表的修改，或通知其它程序，表已发生修改。它的类型有：语句级<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>，以及行级<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>，前者可以在语句执行前或执行后被触发。后者在每个触发语句影响的行触发一次。还有before和after触发的命令。在insert,update,和delete之前或之后执行，引用新旧值进行处理。如果需通过<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>设定插入行中的某列值，则为了访问“新(new)”值，需使用一个<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>before insert，使用after insert则不行。Instead of <B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>命令，使用它告诉<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B>应执行什么操作。以上四种大类合成14种小类（略）。各种<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>的执行顺序如下：</FONT> 
<UL><BR><FONT face=宋体 size=2>如果有，最先执行语句级before<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>。</FONT> &nbsp;<BR><FONT face=宋体 size=2>每个insert，delete,update影响的行；</FONT> </UL>
<OL type=1><FONT face=宋体 size=2>
<LI>如果有，最先执行行级before</FONT><FONT face="宋体, MS Song"> </FONT></LI></OL>
<OL type=1 start=2><FONT face=宋体 size=2>
<LI>执行行的delete或update</FONT><FONT face="宋体, MS Song"> </FONT><FONT face=宋体 size=2>
<LI>如果有,执行行级after<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</FONT><FONT face="宋体, MS Song"> </FONT></B></LI></OL>
<UL><BR><FONT face=宋体 size=2>如果有,执行语句级after<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</FONT> </B></UL>
<P align=justify><FONT face=宋体 size=2>３．使用数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>管理数据冗余性</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>为了数据分析和制作报表的需要,用户在数据模型中加入了冗余数据，应使用<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>,以保证数据的完整性。</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>冗余数据可以用规定的 for each row选项的before update<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>进行管理。update 命令可放在<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>中对所有需要更新的冗余数据进行更新,如客户表和订单表,订单表包括客户的订单和客户表的冗余信息,客户表(customer)的表结构:客户号(cu_no)、客户名(cu_name)、客户地址(cu_address)。订单表(order)的表结构:订单号(or_no),客户号(or_no)，客户名（cu_name），客户地址（cu_address）,当客户基表中的数据被更新时更新订单中的冗余列。语法如下：</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>create or replace trigger bj_customer</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>before update on customer</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>for each row</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>begin</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>&nbsp;&nbsp;&nbsp; update order set</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>&nbsp;&nbsp;&nbsp; cu_no=:new.cu_no，</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>&nbsp;&nbsp;&nbsp; cu_name=:new.cu_name，</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>&nbsp;&nbsp;&nbsp; cu_address=:new.cu_addess，</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2> &nbsp;&nbsp; where cu_no=:old.cu_no；</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end;</FONT>&nbsp;<BR></P>
<P align=justify><FONT face=宋体 size=2>４．用<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>完成数据复制</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>如果需求非常有限，可以用数据<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>从一个数据库中向另一个数据库复制数据，如果数据复制需求仅与数据的插入有关，当一条记录插入到一个数据库中的某个基表中时，用户还希望把这条记录插入到一个远程数据库中，需用create database link语句创建一条到远程数据库的连接，一旦创建了一条数据库连接后，就可以在基表上创建一个after insert<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>，以把每一条记录插入到远程数据库中。</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>（1）在脚本中创建数据库连接（database link）bj_ysd_remote基表作为数据库基表，Bj_ysd_local代表本地数据库上的源基表。</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Creat database link remote(连接名)</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Connect to bj(帐户) indentified by bj(密码)</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Using ‘:2’;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>（2）复制记录</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>create or replace trigger trig_ysd（<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>名）</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>after insert on bj_ysd_local</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>for each row</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>begin </FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>insert into </FONT><A href="mailto:bj_ysd_remote@dblink"><FONT face=宋体 color=#0000ff size=2>bj_ysd_remote@dblink</FONT></A><FONT face=宋体 size=2> remote</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>value(:new.x1,:new.x2,……)/＊x1.x2代表字段名＊／</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>（3）删除记录</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>create or replace trigger trig_ysd_del</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>after delete on bj_ysd_local</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>for each row</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>begin </FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>&nbsp;&nbsp;&nbsp; delete from </FONT><A href="mailto:bj_ysd_remote@dblink"><FONT face=宋体 color=#0000ff size=2>bj_ysd_remote@dblink</FONT></A><FONT face=宋体 size=2> remote</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>where x1=:old.x1</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end;</FONT></P>
<P align=justify><FONT face=宋体 size=2>５．用数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>完成瀑布式删除操作</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>在某些情况下，当要删除一条记录时，该记录是与外键有关的另外一张基表上的记录时，这个删除操作必须在模型中进行传递，否则会出现大量的冗长数据，仍以cumstomer 和order基表为例，当从customer中删除一个客户时，order基表中所有相关记录也应当删除。</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Create or replace trigger trig_cust</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Before delete on&nbsp; customer</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>For each row</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Begin</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Delete from order；</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>Where&nbsp; cu_no=old.cu_no；</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>End;</FONT></P>
<P align=justify><FONT face=宋体 size=2>６．用<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>完成动态数据的操作</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>在涉及如何实现动态库存的问题时，可用<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>解决。仓库有验收、出库、调拨、报废、退料、让售等这些数据必须与以前的库存相加减，才能完成动态库存操作。本文仅以验收单<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>为例，其它的结构雷同。它们涉及到两个基表：bi_ysd(验收单)，Bj_kcb(当前库存表)，前者的表结构（rq(日期)，ysdh(验收单号)，&nbsp;bjbm(备件编码)，yssl(验收数量)，ysdj(验收单价)），后者的表结构为（bjbm（备件编码）,dqkcl（当前库存量）,dqkcje（当前库存金额））<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>如下：</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>create or replace trigger trig_ysd</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>after insert or update or delete on bj_ysd</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>for each row</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>declare rq1 varchar2(8);rq2 varchar2(8);</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>/*限于篇幅，yssl1,yssl2,ysdj1,ysdj2,bjbm1,bjbm2,ii声明略*/</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>if inserting or updating then</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>rq1:=:new.rq;bjbm1:=:new.bjbm;yssl1:=:new.yssl;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>ysdj1:=:new.ysdj;</FONT></P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P align=justify><FONT face=宋体 size=2>select count(*) into ii from bj_dqkcb </FONT></P></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P align=justify><FONT face=宋体 size=2>where bjbm=bjbm1;</FONT></P></BLOCKQUOTE></BLOCKQUOTE>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>if&nbsp; ii=0 then </FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>insert&nbsp; into&nbsp; bj_dqkcb(bjbm,dqkcl,dqkcje)</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>value(bjbm1,yssl1,ysdj1);</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>else </FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>update bj_dqkcb</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>set dqkcl=dqkcl+yssl1;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>dqkcje=dqkcje+yssl1*ysdj1;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end if</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end if</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>if deleting or updating then</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>rq2:=:old.rq;bjbm2:=:old.bjbm;yssl2:=:old.yssl;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>ysdj2:=:old.ysdj;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>update bj_dqkcb</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>set dqkcb=dqkcl-yssl2;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>dqkcje=dqkcje-yssl2*ysdj2</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end if;</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>end ;</FONT></P>
<P align=justify><FONT face=宋体 size=2>７．结束语</FONT></P>
<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face=宋体 size=2>数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>在数据库开发、ＭＩＳ开发上有很广泛的应用，但经验表明，使用过多的<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>将降低整个数据库的性能。如果数据库<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>写得不好，它会很快破坏数据库的性能，因此，在适当的时候使用恰当的<B style="COLOR: black; BACKGROUND-COLOR: #a0ffff">触发器</B>显得非常重要。</FONT></P>
<P align=justify><FONT face=宋体 size=2>参考文献：</FONT></P>
<P align=justify><FONT face=宋体 size=2>Michael Abbey.机械工业出版社.Oracle8初学者指南,1998</FONT></P>
<P align=justify><FONT face=宋体 size=2>Joline Morrison.机械工业出版社.Oracle8数据库指南,1999</FONT>&nbsp;<BR></P>
<P align=justify><FONT face=宋体 size=2>Tile:The applications of the <B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B> triggers in the development of MIS</FONT></P>
<P align=justify><FONT face=宋体 size=2>Abstract:the paper introduces the concept and types of the <B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B> triggers,summarizes the applications of the <B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle</B> triggers in the MIS,and provides the examples for reference.</FONT></P>
<P align=justify><FONT face=宋体 size=2>Key words:<B style="COLOR: black; BACKGROUND-COLOR: #ffff66">oracle&nbsp;&nbsp; </B>trigger</FONT></P><img src ="http://www.blogjava.net/TrampEagle/aggbug/32623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-27 13:23 <a href="http://www.blogjava.net/TrampEagle/articles/32623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Temporary Tables临时表</title><link>http://www.blogjava.net/TrampEagle/articles/32282.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Fri, 24 Feb 2006 04:27:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32282.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32282.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32282.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32282.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32282.html</trackback:ping><description><![CDATA[<P>引自：<A href="http://www.matrix.org.cn/thread.shtml?topicId=31492&amp;forumId=36">http://www.matrix.org.cn/thread.shtml?topicId=31492&amp;forumId=36</A><BR><BR>在Oracle8i或以上版本中，可以创建以下两种临时表： <BR>1。会话特有的临时表 <BR>&nbsp;&nbsp;&nbsp;&nbsp;CREATE GLOBAL TEMPORARY &lt;TABLE_NAME&gt; (&lt;column specification&gt;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;ON COMMIT PRESERVE ROWS； <BR>&nbsp;&nbsp;<BR>2。事务特有的临时表 <BR>&nbsp;&nbsp;&nbsp;&nbsp;CREATE GLOBAL TEMPORARY &lt;TABLE_NAME&gt; (&lt;column specification&gt;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;ON COMMIT DELETE ROWS； <BR>&nbsp;&nbsp; CREATE GLOBAL TEMPORARY TABLE MyTempTable <BR>所建的临时表虽然是存在的，但是你试一下insert 一条记录然后用别的连接登上去select，记录是空的，明白了吧，我把下面两句话再贴一下： <BR>--ON COMMIT DELETE ROWS 说明临时表是事务指定，每次提交后ORACLE将截断表（删除全部行） <BR>--ON COMMIT PRESERVE ROWS 说明临时表是会话指定，当中断会话时ORACLE将截断表。 <BR>冲突的问题更本不用考虑. <BR>&nbsp;&nbsp;<BR>临时表只是保存当前会话(session)用到的数据，数据只在事务或会话期间存在。 <BR>&nbsp;&nbsp;<BR>通过CREATE GLOBAL TEMPORARY TABLE命令创建一个临时表，对于事务类型的临时表， <BR>数据只是在事务期间存在，对于会话类型的临时表，数据在会话期间存在。 <BR>&nbsp;&nbsp;<BR>会话的数据对于当前会话私有。每个会话只能看到并修改自己的数据。DML锁不会加到 <BR>临时表的数据上。下面的语句控制行的存在性。 <BR>&nbsp;&nbsp; <BR>● ON COMMIT DELETE ROWS 表名行只是在事务期间可见 <BR>● ON COMMIT PRESERVE ROWS 表名行在整个会话期间可见 <BR>&nbsp;&nbsp;<BR>可以对临时表创建索引，视图，出发器，可以用export和import工具导入导出表的 <BR>定义，但是不能导出数据。表的定义对所有的会话可见。<BR><BR><BR>Temporary Tables临时表<BR>1简介<BR>&nbsp;&nbsp; ORACLE数据库除了可以保存永久表外，还可以建立临时表temporary tables。这些临时表用来保存一个会话SESSION的数据，<BR>&nbsp;&nbsp; 或者保存在一个事务中需要的数据。当会话退出或者用户提交commit和回滚rollback事务的时候，临时表的数据自动清空，<BR>&nbsp;&nbsp; 但是临时表的结构以及元数据还存储在用户的数据字典中。<BR>&nbsp;&nbsp; 临时表只在oracle8i以及以上产品中支持。<BR>2详细介绍<BR>&nbsp;&nbsp; Oracle临时表分为 会话级临时表 和 事务级临时表。<BR>会话级临时表是指临时表中的数据只在会话生命周期之中存在，当用户退出会话结束的时候，Oracle自动清除临时表中数据。<BR>事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束（commit or rollback），Oracle自动清除临时表中数据。<BR>临时表中的数据只对当前Session有效，每个Session都有自己的临时数据，并且不能访问其它Session的临时表中的数据。因此，<BR>临时表不需要DML锁.当一个会话结束(用户正常退出 用户不正常退出 ORACLE实例崩溃)或者一个事务结束的时候，Oracle对这个会话的<BR>表执行 TRUNCATE 语句清空临时表数据.但不会清空其它会话临时表中的数据.<BR>你可以索引临时表和在临时表基础上建立视图.同样,建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效.&nbsp;&nbsp;<BR>临时表可以拥有触发器.<BR>3建立临时表<BR>&nbsp;&nbsp; 临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效. <BR>&nbsp;&nbsp; 建立方法:<BR>1) ON COMMIT DELETE ROWS 定义了建立事务级临时表的方法.<BR>CREATE GLOBAL TEMPORARY TABLE admin_work_area<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(startdate DATE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddate DATE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class CHAR(20))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ON COMMIT DELETE ROWS;<BR>EXAMPLE:<BR>SQL&gt; CREATE GLOBAL TEMPORARY TABLE admin_work_area<BR>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(startdate DATE,<BR>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddate DATE,<BR>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class CHAR(20))<BR>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ON COMMIT DELETE ROWS;<BR>SQL&gt; create table permernate( a number);<BR>SQL&gt; insert into admin_work_area values(sysdate,sysdate,'temperary table');<BR>SQL&gt; insert into permernate values(1);<BR>SQL&gt; commit;<BR>SQL&gt; select * from admin_work_area;<BR>SQL&gt; select&nbsp;&nbsp;* from permernate;<BR>A<BR>1<BR>2)ON COMMIT PRESERVE ROWS 定义了创建会话级临时表的方法.<BR>CREATE GLOBAL TEMPORARY TABLE admin_work_area<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(startdate DATE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddate DATE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class CHAR(20))<BR>&nbsp;&nbsp;&nbsp;&nbsp; ON COMMIT PRESERVE ROWS;<BR>EXAMPLE:<BR><BR>会话1:<BR>SQL&gt; drop table admin_work_area;<BR>SQL&gt; CREATE GLOBAL TEMPORARY TABLE admin_work_area<BR>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(startdate DATE,<BR>&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddate DATE,<BR>&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class CHAR(20))<BR>&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ON COMMIT PRESERVE ROWS;<BR>SQL&gt; insert into permernate values(2);<BR>SQL&gt; insert into admin_work_area values(sysdate,sysdate,'session temperary');<BR>SQL&gt; commit;<BR>SQL&gt; select * from permernate;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<BR>----------<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR><BR>SQL&gt; select * from admin_work_area;<BR><BR>STARTDATE&nbsp;&nbsp;ENDDATE&nbsp;&nbsp;&nbsp;&nbsp;CLASS<BR>---------- ---------- --------------------<BR>17-1?? -03 17-1?? -03 session temperary<BR><BR>会话2:<BR><BR>SQL&gt; select * from permernate;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<BR>----------<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR><BR>SQL&gt; select * from admin_work_area;<BR><BR>未选择行.<BR><BR>会话2看不见会话1中临时表的数据.<BR><BR><BR><BR>4 ORACLE临时表和SQLSERVER临时表异同<BR><BR>SQL SERVER临时表<BR>也可以创建临时表。临时表与永久表相似，但临时表存储在 tempdb 中，当不再使用时会自动删除。<BR>有本地和全局两种类型的临时表，二者在名称、可见性和可用性上均不相同。本地临时表的名称以单个数字符号 (#) 打头；<BR>它们仅对当前的用户连接是可见的；当用户从 Microsoft? SQL Server? 2000 实例断开连接时被删除。全局临时表的名称以数学符号 <BR>(##) 打头，创建后对任何用户都是可见的，当所有引用该表的用户从 SQL Server 断开连接时被删除。<BR>例如，如果创建名为 employees 的表，则任何人只要在数据库中有使用该表的安全权限就可以使用该表，除非它已删除。<BR>如果创建名为 #employees 的本地临时表，只有您能对该表执行操作且在断开连接时该表删除。如果创建名为 ##employees 的全局临时表<BR>，数据表中的任何用户均可对该表执行操作。如果该表在您创建后没有其他用户使用，则当您断开连接时该表删除。如果该表在您创建<BR>后有其他用户使用，则 SQL Server在所有用户断开连接后删除该表<BR>不同:<BR>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL SERVER临时表是一种”内存表”,表是存储在内存中的.ORACLE临时表除非执行DROP TABLE,否则表定义会保留在数据字典中.<BR>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL SERVER临时表不存在类似ORACLE临时表 事务级别 上的功能.<BR>3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL SERVER本地临时表(#) 与 ORACLE的会话级别临时表类似,但是在会话退出的时候,ORACLE不会删除表.<BR>4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL SERVER的全局临时表(##) 是指多个连接共享同一片内存.当没有指针引用该内存区域时,SQL SERVER自动释放全局临时表.<BR>5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于ORACLE不是一种 内存中的数据库. 所以如果ORACLE类似SQL SERVER 频繁的对临时表进行建立和删除,必定会影响性能.<BR>所以ORACLE会保留临时表的定义直到用户DROP TABLE.<BR>6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在ORACLE中,如果需要多个用户共享一个表(类似SQL SERVER的全局临时表##).则可以利用永久表,<BR>并且在表中添加一些可以唯一标识用户的列.利用触发器和视图.当用户退出的时候,根据该登陆用户的唯一信息删除相应的表中的数据.<BR>这种方法给ORACLE带来了一定量的负载.<BR><!-- the post be hidden --></P><img src ="http://www.blogjava.net/TrampEagle/aggbug/32282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-24 12:27 <a href="http://www.blogjava.net/TrampEagle/articles/32282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sybase与oracle存储过程的写法对比</title><link>http://www.blogjava.net/TrampEagle/articles/32131.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 23 Feb 2006 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32131.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32131.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32131.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32131.html</trackback:ping><description><![CDATA[<P>引自：<A href="http://bbs.chinaunix.net/viewthread.php?tid=643946">http://bbs.chinaunix.net/viewthread.php?tid=643946</A><BR><BR><SPAN style="FONT-SIZE: 13px">在oracle中创建存储过程和sybase及sql server下的语法有些不一致之处。<BR><BR>下面就此用不同的数据库下存储过程的例子来演示之。<BR><BR>－－－－－－－－－－－－－－－－－－－－－－－－－－－<BR>oracle下：<BR>CREATE OR REPLACE FUNCTION MY_FUNC<BR>(<BR>P1 IN MY_TABLE.YY%TYPE,<BR>P2 IN MY_TABLE.NN%TYPE,<BR>P3 VARCHAR(100)<BR>)<BR>RETURN VARCHAR2 AS<BR>/*定义有参数的游标和无参数的游标*/<BR>CURSOR MY_CURSOR1 IS<BR>&nbsp; &nbsp; SELECT YY,NN,DECODE(FYYSDM,0,'合计',1,'加工费','其他费用要素')<BR>&nbsp; &nbsp; FROM MY_TABLE<BR>&nbsp; &nbsp; WHERE YY=P1<BR>&nbsp; &nbsp; GROUP BY YY,NN<BR>&nbsp; &nbsp; ORDER BY YY,NN;<BR>/*定义游标变量，存储游标数据集中的记录*/<BR>V_CURSOR1 MY_CURSOR1%ROWTYPE; <BR><BR>CURSOR MY_CURSOR2(V_ZYDM MY_TABLE.ZYDM%TYPE,V_FYYSDM NUMBER) AS<BR>&nbsp; &nbsp; SELECT YY,NN,ZYDM,NVL(ZYCB,0) /*NVL函数转换空值为指定值*/<BR>&nbsp; &nbsp; FROM MY_TABLE<BR>&nbsp; &nbsp; WHERE YY=P1 AND NN=P2 AND ZYDM=V_ZYDM AND FYYSDM=V_FYYSDM<BR>&nbsp; &nbsp; GROUP BY YY,NN;<BR>/*定义游标变量，存储游标数据集中的记录*/<BR>V_CURSOR2 MY_CURSOR2%ROWTYPE; <BR><BR>V_CPDM&nbsp;&nbsp;MY_TABLE.CPDM%TYPE;<BR>V_COUNT NUMBER;<BR>V_BZ&nbsp; &nbsp; VARCHAR2(2);<BR>V_CPCB&nbsp;&nbsp;NUMBER(22,2);<BR><BR>BEGIN<BR>&nbsp; &nbsp; V_BZ:=1;<BR>&nbsp; &nbsp; SELECT CPDM INTO V_CPDM FROM MY_TABLE;<BR>&nbsp; &nbsp; SELECT CPCB INTO V_CPCB FROM MY_TABLE WHERE ROWNUM=1;<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; IF MY_CURSOR1%ISOPEN THEN /*判断游标是否已经打开*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; CLOSE MY_CURSOR1;<BR>&nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; OPEN MY_CURSOR1;<BR>&nbsp; &nbsp; FETCH MY_CURSOR1 INTO V_CURSOR1;<BR>&nbsp; &nbsp; IF MY_CURSOR1%NOTFOUND THEN /*游标返回结果为空*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; CLOSE MY_CURSOR1;<BR>&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; RETURN(V_BZ);<BR>&nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; WHILE MY_CURSOR1%FOUND LOOP /*游标返回结果不为空*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_CPDM:=V_CURSOR1.CPDM;<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_CPCB:=V_CURSOR1.CPCB;<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_COUNT:=100;<BR>&nbsp; &nbsp; &nbsp; &nbsp; IF V_COUNT=100 THEN<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;V_COUNT:=99;<BR>&nbsp; &nbsp; &nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FETCH MY_CURSOR1 INTO V_CURSOR1;<BR>&nbsp; &nbsp; END LOOP;<BR>&nbsp; &nbsp; CLOSE MY_CURSOR1;<BR><BR>&nbsp; &nbsp; /*显式打开带参游标*/<BR>&nbsp; &nbsp; SELECT CPDM INTO V_CPDM FROM MY_TABLE;<BR>&nbsp; &nbsp; OPEN MY_CURSOR2;<BR>&nbsp; &nbsp; FETCH MY_CURSOR2 INTO V_CURSOR2;<BR>&nbsp; &nbsp; WHILE MY_CURSOR2%FOUND LOOP /*游标返回结果不为空*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_CPDM:=V_CURSOR2.CPDM;<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_CPCB:=V_CURSOR2.CPCB;<BR>&nbsp; &nbsp; &nbsp; &nbsp; V_COUNT:=100;<BR>&nbsp; &nbsp; &nbsp; &nbsp; IF V_COUNT=100 THEN<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;V_COUNT:=99;<BR>&nbsp; &nbsp; &nbsp; &nbsp; ELSE<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;V_COUNT:=88;<BR>&nbsp; &nbsp; &nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FETCH MY_CURSOR2 INTO V_CURSOR2;<BR>&nbsp; &nbsp; END LOOP;<BR>&nbsp; &nbsp; CLOSE MYCURSOR2;<BR><BR>&nbsp; &nbsp; /*隐式打开游标*/<BR>&nbsp; &nbsp; FOR V_CURSOR2 IN MY_CURSOR2(V_CPDM,V_CURSOR1.FYYSDM) LOOP<BR>&nbsp; &nbsp; &nbsp; &nbsp; IF V_CURSOR2.CPCB IS NULL THEN<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; PRINT '非法!';<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; ROLLBACK;<BR>&nbsp; &nbsp; &nbsp; &nbsp; END IF;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; UPDATE MY_TABLE<BR>&nbsp; &nbsp; &nbsp; &nbsp; SET CPCB=V_CPCB<BR>&nbsp; &nbsp; &nbsp; &nbsp; WHERE YY=P1 AND NN=P2 AND CPDM=V_CURSOR2.CPDM;<BR>&nbsp; &nbsp; &nbsp; &nbsp; IF SQL%NOTFOUND THEN /*判断前句是否有执行结果*/<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; /*程序段*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; END LOOP;<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; V_BZ:=MY_DELETE_CB(P_YY,P_NN);<BR>&nbsp; &nbsp; IF V_BZ&lt;&gt;0 THEN<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;PRINT '失败!';<BR>&nbsp; &nbsp; END IF;<BR>&nbsp; &nbsp; FOR I INT 1..V_COUNT LOOP<BR>&nbsp; &nbsp; &nbsp; &nbsp; /**/<BR>&nbsp; &nbsp; END LOOP;<BR><BR>&nbsp; &nbsp; COMMIT;/*提交事务*/<BR>&nbsp; &nbsp; RETURN(0);/*要有返回值*/<BR>END MY_FUNC;<BR><BR>CREATE OR REPLACE PROCEDURE SP_MY <BR>(<BR>P_YY IN MY_TABLE.YY%TYPE;<BR>P_NN NUMBER;<BR>)<BR>IS<BR><BR>CURSOR MY_CURSOR IS<BR>&nbsp; &nbsp; SELECT CPCB <BR>&nbsp; &nbsp; FROM MY_TABLE <BR>&nbsp; &nbsp; WHERE YY=P_YY AND NN=P_NN;<BR><BR>V_ZYCB NUMBER(22,2);<BR><BR>BEGIN<BR>&nbsp; &nbsp; /**/<BR>&nbsp; &nbsp; /*无返回值*/<BR>END;<BR><BR>附oracle下函数：<BR>NVL(AAA,BBB)&nbsp;&nbsp;空值判断函数，AAA是待判断变量,BBB为为空时要替换值<BR>DECODE(ID,P1,S1,P2,S2,S3) 条件判断函数，假如ID是P1则返回S1,假如ID是P2则返回S2,否则返回S3。<BR>RPAD(AAA,COUNT,'0') 字符补空函数，在AAA变量后补零，共字符串长COUNT。<BR>SUBSTR(AAA,M,N) 取子串函数，取AAA从第M个字符开始，取N个字符。<BR>LENGTH(STR)&nbsp;&nbsp;取字符长度。<BR>LENGTHB(STR) 取字符字节长度。<BR>TO_CHAR()<BR>TO_NUMBER()类型转换函数<BR>--------------------------------------------------<BR>SYBASE下:<BR>CREATE PROCEDURE PRO_MY<BR>(<BR>@P_YY CHAR(4),<BR>@P_NN CHAR(2)='01',<BR>@P_OUT VARCHAR(255)=NULL OUTPUT<BR>)<BR>AS<BR>BEGIN<BR>&nbsp; &nbsp; DECLARE @V_CPDM NUMERIC(9,0),<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;@V_CPCB NUMERIC(22,2),<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;@V_ID&nbsp; &nbsp;INT,<BR>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;@V_JE&nbsp; &nbsp;FLOAT<BR><BR>&nbsp; &nbsp; DECLARE CUR_TEST CURSOR FOR<BR>&nbsp; &nbsp; &nbsp; &nbsp; SELECT CPCB,JE<BR>&nbsp; &nbsp; &nbsp; &nbsp; FROM TEST<BR>&nbsp; &nbsp; &nbsp; &nbsp; WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM<BR>&nbsp; &nbsp; FOR READ ONLY<BR><BR>&nbsp; &nbsp; SELECT @V_CPCB=CPCB <BR>&nbsp; &nbsp; FROM TEST <BR>&nbsp; &nbsp; WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM<BR>&nbsp; &nbsp; IF @@ROWCOUNT=0<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;PRINT '未找到'<BR>&nbsp; &nbsp; ELSE<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PRINT '找到'<BR><BR>&nbsp; &nbsp; OPEN CUR_TEST<BR>&nbsp; &nbsp; FETCH CUR_TEST INTO @V_CPCB,@V_JE<BR>&nbsp; &nbsp; IF @@SQLSTATUS=2 --返回结果集为空<BR>&nbsp; &nbsp; IF @@SQLSTATUS=1 --游标执行出错<BR>&nbsp; &nbsp; BEGIN<BR>&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR 20000 --返回自定义错误号<BR>&nbsp; &nbsp; &nbsp; &nbsp; --RAISERROR 20000,'错误信息' --返回自定义错误号<BR>&nbsp; &nbsp; &nbsp; &nbsp; ROLLBACK<BR>&nbsp; &nbsp; &nbsp; &nbsp; RETURN 10<BR>&nbsp; &nbsp; END<BR>&nbsp; &nbsp; WHILE @@SQLSTATUS=0 --结果集返回正常结果<BR>&nbsp; &nbsp; BEGIN<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/*Exception*/<BR>&nbsp; &nbsp; &nbsp; &nbsp; FETCH CUR_TEST INTO @V_CPCB,@V_JE<BR>&nbsp; &nbsp; END<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; SELECT @V_ID=@V_ID+1<BR><BR>&nbsp; &nbsp; IF (@V_STR NOT LIKE "[0-9]")<BR>&nbsp; &nbsp; &nbsp; &nbsp; SELECT @@V_ID=1<BR><BR>&nbsp; &nbsp; EXECUTE @V_ID=DELETE_CB @P_YY,@P_NN&nbsp;&nbsp;<BR><BR>&nbsp; &nbsp; UPDATE TEST SET CPCB=100 WHERE YY=@P_YY AND NN=@P_NN<BR>&nbsp; &nbsp; IF @@ERROR!=0<BR>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; PRINT '更新失败'&nbsp;&nbsp;<BR><BR>&nbsp; &nbsp; RETURN 0<BR><BR>END<BR><BR>附录：<BR>CONVERT(INT,@V_JE) --类型转换函数<BR>LTRIM(@V_STR) --去掉左空格<BR>RTRIM(@V_STR) --去掉右空格<BR>ROUND(@V_JE,2) --数值小数位数设定<BR>SUBSTRING(@V_STR,M,N) --取子字符串<BR>STR(@V_JE,M,N) --设置数值的显示位数和小数位数<BR>CHAR_LENGTH(@V_STR) --字符串长度<BR>PATINDEX("%[0-9]%",@V_STR) --取前边字符在后面字符串中的起始位置<BR>patindex("%[kKmMgGpP]%", @v_str)<BR>--case语句<BR>CASE @V_ID WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE 'OTHER' END<BR>ISNULL(@V_JE,0) --非空值判断<BR>－－－－－－－－－－－－－－－－－－－－－－－－－<BR>另外：<BR>关于事务处理：<BR>ORACLE下不用显式打开事务，直接提交即可，而且可以分步提交，多次提交，不用成对出现。 <BR>SYBASE必须显式打开和提交事务，且必须成对出现，平时我们单条更新语句的执行被sybase默认为隐式事务来提交。</SPAN></P><img src ="http://www.blogjava.net/TrampEagle/aggbug/32131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-23 17:22 <a href="http://www.blogjava.net/TrampEagle/articles/32131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle技巧和脚本</title><link>http://www.blogjava.net/TrampEagle/articles/32084.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 23 Feb 2006 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32084.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32084.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32084.html</trackback:ping><description><![CDATA[引自：<a href="http://searchdatabase.techtarget.com.cn/tips/229/2101229.shtml">http://searchdatabase.techtarget.com.cn/tips/229/2101229.shtml</a><br /><a class="f1">  
<div class="guanggao"><span id="contentAdv"></span></div><p>　　1. 如何查看ORACLE的隐含参数?</p><p>　　ORACLE的显式参数，除了在INIT.ORA文件中定义的外，在svrmgrl中用"show parameter *"，可以显示。但ORACLE还有一些参数是以“_”，开头的。如我们非常熟悉的“_offline_rollback_segments”等。</p><p>　　这些参数可在sys.x$ksppi表中查出。</p><p>　　语句:“select ksppinm from x$ksppi where substr(ksppinm,1,1)='_'; ”</p><p>　　2. 如何查看安装了哪些ORACLE组件?</p><p>　　进入${ORACLE_HOME}/orainst/，运行./inspdver，显示安装组件和版本号。</p><p>　　3. 如何查看ORACLE所占用共享内存的大小?</p><p>　　可用UNIX命令“ipcs”查看共享内存的起始地址、信号量、消息队列。</p><p>　　在svrmgrl下，用“oradebug <a class="bluekey" href="http://www.yesky.com/key/3259/593259.html" target="_blank">ipc</a>”，可看出ORACLE占用共享内存的分段和大小。</p><p>　　example:</p><p>　　SVRMGR&gt; oradebug ipc</p><p>　　-------------- Shared memory --------------</p><p>　　Seg Id Address Size</p><p>　　1153 7fe000 784</p><p>　　1154 800000 419430400</p><p>　　1155 19800000 67108864</p><p>　　4. 如何查看当前SQL*PLUS用户的<a class="bluekey" href="http://www.yesky.com/key/1985/501985.html" target="_blank">sid</a>和serial#?</p><p>　　在SQL*PLUS下，运行:</p><p>　　“select sid, serial#, status from v$session</p><p>　　where audsid=userenv('sessionid');”</p><p>　　5. 如何查看当前数据库的字符集?</p><p>　　在SQL*PLUS下，运行:</p><p>　　“select userenv('language') from dual;”</p><p>　　或:</p><p>　　“select userenv('lang') from dual;”</p><p>　　6. 如何查看数据库中某用户，正在运行什么SQL语句?</p><p>　　根据MACHINE、USERNAME或SID、SERIAL#，连接表V$SESSION和V$SQLTEXT，可查出。</p><p>　　SQL*PLUS语句:</p><p>　　“SELECT SQL_TEXT FROM V$SQL_TEXT T, V$SESSION S WHERE T.ADDRESS=S.SQL_ADDRESS</p><p>　　AND T.<a class="bluekey" href="http://www.yesky.com/key/4763/534763.html" target="_blank">HASH</a>_VALUE=S.SQL_HASH_VALUE</p><p>　　AND S.MACHINE='XXXXX' OR USERNAME='XXXXX' -- 查看某主机名，或用户名</p><p>　　/”</p><p>　　7. 如何删除表中的重复记录?</p><p>　　例句:</p><p>　　DELETE</p><p>　　FROM table_name a</p><p>　　WHERE rowid &gt; ( SELECT min(rowid)</p><p>　　FROM table_name b</p><p>　　WHERE b.pk_column_1 = a.pk_column_1</p><p>　　and b.pk_column_2 = a.pk_column_2 );</p><p>　　8. 手工临时强制改变服务器字符集</p><p>　　以sys或system登录系统，sql*plus运行:“create database <a class="bluekey" href="http://www.yesky.com/key/4232/594232.html" target="_blank">character</a> set us7ascii;".</p><p>　　有以下错误提示:</p><p>　　* create database character set US7ASCII</p><p>　　ERROR at line 1:</p><p>　　ORA-01031: insufficient privileges</p><p>　　实际上，看v$nls_parameters，字符集已更改成功。但重启数据库后，数据库字符集又变回原来的了。</p><p>　　该命令可用于临时的不同字符集服务器之间数据倒换之用。</p><p>　　9. 怎样查询每个<a class="bluekey" href="http://www.yesky.com/key/464/595464.html" target="_blank">instance</a>分配的PCM锁的数目</p><p>　　用以下命令:</p><p>　　select count(*) "Number of hashed PCM locks" from v$lock_element where bitand(flags,4)&lt;&gt;0</p><p>　　/</p><p>　　select count(*) "Number of fine grain PCM locks" from v$lock_element</p><p>　　where bitand(flags,4)=0</p><p>　　/</p><p>　　10. 怎么判断当前正在使用何种SQL优化方式?</p><p>　　用explain plan产生EXPLAIN PLAN，检查PLAN_TABLE中ID=0的POSITION列的值。</p><p>　　e.g.</p><p>　　select decode(nvl(position,-1),-1,'RBO',1,'CBO') from plan_table where id=0</p><p>　　/</p><p>　　11. 做EXPORT时，能否将DUMP文件分成多个?</p><p>　　ORACLE8I中EXP增加了一个参数FILESIZE，可将一个文件分成多个:</p><p>　　EXP SCOTT/TIGER FILE=(ORDER_1.DMP,ORDER_2.DMP,ORDER_3.DMP) FILESIZE=1G TABLES=ORDER;</p><p>　　其他版本的ORACLE在UNIX下可利用管道和split分割:</p><p>　　mknod pipe p</p><p>　　split -b 2048m pipe order &amp; #将文件分割成，每个2GB大小的，以order为前缀的文件:</p><p>　　#orderaa,orderab,orderac,... 并将该进程放在后台。</p><p>　　EXP SCOTT/TIGER FILE=pipe tables=order<br /><br />导入导出命令：<br />备份：exp 用户/密码@服务名 file=testj.dmp<br />恢复：imp 用户/密码@服务名 file=testj.dmp full y<br />恢复之前先建表空间、用户（已有时先删掉用户再新建用户）</p></a><img src ="http://www.blogjava.net/TrampEagle/aggbug/32084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-23 11:28 <a href="http://www.blogjava.net/TrampEagle/articles/32084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用Oracle实现实时通信？</title><link>http://www.blogjava.net/TrampEagle/articles/32082.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 23 Feb 2006 03:19:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32082.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32082.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32082.html</trackback:ping><description><![CDATA[引自：<a href="http://searchdatabase.techtarget.com.cn/askexperts/62/2110562.shtml?ticket=ST-10061-qlZuEnO1WXkMpEHSDxNt">http://searchdatabase.techtarget.com.cn/askexperts/62/2110562.shtml?ticket=ST-10061-qlZuEnO1WXkMpEHSDxNt</a><br /><br />        由于Oracle不提供用于实时输出消息的工具, Oracle数据库开发者总是要面临实时监视他们的储备过程执行的挑战。他们必须使用dbms_output.put_<a class="bluekey" href="http://www.yesky.com/key/986/135986.html" target="_blank">line</a>调用，这个调用直到过程完成才返回结果。 
<p>　　在本文中，我想演示如何从Oracle9i数据库直接发送电子邮件，作为一种实时通信解决方案。这样我们要监视存储过程就不再需要等待它们完成了，这样的方法还为开发者提供了其他的一些好处:</p><p>　　. 可以在几分钟内调试一些很长的批处理过程，而不需要等几个小时;</p><p>　　. 计算用于指定代码块所需的执行时间;</p><p>　　这就需要解决一个问题，我们如何从运行的存储过程中输出消息以便我们可以即时检查它们，即使我们不在办公场所?我们的做法是把所有必需的过程与函数包装在自定义的包中，然后使用Oracle9i UTL_SMTP包直接地从Oracle数据库中发送电子邮件。下面我将详细讲解一些这个过程。</p><p>　　Oracle的UTL_SMTP包</p><p>　　在Oracle9i中引入了UTL_SMTP包(SMTP代表Simple Mail Transfer Protocol简单邮件传送协议，使用TCP端口25在客户机和服务器之间建立通信联络)，使开发者能够从数据库发送电子邮件。</p><p>　　只有安装带有Java虚拟机(JVM)的8i或更高的版本才能使用UTL_SMTP。 此外还必须把plsql.jar载入数据库中。否则，当调用UTL_SMTP API来发送电子邮件的时候我们将得到下面的异常:ORA - 29540 : class oracle/plsql/net/TCPConnection does not exist。</p><p>　　默认的$ORACLE_HOME/javavm/<a class="bluekey" href="http://www.yesky.com/key/2906/142906.html" target="_blank">install</a>/initjvm.sql脚本(安装了JVM)不运行把plsql.jar载入数据库的initplsj.sql脚本。系统用户或者内部用户可以手工运行$ORACLE_HOME/RDBMS/<a class="bluekey" href="http://www.yesky.com/key/74/130074.html" target="_blank">ADMIN</a>/initplsj.sql脚本以解决这个问题。 如果你没有可用的脚本，你要么可以从Oracle支持那里得到它，要么可以简单地直接使用loadjava载入实用程序plsql.jar:</p><p>　　loadjava -user sys/password@<a class="bluekey" href="http://www.yesky.com/key/2861/137861.html" target="_blank">database</a> -resolve plsql/jlib/plsql.jar</p><p>　　UTL_SMTP API:</p><p>　　本文的代码中使用了下列UTL_SMTP包中的API:</p><p>　　OPEN_CONNECTION():打开到简单邮件传送协议服务器的连接。</p><p>　　<a class="bluekey" href="http://www.yesky.com/key/1806/141806.html" target="_blank">HELO</a>():执行连接之后建立与简单邮件传送协议服务器初始的收发关系功能，它能识别发送到服务器的“信使”。</p><p>　　MAIL():初始化与服务器的邮件交换，但是事实上不发送消息。</p><p>　　RCPT():识别消息的接受者。为了把一条消息发送到多个接受者，你必须多次调用这个过程。</p><p>　　DATA():指定电子邮件的内容。</p><p>　　QUIT():终止一个SMTP会话并且断开与服务器的连接。</p><p>　　为了利用应用程序编程接口，把下面的调用按照给定的顺序放入程序中:</p><p>　　调用 OPEN_CONNECTION</p><p>　　调用 HELO</p><p>　　调用 MAIL</p><p>　　调用 RCPT for each recipient</p><p>　　格式化电子邮件的内容然后调用MAIL</p><p>　　调用 QUIT</p><p>　　EmailUtils包规范</p><p>　　EmailUtils包包括下列API:</p><p>　　SetSender/GetSender-设置/取得发送者</p><p>　　SetRecipient/GetRecipient -设置/取得接受者</p><p>　　SetCcrecipient/GetCcrecipient -设置/取得抄件接受者</p><p>　　SetMailHost/GetMailHost -设置/取得邮件主机</p><p>　　SetSubject/GetSubject -设置/取得主题</p><p>　　Send-发送邮件</p><p>　　代码1说明了EmailUtils包的规范:</p><p>　　create or replace package EmailUtils as</p><p>　　procedure SetSender(pSender in varchar2);</p><p>　　function GetSender</p><p>　　return varchar2;</p><p>　　procedure SetRecipient(pRecipient in varchar2);</p><p>　　function GetRecipient</p><p>　　return varchar2;</p><p>　　procedure SetCcRecipient(pCcRecipient in varchar2);</p><p>　　function GetCcRecipient</p><p>　　return varchar2;</p><p>　　procedure SetMailHost(pMailHost in varchar2);</p><p>　　function GetMailHost</p><p>　　return varchar2;</p><p>　　procedure SetSubject(pSubject in varchar2);</p><p>　　function GetSubject</p><p>　　return varchar2;</p><p>　　procedure Send(pMessage in varchar2);</p><p>　　procedure Send(pSender in varchar2,</p><p>　　pRecipient in varchar2,</p><p>　　pMailHost in varchar2,</p><p>　　pCcRecipient in varchar2 := null,</p><p>　　pSubject in varchar2 := null,</p><p>　　pMessage in varchar2 := null);</p><p>　　end EmailUtils;</p><p>　　/</p><p>　　可以看出，Send过程是重载过程:包规范中包括这个过程的两个版本。 一个版本当至少三个强制性参数要规定的时候引用，pSender，pRecipient和pMailHost:</p><p>　　procedure Send(pSender in varchar2,</p><p>　　pRecipient in varchar2,</p><p>　　pMailHost in varchar2,</p><p>　　pCcRecipient in varchar2 := null,</p><p>　　pSubject in varchar2 := null,</p><p>　　pMessage in varchar2 := null);<br /> </p><div class="guanggao"><span id="contentAdv"></span></div><p></p><p>　　另一个版本只有当提供pMessage参数值时执行:</p><p>　　procedure Send(pMessage in varchar2);</p><p>　　第二个版本是用作调试的版本。 所有的电子邮件消息共用同样的发送者、接受者、邮件主机、抄送接受者和主题信息，这些都是我在会话的开始的时候设置好的。 下面是一个PL/SQL程序块的例子:</p><p>　　begin</p><p>　　EmailUtils.SetSender('WayneZ@MyCompany.com');</p><p>　　EmailUtils.SetRecipient('waynezheng@vip.sina.com');</p><p>　　EmailUtils.SetCcRecipient('WayneZ@MyCompany.com');</p><p>　　EmailUtils.SetMailHost('MyServer.MyCompany.com');</p><p>　　EmailUtils.SetSubject('DeleteClassifications procedure: Run 1');</p><p>　　end;</p><p>　　/</p><p>　　一个实际的电子邮件消息将在每个Send过程调用中被指定。 我们可以把所用的EmailUtils.Send()调用插入到我们调试的代码中，我们以前为了得到同样的调试结果使用的是DBMS_OUTPUT.PUT_LINE()调用。:</p><p>　　vMessage := 'Point 1.' || utl_tcp.crlf ||</p><p>　　'Rows processed: ' || to_char(vRows) || utl_tcp.crlf ||</p><p>　　'Elapsed time: ' || vTime;</p><p>　　EmailUtils.Send(vMessage);</p><p>　　vMessage := 'Point 3.' || utl_tcp.crlf ||</p><p>　　'Rows processed: ' || to_char(vRows) || utl_tcp.crlf ||</p><p>　　'Elapsed time: ' || vTime;</p><p>　　EmailUtils.Send(vMessage);</p><p>　　代码2显示带有重载Send过程的EmailUtils规格。 我们可以看到，Send过程的代码相当简单。 UTL_SMTP包不提供用于格式化消息内容的应用编程接口。 而是由用户负责格式化消息。 这就是为什么下列程序块要被包含到每个Send过程中以便格式化电子邮件的头部。</p><p>　　vMessage := 'Date: ' ||</p><p>　　to_char(sysdate, 'fmDy, DD Mon YYYY fxHH24:MI:SS') ||</p><p>　　utl_tcp.crlf ||</p><p>　　'From: ' || pSender || utl_tcp.crlf ||</p><p>　　'Subject: ' || pSubject || utl_tcp.crlf ||</p><p>　　'To: ' || pRecipient || utl_tcp.crlf;</p><p>　　同时,如果消息长度超过2000字符的话，你可能得到一个错误( ORA - 06502 : PL/SQL : numeric or value error)。 所以为了避免出现这个错误，我们使用下面的程序块,不允许消息超过2000个字符:</p><p>　　if length(vMessage) &gt; 2000</p><p>　　then</p><p>　　vMessage := substr(vMessage, 1, 2000);</p><p>　　end if;</p><p>　　如果需要发送带有超过2000字的电子邮件，那么可以使用另三个UTL_SMTP应用程序编程接口，提供比DATA()过程更加精细的控制。 首先, OPEN_DATA()发送数据命令。 然后WRITE_DATA()添加数据到你要发送的字符串中。 你可以调用WRITE_DATA()任意多次，这样你就可以一次写2000个字符以克服字数的限制。 最后, CLOSE_DATA()通过发送一个封装在CRLF中的终止周期结束电子邮件消息。</p><p>　　实时消息使你的生活更加舒适</p><p>　　从数据库发送电子邮件就是那么容易。 一旦你试用这个简单的操作，我相信你会发现它很有用，便于你的数据库操作,例如调试、远程的数据库监控和输出数据库数据。</p><p>　　每个数据库开发者都有在代码中使用大量的DBMS_OUTPUT调用的调试经历。 在开始一个SQL * Plus会话之后,输入SET SERVEROUTPUT ON然后运行这个过程。 放进DBMS_OUTPUT.PUT_LINE调用的消息显示在屏幕上--但是只有在过程完成以后才能显示出来。 这个过程极端地麻烦，尤其在调试长的批处理时通常是要运行整晚。 你可以等待10到12小时仅仅是为了查出错误的代码，然后修改，再去等待下一个10到12个小时? 然而，如果你有访问消息的实时的办法，那么你可以在头5到10分钟内捕捉到问题。</p><p>　　DBMS_OUTPUT包也有其他的缺点。 例如,它不接受可变的布尔类型以及它有255字符每行的限制(如果你想输出一个长的消息的话，那么你会得到这个异常:ORA - 20000 : ORU - 10028 : line length overflow, limit of 255 bytes per line)。 把它的缺点全部列出这已经超出本文的范围了，但是重要结论就是DBMS_OUTPUT包不许数据库开发者实时的看到消息。</p><p>　　谈到服务器上的OS文件，你会不会喜欢把选定的数据从服务器中输出到一个Excel电子表格呢? 一个办法就是使用Oracle的UTL_FILE包,它提供了一个标准OS流文档输入/输出的限制级版本。 然而, PL/SQL程序只能访问在初始化文件INIT.ORA的UTL_FILE_DIR参数规定的目录。 这个参数大多数情况下是空的。为了使这个目录可用来进行文件访问，必须请数据库管理者修改初始化文件。 这有些麻烦。使用EmailUtils包,你可以简简单单的把数据写入一个电子邮件中，发送给自己，然后收到它的副本粘贴到自己喜欢的文档编辑器中。</p><p><br /></p><img src ="http://www.blogjava.net/TrampEagle/aggbug/32082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-23 11:19 <a href="http://www.blogjava.net/TrampEagle/articles/32082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL*PLUS常用命令列表</title><link>http://www.blogjava.net/TrampEagle/articles/32081.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 23 Feb 2006 03:16:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32081.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32081.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32081.html</trackback:ping><description><![CDATA[引自：<a href="http://searchdatabase.techtarget.com.cn/tips/59/2073059.shtml">http://searchdatabase.techtarget.com.cn/tips/59/2073059.shtml</a><br /><br />命令列表: 
<p>　　假设当前执行命令为:select * from tab;</p><p>　　(a)ppend　　　　 添加文本到缓冲区当前行尾　　　　a order by tname　结果:select * from tab order by tname;</p><p>　　(注:a后面跟2个空格)</p><p>　　(c)hange/old/<a class="bluekey" href="http://www.yesky.com/key/1252/161252.html" target="_blank">new</a> 在当前行用新的文本替换旧的文本　c/*/tname　　　　　结果:select tname from tab;</p><p>　　(c)hange/text　　从当前行删除文本　　　　　　　　c/tab　　　　　　　结果:select tname from ;</p><p>　　del　　　　　　　删除当前行</p><p>　　del n　　　　　　删除第n行</p><p>　　(i)nput 文本　　 在当前行之后添加一行</p><p>　　(l)ist　　　　　 显示缓冲区中所有行</p><p>　　(l)ist n　　　　 显示缓冲区中第 n 行</p><p>　　(l)ist m n　　　 显示缓冲区中 m 到 n 行</p><p>　　run　　　　　　　执行当前缓冲区的命令</p><p>　　/　　　　　　　　执行当前缓冲区的命令</p><p>　　r　　　　　　　　执行当前缓冲区的命令</p><p>　　@文件名　　　　　运行调入内存的<a class="bluekey" href="http://www.yesky.com/key/1763/161763.html" target="_blank">sql</a>文件，如:</p><p>　　SQL&gt; edit s&lt;回车&gt;</p><p>　　如果当前目录下不存在s.sql文件，则系统自动生成s.sql文件，</p><p>　　在其中输入“select * from tab;”，存盘退出。</p><p>　　SQL&gt; @s&lt;回车&gt;</p><p>　　系统会自动查询当前用户下的所有表、视图、同义词。</p><p>　　@@文件名　　　　 在.sql文件中调用令一个.sql文件时使用</p><p>　　save 文件名　　　将缓冲区的命令以文件方式存盘，缺省文件扩展名为.sql</p><p>　　get 文件名　　　 调入存盘的sql文件</p><p>　　start 文件名　　 运行调入内存的sql文件</p><p>　　spool 文件名　　 把这之后的各种操作及执行结果“假脱机”即存盘到磁盘文件上，默认文件扩展名为.lst</p><p>　　spool　　　　　　显示当前的“假脱机”状态</p><p>　　spool off　　　　停止输出</p><p>　　例:</p><p>　　SQL&gt; spool a</p><p>　　SQL&gt; spool</p><p>　　正假脱机到 A.LST</p><p>　　SQL&gt; spool off</p><p>　　SQL&gt; spool</p><p>　　当前无假脱机</p><p>　　exit　　　　　　 退出SQL*<a class="bluekey" href="http://www.yesky.com/key/4336/159336.html" target="_blank">PLUS</a></p><p>　　desc 表名　　　　显示表的结构</p><p>　　show user　　　　显示当前连接用户</p><p>　　show error　　　 显示错误</p><p>　　show all　　　　 显示所有68个系统变量值</p><p>　　edit　　　　　　 打开默认编辑器，<a class="bluekey" href="http://www.yesky.com/key/322/170322.html" target="_blank">Windows系统</a>中默认是notepad.exe，把缓冲区中最后一条<a class="bluekey" href="http://www.yesky.com/key/2815/182815.html" target="_blank">SQL语句</a>调入afiedt.buf文件中进行编辑</p><p>　　edit 文件名　　　把当前目录中指定的.sql文件调入编辑器进行编辑</p><p>　　clear screen　　 清空当前屏幕显示</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/32081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-23 11:16 <a href="http://www.blogjava.net/TrampEagle/articles/32081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle维护常用SQL语句</title><link>http://www.blogjava.net/TrampEagle/articles/32080.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 23 Feb 2006 03:15:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/32080.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/32080.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/32080.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/32080.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/32080.html</trackback:ping><description><![CDATA[<P>引自：<A href="http://searchdatabase.techtarget.com.cn/tips/144/2090144.shtml">http://searchdatabase.techtarget.com.cn/tips/144/2090144.shtml</A><BR><BR><A class=f1>&nbsp;</P>
<DIV class=guanggao><SPAN id=contentAdv></SPAN></DIV>
<P>　　<STRONG>1、查看表空间的名称及大小</STRONG></P>
<P>　　select t.tablespace_name, round(<A class=bluekey href="http://www.yesky.com/key/2499/207499.html" target=_blank>sum</A>(bytes/(1024*1024)),0) ts_size</P>
<P>　　from dba_tablespaces t, dba_data_files d</P>
<P>　　where t.tablespace_name = d.tablespace_name</P>
<P>　　group by t.tablespace_name;</P>
<P>　　<STRONG>2、查看表空间物理<A class=bluekey href="http://www.yesky.com/key/51/195051.html" target=_blank>文件的名称</A>及大小</STRONG></P>
<P>　　select tablespace_name, file_id, file_name,</P>
<P>　　round(bytes/(1024*1024),0) total_space</P>
<P>　　from dba_data_files</P>
<P>　　order by tablespace_name;</P>
<P>　　<STRONG>3、查看回滚段名称及大小</STRONG></P>
<P>　　select segment_name, tablespace_name, r.status,</P>
<P>　　(initial_extent/1024) InitialExtent,(next_extent/1024) NextExtent,</P>
<P>　　max_extents, v.curext CurExtent</P>
<P>　　From dba_rollback_segs r, v$rollstat v</P>
<P>　　Where r.segment_id = v.usn(+)</P>
<P>　　order by segment_name ;</P>
<P>　　<STRONG>4、查看控制文件</STRONG></P>
<P>　　select name from v$controlfile;</P>
<P>　　<STRONG>5、查看日志文件</STRONG></P>
<P>　　select member from v$logfile;</P>
<P>　　<STRONG>6、查看表空间的使用情况</STRONG></P>
<P>　　select sum(bytes)/(1024*1024) as free_space,tablespace_name</P>
<P>　　from dba_free_space</P>
<P>　　group by tablespace_name;</P>
<P>　　SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE,</P>
<P>　　(B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE"</P>
<P>　　FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C</P>
<P>　　WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME;</P>
<P>　　<STRONG>7、查看数据库库对象</STRONG></P>
<P>　　select owner, object_type, status, count(*) count# from all_objects group by owner, object_type, status;</P>
<P>　　<STRONG>8、查看数据库的版本</STRONG></P>
<P>　　Select <A class=bluekey href="http://www.yesky.com/key/1693/206693.html" target=_blank>version</A> FROM Product_component_version</P>
<P>　　Where SUBSTR(PRODUCT,1,6)='Oracle';</P>
<P>　　<STRONG>9、查看数据库的创建日期和归档方式</STRONG></P>
<P>　　Select Created, Log_Mode, Log_Mode From V$Database;</P>
<P>　　<STRONG>10、捕捉运行很久的SQL</STRONG></P>
<P>　　<A class=bluekey href="http://www.yesky.com/key/3744/183744.html" target=_blank>column</A> username format a12</P>
<P>　　column opname format a16</P>
<P>　　column progress format a8</P>
<P>　　select username,sid,opname,</P>
<P>　　round(sofar*100 / totalwork,0) || '%' as progress,</P>
<P>　　time_remaining,sql_text</P>
<P>　　from v$session_longops , v$sql</P>
<P>　　where time_remaining &lt;&gt; 0</P>
<P>　　and sql_address = address</P>
<P>　　and sql_hash_value = hash_value</P>
<P>　　/</P>
<P>　　<STRONG>11、查看数据表的参数信息</STRONG></P>
<P>　　SELECT partition_name, high_value, high_value_length, tablespace_name,</P>
<P>　　pct_free, pct_used, ini_trans, max_trans, initial_extent,</P>
<P>　　next_extent, min_extent, max_extent, pct_increase, FREELISTS,</P>
<P>　　freelist_groups, <A class=bluekey href="http://www.yesky.com/key/597/210597.html" target=_blank>LOGGING</A>, BUFFER_POOL, num_rows, blocks,</P>
<P>　　empty_blocks, avg_space, chain_cnt, avg_row_len, sample_size,</P>
<P>　　last_analyzed</P>
<P>　　FROM dba_tab_partitions</P>
<P>　　--WHERE table_name = :tname AND table_owner = :towner</P>
<P>　　ORDER BY partition_position</P>
<P>　　<STRONG>12、查看还没提交的事务</STRONG></P>
<P>　　select * from v$locked_object;</P>
<P>　　select * from v$transaction;</P>
<P>　　<STRONG>13、查找object为哪些进程所用</STRONG></P>
<P>　　select</P>
<P>　　p.spid,</P>
<P>　　s.sid,</P>
<P>　　s.serial# serial_num,</P>
<P>　　s.username user_name,</P>
<P>　　a.type object_type,</P>
<P>　　s.osuser os_user_name,</P>
<P>　　a.owner,</P>
<P>　　a.object object_name,</P>
<P>　　decode(sign(48 - command),</P>
<P>　　1,</P>
<P>　　to_char(command), 'Action Code #' || to_char(command) ) action,</P>
<P>　　p.program oracle_process,</P>
<P>　　s.terminal terminal,</P>
<P>　　s.program program,</P>
<P>　　s.status session_status</P>
<P>　　from v$session s, v$access a, v$process p</P>
<P>　　where s.paddr = p.addr and</P>
<P>　　s.type = 'USER' and</P>
<P>　　a.sid = s.sid and</P>
<P>　　a.object='SUBSCRIBER_ATTR'</P>
<P>　　order by s.username, s.osuser<BR><BR><A class=f1>&nbsp;</P>
<DIV class=guanggao><SPAN id=contentAdv></SPAN></DIV>
<P></P>
<P>　　<STRONG>14、回滚段查看</STRONG></P>
<P>　　select rownum, sys.dba_rollback_segs.segment_name Name, v$rollstat.extents</P>
<P>　　Extents, v$rollstat.rssize Size_in_Bytes, v$rollstat.xacts XActs,</P>
<P>　　v$rollstat.gets Gets, v$rollstat.waits Waits, v$rollstat.writes Writes,</P>
<P>　　sys.dba_rollback_segs.status status from v$rollstat, sys.dba_rollback_segs,</P>
<P>　　v$rollname where v$rollname.name(+) = sys.dba_rollback_segs.segment_name and</P>
<P>　　v$rollstat.usn (+) = v$rollname.usn order by rownum</P>
<P>　　<STRONG>15、耗资源的进程(top session)</STRONG></P>
<P>　　select s.schemaname schema_name, decode(sign(48 - command), 1,</P>
<P>　　to_char(command), 'Action Code #' || to_char(command) ) action, status</P>
<P>　　session_status, s.osuser os_user_name, s.sid, p.spid , s.serial# serial_num,</P>
<P>　　nvl(s.username, '[Oracle process]') user_name, s.terminal terminal,</P>
<P>　　s.program program, st.value criteria_value from v$sesstat st, v$session s , v$process p</P>
<P>　　where st.sid = s.sid and st.statistic# = to_number('38') and ('ALL' = 'ALL'</P>
<P>　　or s.status = 'ALL') and p.addr = s.paddr order by st.value desc, p.spid asc, s.username asc, s.osuser asc</P>
<P>　　<STRONG>16、查看锁(lock)情况</STRONG></P>
<P>　　select /*+ RULE */ ls.osuser os_user_name, ls.username user_name,</P>
<P>　　decode(ls.type, 'RW', 'Row wait enqueue lock', 'TM', 'DML enqueue lock', 'TX',</P>
<P>　　'Transaction enqueue lock', 'UL', 'User supplied lock') lock_type,</P>
<P>　　o.object_name object, decode(ls.lmode, 1, null, 2, 'Row Share', 3,</P>
<P>　　'Row Exclusive', 4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive', null)</P>
<P>　　lock_mode, o.owner, ls.sid, ls.serial# serial_num, ls.id1, ls.id2</P>
<P>　　from sys.dba_objects o, ( select s.osuser, s.username, l.type,</P>
<P>　　l.lmode, s.sid, s.serial#, l.id1, l.id2 from v$session s,</P>
<P>　　v$lock l where s.sid = l.sid ) ls where o.object_id = ls.id1 and o.owner</P>
<P>　　&lt;&gt; 'SYS' order by o.owner, o.object_name</P>
<P>　　<STRONG>17、查看等待(wait)情况</STRONG></P>
<P>　　SELECT v$waitstat.class, v$waitstat.count count, SUM(v$sysstat.value) sum_value</P>
<P>　　FROM v$waitstat, v$sysstat WHERE v$sysstat.name IN ('db block gets',</P>
<P>　　'consistent gets') group by v$waitstat.class, v$waitstat.count</P>
<P>　　<STRONG>18、查看sga情况</STRONG></P>
<P>　　SELECT NAME, BYTES FROM SYS.V_$SGASTAT ORDER BY NAME ASC</P>
<P>　　<STRONG>19、查看catched object</STRONG></P>
<P>　　SELECT owner, name, db_link, namespace,</P>
<P>　　type, sharable_mem, loads, executions,</P>
<P>　　locks, pins, kept FROM v$db_object_cache</P>
<P>　　<STRONG>20、查看V$SQLAREA</STRONG></P>
<P>　　SELECT SQL_TEXT, SHARABLE_MEM, PERSISTENT_MEM, RUNTIME_MEM, SORTS,</P>
<P>　　VERSION_COUNT, LOADED_VERSIONS, OPEN_VERSIONS, USERS_OPENING, EXECUTIONS,</P>
<P>　　USERS_EXECUTING, LOADS, FIRST_LOAD_TIME, INVALIDATIONS, PARSE_CALLS, DISK_READS,</P>
<P>　　BUFFER_GETS, ROWS_PROCESSED FROM V$SQLAREA</P>
<P>　　<STRONG>21、查看object分类数量</STRONG></P>
<P>　　select decode (o.type#,1,'INDEX' , 2,'TABLE' , 3 , 'CLUSTER' , 4, 'VIEW' , 5 ,</P>
<P>　　'SYNONYM' , 6 , 'SEQUENCE' , 'OTHER' ) object_type , count(*) quantity from</P>
<P>　　sys.obj$ o where o.type# &gt; 1 group by decode (o.type#,1,'INDEX' , 2,'TABLE' , 3</P>
<P>　　, 'CLUSTER' , 4, 'VIEW' , 5 , 'SYNONYM' , 6 , 'SEQUENCE' , 'OTHER' ) union select</P>
<P>　　'COLUMN' , count(*) from sys.col$ union select 'DB LINK' , count(*) from</P>
<P>　　<STRONG>22、按用户查看object种类</STRONG></P>
<P>　　select u.name schema, sum(decode(o.type#, 1, 1, NULL)) indexes,</P>
<P>　　sum(decode(o.type#, 2, 1, NULL)) tables, sum(decode(o.type#, 3, 1, NULL))</P>
<P>　　clusters, sum(decode(o.type#, 4, 1, NULL)) views, sum(decode(o.type#, 5, 1,</P>
<P>　　NULL)) synonyms, sum(decode(o.type#, 6, 1, NULL)) sequences,</P>
<P>　　sum(decode(o.type#, 1, NULL, 2, NULL, 3, NULL, 4, NULL, 5, NULL, 6, NULL, 1))</P>
<P>　　others from sys.obj$ o, sys.user$ u where o.type# &gt;= 1 and u.user# =</P>
<P>　　o.owner# and u.name &lt;&gt; 'PUBLIC' group by u.name order by</P>
<P>　　sys.link$ union select 'CONSTRAINT' , count(*) from sys.con$</P>
<P>　　<STRONG>23、有关connection的相关信息</STRONG></P>
<P>　　1)查看有哪些用户连接</P>
<P>　　select s.osuser os_user_name, decode(sign(48 - command), 1, to_char(command),</P>
<P>　　'Action Code #' || to_char(command) ) action, p.program oracle_process,</P>
<P>　　status session_status, s.terminal terminal, s.program program,</P>
<P>　　s.username user_name, s.fixed_table_sequence activity_meter, '' query,</P>
<P>　　0 memory, 0 max_memory, 0 cpu_usage, s.sid, s.serial# serial_num</P>
<P>　　from v$session s, v$process p where s.paddr=p.addr and s.type = 'USER'</P>
<P>　　order by s.username, s.osuser</P>
<P>　　2)根据v.sid查看对应连接的资源占用等情况</P>
<P>　　select n.name,</P>
<P>　　v.value,</P>
<P>　　n.class,</P>
<P>　　n.statistic#</P>
<P>　　from v$statname n,</P>
<P>　　v$sesstat v</P>
<P>　　where v.sid = 71 and</P>
<P>　　v.statistic# = n.statistic#</P>
<P>　　order by n.class, n.statistic#</P>
<P>　　3)根据sid查看对应连接正在运行的sql</P>
<P>　　select /*+ PUSH_SUBQ */</P>
<P>　　command_type,</P>
<P>　　sql_text,</P>
<P>　　sharable_mem,</P>
<P>　　persistent_mem,</P>
<P>　　runtime_mem,</P>
<P>　　sorts,</P>
<P>　　version_count,</P>
<P>　　loaded_versions,</P>
<P>　　open_versions,</P>
<P>　　users_opening,</P>
<P>　　executions,</P>
<P>　　users_executing,</P>
<P>　　loads,</P>
<P>　　first_load_time,</P>
<P>　　invalidations,</P>
<P>　　parse_calls,</P>
<P>　　disk_reads,</P>
<P>　　buffer_gets,</P>
<P>　　rows_processed,</P>
<P>　　sysdate start_time,</P>
<P>　　sysdate finish_time,</P>
<P>　　'&gt;' || address sql_address,</P>
<P>　　'N' status</P>
<P>　　from v$sqlarea</P>
<P>　　where address = (select sql_address from v$session where sid = 71)</P>
<P>　　<STRONG>24、查询表空间使用情况select a.tablespace_name "表空间名称",</STRONG></P>
<P>　　100-round((nvl(b.bytes_free,0)/a.bytes_alloc)*100,2) "占用率(%)",</P>
<P>　　round(a.bytes_alloc/1024/1024,2) "容量(M)",</P>
<P>　　round(nvl(b.bytes_free,0)/1024/1024,2) "空闲(M)",</P>
<P>　　round((a.bytes_alloc-nvl(b.bytes_free,0))/1024/1024,2) "使用(M)",</P>
<P>　　Largest "最大扩展段(M)",</P>
<P>　　to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') "采样时间"</P>
<P>　　from (select f.tablespace_name,</P>
<P>　　sum(f.bytes) bytes_alloc,</P>
<P>　　sum(decode(f.autoextensible,'YES',f.maxbytes,'NO',f.bytes)) maxbytes</P>
<P>　　from dba_data_files f</P>
<P>　　group by tablespace_name) a,</P>
<P>　　(select f.tablespace_name,</P>
<P>　　sum(f.bytes) bytes_free</P>
<P>　　from dba_free_space f</P>
<P>　　group by tablespace_name) b,</P>
<P>　　(select round(max(ff.length)*16/1024,2) Largest,</P>
<P>　　ts.name tablespace_name</P>
<P>　　from sys.fet$ ff, sys.file$ tf,sys.ts$ ts</P>
<P>　　where ts.ts#=ff.ts# and ff.file#=tf.relfile# and ts.ts#=tf.ts#</P>
<P>　　group by ts.name, tf.blocks) c</P>
<P>　　where a.tablespace_name = b.tablespace_name and a.tablespace_name = c.tablespace_name</P>
<P>　　<STRONG>25、 查询表空间的碎片程度</STRONG></P>
<P>　　select tablespace_name,count(tablespace_name) from dba_free_space group by tablespace_name</P>
<P>　　having count(tablespace_name)&gt;10;</P>
<P>　　alter tablespace name coalesce;</P>
<P>　　alter table name deallocate unused;</P>
<P>　　create or replace view ts_blocks_v as</P>
<P>　　select tablespace_name,block_id,bytes,blocks,'free space' segment_name from dba_free_space</P>
<P>　　union all</P>
<P>　　select tablespace_name,block_id,bytes,blocks,segment_name from dba_extents;</P>
<P>　　select * from ts_blocks_v;</P>
<P>　　select tablespace_name,sum(bytes),max(bytes),count(block_id) from dba_free_space</P>
<P>　　group by tablespace_name;</P></A><img src ="http://www.blogjava.net/TrampEagle/aggbug/32080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-23 11:15 <a href="http://www.blogjava.net/TrampEagle/articles/32080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle函数列表速查</title><link>http://www.blogjava.net/TrampEagle/articles/31946.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 22 Feb 2006 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31946.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31946.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31946.html</trackback:ping><description><![CDATA[<P>引自：<A href="http://www.channel7.cn/2004/10-20/203215.html">http://www.channel7.cn/2004/10-20/203215.html</A><BR><BR>PL/SQL单行函数和组函数详解<BR>　函数是一种有零个或多个参数并且有一个返回值的程序。在SQL中Oracle内建了一系列函数，这些函数都可被称为SQL或PL/SQL语句，函数主要分为两大类： </P>
<P>　　 单行函数</P>
<P>　　 组函数 </P>
<P>　　本文将讨论如何利用单行函数以及使用规则。</P>
<P>　　SQL中的单行函数</P>
<P>　　SQL和PL/SQL中自带很多类型的函数，有字符、数字、日期、转换、和混合型等多种函数用于处理单行数据，因此这些都可被统称为单行函数。这些函数均可用于SELECT,WHERE、ORDER BY等子句中，例如下面的例子中就包含了TO_CHAR,UPPER,SOUNDEX等单行函数。<BR>SELECT ename,TO_CHAR(hiredate,'day,DD-Mon-YYYY')FROM empWhere UPPER(ename) Like 'AL%'ORDER BY SOUNDEX(ename)</P>
<P>　　单行函数也可以在其他语句中使用，如update的SET子句，INSERT的VALUES子句，DELET的WHERE子句,认证考试特别注意在SELECT语句中使用这些函数，所以我们的注意力也集中在SELECT语句中。</P>
<P>　　NULL和单行函数</P>
<P>　　在如何理解NULL上开始是很困难的，就算是一个很有经验的人依然对此感到困惑。NULL值表示一个未知数据或者一个空值，算术操作符的任何一个操作数为NULL值，结果均为提个NULL值,这个规则也适合很多函数，只有CONCAT,DECODE,DUMP,NVL,REPLACE在调用了NULL参数时能够返回非NULL值。在这些中NVL函数时最重要的，因为他能直接处理NULL值，NVL有两个参数：NVL(x1,x2),x1和x2都式表达式，当x1为null时返回X2,否则返回x1。</P>
<P>　　下面我们看看emp数据表它包含了薪水、奖金两项，需要计算总的补偿<BR>column name emp_id salary bonuskey type pk nulls/unique nn,u nnfk table datatype number number numberlength 11.2 11.2</P>
<P>　　不是简单的将薪水和奖金加起来就可以了，如果某一行是null值那么结果就将是null，比如下面的例子：<BR>update empset salary=(salary+bonus)*1.1</P>
<P>　　这个语句中，雇员的工资和奖金都将更新为一个新的值，但是如果没有奖金，即 salary + null,那么就会得出错误的结论，这个时候就要使用nvl函数来排除null值的影响。<BR>所以正确的语句是：<BR>update empset salary=(salary+nvl(bonus,0)*1.1<BR>单行字符串函数</P>
<P>　　单行字符串函数用于操作字符串数据，他们大多数有一个或多个参数，其中绝大多数返回字符串</P>
<P>　　ASCII()<BR>　　c1是一字符串，返回c1第一个字母的ASCII码，他的逆函数是CHR()<BR>SELECT ASCII('A') BIG_A,ASCII('z') BIG_z FROM empBIG_A BIG_z65 122</P>
<P>　　CHR(＜i＞)[NCHAR_CS]<BR>　　i是一个数字，函数返回十进制表示的字符<BR>select CHR(65),CHR(122),CHR(223) FROM empCHR65 CHR122 CHR223A z B</P>
<P>　　CONCAT(,)<BR>　　c1,c2均为字符串，函数将c2连接到c1的后面，如果c1为null,将返回c2.如果c2为null,则返回c1，如果c1、c2都为null，则返回null。他和操作符||返回的结果相同<BR>select concat('slobo ','Svoboda') username from dualusernameslobo Syoboda</P>
<P>　　INITCAP()<BR>　　c1为一字符串。函数将每个单词的第一个字母大写其它字母小写返回。单词由空格，控制字符，标点符号限制。<BR>select INITCAP('veni,vedi,vici') Ceasar from dualCeasarVeni,Vedi,Vici</P>
<P>　　INSTR(,[,＜i＞[,]])<BR>　　c1,c2均为字符串，i,j为整数。函数返回c2在c1中第j次出现的位置，搜索从c1的第i个字符开始。当没有发现需要的字符时返回0,如果i为负数，那么搜索将从右到左进行，但是位置的计算还是从左到右，i和j的缺省值为1.<BR>select INSTR('Mississippi','i',3,3) from dualINSTR('MISSISSIPPI','I',3,3)11select INSTR('Mississippi','i',-2,3) from dualINSTR('MISSISSIPPI','I',3,3)2</P>
<P>　　INSTRB(,[,i[,j])<BR>　　与INSTR（）函数一样，只是他返回的是字节，对于单字节INSTRB()等于INSTR()</P>
<P>　　LENGTH()<BR>　　c1为字符串，返回c1的长度，如果c1为null，那么将返回null值。<BR>select LENGTH('Ipso Facto') ergo from dualergo10</P>
<P>　　LENGTHb()<BR>　　与LENGTH()一样，返回字节。</P>
<P>　　lower()<BR>　　返回c的小写字符，经常出现在where子串中<BR>select LOWER(colorname) from itemdetail WHERE LOWER(colorname) LIKE '%white%'COLORNAMEWinterwhite</P>
<P>　　LPAD(,＜i＞[,])<BR>　　c1,c2均为字符串，i为整数。在c1的左侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格，参见RPAD。<BR>select LPAD(answer,7,'') padded,answer unpadded from question;PADDED UNPADDED Yes YesNO NOMaybe maybe</P>
<P>　　LTRIM(,)<BR>　　把c1中最左边的字符去掉，使其第一个字符不在c2中，如果没有c2，那么c1就不会改变。<BR>select LTRIM('Mississippi','Mis') from dualLTRppi</P>
<P>　　RPAD(,＜i＞[,]) <BR>　　在c1的右侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格,其他与LPAD相似</P>
<P>　　RTRIM(,)<BR>　　把c1中最右边的字符去掉，使其第后一个字符不在c2中，如果没有c2，那么c1就不会改变。</P>
<P>　　REPLACE(,[,])<BR>　　c1,c2,c3都是字符串，函数用c3代替出现在c1中的c2后返回。<BR>select REPLACE('uptown','up','down') from dualREPLACEdowntown</P>
<P>　　STBSTR(,＜i＞[,])<BR>　　c1为一字符串，i,j为整数，从c1的第i位开始返回长度为j的子字符串，如果j为空，则直到串的尾部。<BR>select SUBSTR('Message',1,4) from dualSUBSMess</P>
<P>　　SUBSTRB(,＜i＞[,])<BR>　　与SUBSTR大致相同，只是I,J是以字节计算。</P>
<P>　　SOUNDEX()<BR>　　返回与c1发音相似的词<BR>select SOUNDEX('dawes') Dawes SOUNDEX('daws') Daws, SOUNDEX('dawson') from dualDawes Daws DawsonD200 D200 D250</P>
<P>　　TRANSLATE(,,)<BR>　　将c1中与c2相同的字符以c3代替<BR>select TRANSLATE('fumble','uf','ar') test from dualTEXTramble </P>
<P>　　TRIM([[]] from c3)<BR>　　将c3串中的第一个，最后一个，或者都删除。<BR>select TRIM(' space padded ') trim from dual TRIMspace padded</P>
<P>　　UPPER()<BR>　　返回c1的大写，常出现where子串中<BR>select name from dual where UPPER(name) LIKE 'KI%'NAMEKING<BR>单行数字函数</P>
<P>　　单行数字函数操作数字数据，执行数学和算术运算。所有函数都有数字参数并返回数字值。所有三角函数的操作<BR>数和值都是弧度而不是角度，oracle没有提供内建的弧度和角度的转换函数。 </P>
<P></P>
<P>　　ABS()<BR>　　返回n的绝对值</P>
<P>　　ACOS()<BR>　　反余玄函数，返回-1到1之间的数。n表示弧度<BR>select ACOS(-1) pi,ACOS(1) ZERO FROM dualPI ZERO3.14159265 0 </P>
<P>　　ASIN()<BR>　　反正玄函数，返回-1到1，n表示弧度</P>
<P>　　ATAN()<BR>　　反正切函数，返回n的反正切值，n表示弧度。</P>
<P>　　CEIL()<BR>　　返回大于或等于n的最小整数。</P>
<P>　　COS()<BR>　　返回n的余玄值，n为弧度</P>
<P>　　COSH()<BR>　　返回n的双曲余玄值，n 为数字。<BR>select COSH(&lt;1.4&gt;) FROM dualCOSH(1.4)2.15089847</P>
<P>　　EXP()<BR>　　返回e的n次幂，e=2.71828183.</P>
<P>　　FLOOR()<BR>　　返回小于等于N的最大整数。</P>
<P>　　LN()<BR>　　返回N的自然对数，N必须大于0</P>
<P>　　LOG(,)<BR>　　返回以n1为底n2的对数</P>
<P>　　MOD()<BR>　　返回n1除以n2的余数，</P>
<P>　　POWER(,)<BR>　　返回n1的n2次方</P>
<P>　　ROUND(,)<BR>　　返回舍入小数点右边n2位的n1的值，n2的缺省值为0，这回将小数点最接近的整数，如果n2为负数就舍入到小数点左边相应的位上，n2必须是整数。<BR>select ROUND(12345,-2),ROUND(12345.54321,2) FROM dualROUND(12345,-2) ROUND(12345.54321,2)12300 12345.54</P>
<P>　　SIGN()<BR>　　如果n为负数，返回-1,如果n为正数，返回1，如果n=0返回0.</P>
<P>　　SIN（)<BR>　　返回n的正玄值,n为弧度。</P>
<P>　　SINH()<BR>　　返回n的双曲正玄值,n为弧度。</P>
<P>　　SQRT()<BR>　　返回n的平方根,n为弧度</P>
<P>　　TAN（)<BR>　　返回n的正切值,n为弧度</P>
<P>　　TANH()<BR>　　返回n的双曲正切值,n为弧度</P>
<P>　　TRUNC(,)<BR>　　返回截尾到n2位小数的n1的值，n2缺省设置为0，当n2为缺省设置时会将n1截尾为整数，如果n2为负值，就截尾在小数点左边相应的位上。</P>
<P>　　单行日期函数</P>
<P>　　单行日期函数操作DATA数据类型，绝大多数都有DATA数据类型的参数，绝大多数返回的也是DATA数据类型的值。</P>
<P>　　ADD_MONTHS(,＜i＞)<BR>　　返回日期d加上i个月后的结果。i可以使任意整数。如果i是一个小数，那么数据库将隐式的他转换成整数，将会截去小数点后面的部分。</P>
<P>　　LAST_DAY()<BR>　　函数返回包含日期d的月份的最后一天 </P>
<P>　　MONTHS_BETWEEN(,)<BR>　　返回d1和d2之间月的数目,如果d1和d2的日的日期都相同，或者都使该月的最后一天，那么将返回一个整数，否则会返回的结果将包含一个分数。</P>
<P>　　NEW_TIME(,,)<BR>　　d1是一个日期数据类型，当时区tz1中的日期和时间是d时，返回时区tz2中的日期和时间。tz1和tz2时字符串。</P>
<P>　　NEXT_DAY(,)<BR>　　返回日期d后由dow给出的条件的第一天，dow使用当前会话中给出的语言指定了一周中的某一天，返回的时间分量与d的时间分量相同。<BR>select NEXT_DAY('01-Jan-2000','Monday') "1st Monday",NEXT_DAY('01-Nov-2004','Tuesday')+7 "2nd Tuesday") from dual;1st Monday 2nd Tuesday03-Jan-2000 09-Nov-2004 </P>
<P>　　ROUND([,])<BR>　　将日期d按照fmt指定的格式舍入，fmt为字符串。</P>
<P>　　SYADATE<BR>　　函数没有参数，返回当前日期和时间。</P>
<P>　　TRUNC([,]) <BR>　　返回由fmt指定的单位的日期d.<BR>单行转换函数</P>
<P>　　单行转换函数用于操作多数据类型，在数据类型之间进行转换。</P>
<P>　　CHARTORWID()<BR>　　c 使一个字符串，函数将c转换为RWID数据类型。<BR>SELECT test_id from test_case where rowid=CHARTORWID('AAAA0SAACAAAALiAAA') </P>
<P>　　CONVERT(,[,])<BR>　　c尾字符串，dset、sset是两个字符集，函数将字符串c由sset字符集转换为dset字符集，sset的缺省设置为数据库的字符集。</P>
<P>　　HEXTORAW()<BR>　　x为16进制的字符串，函数将16进制的x转换为RAW数据类型。</P>
<P>　　RAWTOHEX()<BR>　　x是RAW数据类型字符串，函数将RAW数据类转换为16进制的数据类型。</P>
<P>　　ROWIDTOCHAR()<BR>　　函数将ROWID数据类型转换为CHAR数据类型。</P>
<P>　　TO_CHAR([[,)<BR>　　x是一个data或number数据类型，函数将x转换成fmt指定格式的char数据类型，如果x为日期nlsparm=NLS_DATE_LANGUAGE 控制返回的月份和日份所使用的语言。如果x为数字nlsparm=NLS_NUMERIC_CHARACTERS 用来指定小数位和千分位的分隔符，以及货币符号。<BR>NLS_NUMERIC_CHARACTERS ="dg", NLS_CURRENCY="string"</P>
<P>　　TO_DATE([,[,）<BR>　　c表示字符串，fmt表示一种特殊格式的字符串。返回按照fmt格式显示的c,nlsparm表示使用的语言。函数将字符串c转换成date数据类型。</P>
<P>　　TO_MULTI_BYTE()<BR>　　c表示一个字符串，函数将c的担子截字符转换成多字节字符。</P>
<P>　　TO_NUMBER([,[,)<BR>　　c表示字符串，fmt表示一个特殊格式的字符串，函数返回值按照fmt指定的格式显示。nlsparm表示语言，函数将返回c代表的数字。</P>
<P>　　TO_SINGLE_BYTE()<BR>　　将字符串c中得多字节字符转化成等价的单字节字符。该函数仅当数据库字符集同时包含单字节和多字节字符时才使用</P>
<P>　　其它单行函数</P>
<P>　　BFILENAME( <BR>,)<BR>　　dir是一个directory类型的对象，file为一文件名。函数返回一个空的BFILE位置值指示符，函数用于初始化BFILE变量或者是BFILE列。</P>
<P>　　DECODE(,,[,,,[])<BR>　　x是一个表达式，m1是一个匹配表达式，x与m1比较，如果m1等于x，那么返回r1,否则,x与m2比较，依次类推m3,m4,m5....直到有返回结果。</P>
<P>　　DUMP(,[,[,[,]]])<BR>　　x是一个表达式或字符，fmt表示8进制、10进制、16进制、或则单字符。函数返回包含了有关x的内部表示信息的VARCHAR2类型的值。如果指定了n1,n2那么从n1开始的长度为n2的字节将被返回。</P>
<P>　　EMPTY_BLOB()<BR>　　该函数没有参数，函数返回 一个空的BLOB位置指示符。函数用于初始化一个BLOB变量或BLOB列。</P>
<P>　　EMPTY_CLOB()<BR>　　该函数没有参数，函数返回 一个空的CLOB位置指示符。函数用于初始化一个CLOB变量或CLOB列。</P>
<P>　　GREATEST()<BR>　　exp_list是一列表达式，返回其中最大的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，那么返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。</P>
<P>　　LEAST()<BR>　　exp_list是一列表达式，返回其中最小的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，将返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。</P>
<P>　　UID<BR>　　该函数没有参数，返回唯一标示当前数据库用户的整数。</P>
<P>　　USER<BR>　　返回当前用户的用户名</P>
<P>　　USERENV()<BR>　　基于opt返回包含当前会话信息。opt的可选值为：</P>
<P>　　ISDBA　 　　会话中SYSDBA脚色响应，返回TRUE <BR>　　SESSIONID 　返回审计会话标示符<BR>　　ENTRYID 　　返回可用的审计项标示符 <BR>　　INSTANCE　　在会话连接后，返回实例标示符。该值只用于运行Parallel 服务器并且有 多个实例的情况下使用。<BR>　　LANGUAGE　　返回语言、地域、数据库设置的字符集。<BR>　　LANG　　　　返回语言名称的ISO缩写。<BR>　　TERMINAL　　为当前会话使用的终端或计算机返回操作系统的标示符。 </P>
<P></P>
<P>　　VSIZE()<BR>　　x是一个表达式。返回x内部表示的字节数。<BR>SQL中的组函数</P>
<P>　　组函数也叫集合函数，返回基于多个行的单一结果，行的准确数量无法确定，除非查询被执行并且所有的结果都被包含在内。与单行函数不同的是，在解析时所有的行都是已知的。由于这种差别使组函数与单行函数有在要求和行为上有微小的差异.</P>
<P>　　组（多行）函数</P>
<P>　　与单行函数相比，oracle提供了丰富的基于组的，多行的函数。这些函数可以在select或select的having子句中使用，当用于select子串时常常都和GROUP BY一起使用。</P>
<P>　　AVG([{DISYINCT|ALL}])<BR>　　返回数值的平均值。缺省设置为ALL.<BR>SELECT AVG(sal),AVG(ALL sal),AVG(DISTINCT sal) FROM scott.empAVG(SAL) AVG(ALL SAL) AVG(DISTINCT SAL)1877.94118 1877.94118 1916.071413</P>
<P>　　COUNT({*|DISTINCT|ALL} )<BR>　　返回查询中行的数目，缺省设置是ALL,*表示返回所有的行。</P>
<P>　　MAX([{DISTINCT|ALL}])<BR>　　返回选择列表项目的最大值，如果x是字符串数据类型，他返回一个VARCHAR2数据类型，如果X是一个DATA数据类型，返回一个日期，如果X是numeric数据类型，返回一个数字。注意distinct和all不起作用，应为最大值与这两种设置是相同的。</P>
<P>　　MIN([{DISTINCT|ALL}])<BR>　　返回选择列表项目的最小值。</P>
<P>　　STDDEV([{DISTINCT|ALL}])<BR>　　返回选者的列表项目的标准差，所谓标准差是方差的平方根。</P>
<P>　　SUM([{DISTINCT|ALL}])<BR>　　返回选择列表项目的数值的总和。</P>
<P>　　VARIANCE([{DISTINCT|ALL}])<BR>　　返回选择列表项目的统计方差。</P>
<P>　　用GROUP BY给数据分组</P>
<P>　　正如题目暗示的那样组函数就是操作那些已经分好组的数据，我们告诉数据库用GROUP BY怎样给数据分组或者分类，当我们在SELECT语句的SELECT子句中使用组函数时，我们必须把为分组或非常数列放置在GROUP BY子句中，如果没有用group by进行专门处理，那么缺省的分类是将整个结果设为一类。<BR>select stat,counter(*) zip_count from zip_codes GROUP BY state;ST ZIP_COUNT-- ---------AK 360AL 1212AR 1309AZ 768CA 3982</P>
<P>　　在这个例子中，我们用state字段分类；如果我们要将结果按照zip_codes排序,可以用ORDER BY语句，ORDER BY子句可以使用列或组函数。<BR>select stat,counter(*) zip_count from zip_codes GROUP BY state ORDER BY COUNT(*) DESC;ST COUNT(*)-- --------NY 4312PA 4297TX 4123CA 3982</P>
<P>　　用HAVING子句限制分组数据</P>
<P>　　现在你已经知道了在查询的SELECT语句和ORDER BY子句中使用主函数，组函数只能用于两个子串中，组函数不能用于WHERE子串中，例如下面的查询是错误的：<BR>错误SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' AND SUM(sale_amount)&gt;10000 GROUP BY sales_clerk</P>
<P>　　这个语句中数据库不知道SUM()是什么，当我们需要指示数据库对行分组，然后限制分组后的行的输出时，正确的方法是使用HAVING语句：<BR>SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' GROUP BY sales_clerkHAVING SUM(sale_amount)&gt;10000;</P>
<P>　　嵌套函数</P>
<P>　　函数可以嵌套。一个函数的输出可以是另一个函数的输入。操作数有一个可继承的执行过程。但函数的优先权只是基于位置，函数遵循由内到外，由左到右的原则。嵌套技术一般用于象DECODE这样的能被用于逻辑判断语句IF....THEN...ELSE的函数。</P><img src ="http://www.blogjava.net/TrampEagle/aggbug/31946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-22 13:05 <a href="http://www.blogjava.net/TrampEagle/articles/31946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE常用傻瓜問題1000問(之四)</title><link>http://www.blogjava.net/TrampEagle/articles/31878.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 21 Feb 2006 14:49:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31878.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31878.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31878.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31878.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31878.html</trackback:ping><description><![CDATA[引自：<A href="http://www.newebug.com/article/database/2167.shtml">http://www.newebug.com/article/database/2167.shtml</A><BR><BR>虚擬字段 <BR>133. CURRVAL 和 nextval <BR>　 为表创建序列 <BR>　 CREATE SEQUENCE EMPSEQ ... ; <BR>　 SELECT empseq.currval FROM DUAL ; <BR>　 自动插入序列的数值 <BR>　 INSERT INTO emp <BR>　　　　valueS (empseq.nextval, 'LEWIS', 'CLERK', <BR>　　　　　　　　7902, SYSDATE, 1200, NULL, 20) ; <BR><BR>134. ROWNUM <BR>　 按设定排序的行的序号 <BR>　 SELECT * FROM emp WHERE ROWNUM &lt; 10 ; <BR><BR>135. ROWID <BR>　 返回行的物理地址 <BR>　 SELECT ROWID, ename FROM emp　WHERE deptno = 20 ; <BR><BR>136. 将N秒转换为时分秒格式？ <BR>　 set serverout on <BR>　 declare <BR>　 N number := 1000000; <BR>　 ret varchar2(100); <BR>　 begin <BR>　 ret := trunc(n/3600) || '小时' || to_char(to_date(mod(n,3600),'sssss'),'fmmi"分　 "ss"秒"') ; <BR>　 dbms_output.put_line(ret); <BR>　 end; <BR><BR>137. 如何查询做比较大的排序的进程？ <BR>　 SELECT b.tablespace, b.segfile#, b.segblk#, b.blocks, a.sid, a.serial#, <BR>　 a.username, a.osuser, a.status <BR>　 FROM v$session a,v$sort_usage b <BR>　 WHERE a.saddr = b.session_addr <BR>　 ORDER BY b.tablespace, b.segfile#, b.segblk#, b.blocks ; <BR><BR>138. 如何查询做比较大的排序的进程的SQL语句？ <BR>　 select /*+ ORDERED */ sql_text from v$sqltext a <BR>　 where a.hash_value = ( <BR>　 select sql_hash_value from v$session b <BR>　 where b.sid = &amp;sid and b.serial# = &amp;serial) <BR>　 order by piece asc ; <BR><BR>139. 如何查找重复记录？ <BR>　 SELECT * FROM TABLE_NAME <BR>　 WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D <BR>　 WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2); <BR><BR>140. 如何删除重复记录？ <BR>　 DELETE FROM TABLE_NAME <BR>　 WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D <BR>　 WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2); <BR><BR>141. 如何快速编译所有视图？ <BR>　 SQL &gt;SPOOL VIEW1.SQL <BR>　 SQL &gt;SELECT ‘ALTER VIEW ‘||TNAME||’ <BR>　 COMPILE;’ FROM TAB; <BR>　 SQL &gt;SPOOL OFF <BR>　 然后执行VIEW1.SQL即可。 <BR>　 SQL &gt;@VIEW1.SQL; <BR><BR>142. ORA-01555 SNAPSHOT TOO OLD的解决办法 <BR>　 增加MINEXTENTS的值，增加区的大小，设置一个高的OPTIMAL值。 <BR><BR>143. 事务要求的回滚段空间不够，表现为表空间用满（ORA-01560错误），回滚段扩展到达参数　　　MAXEXTENTS的值（ORA-01628）的解决办法. <BR>　 向回滚段表空间添加文件或使已有的文件变大；增加MAXEXTENTS的值。 <BR><BR>144. 如何加密ORACLE的存储过程？ <BR>　　下列存储过程内容放在AA.SQL文件中 <BR>　　create or replace procedure testCCB(i in number) as <BR>　　begin <BR>　　dbms_output.put_line('输入参数是'||to_char(i)); <BR>　　end; <BR><BR>　　SQL&gt;wrap iname=a.sql; <BR>　　PL/SQL Wrapper: Release 8.1.7.0.0 - Production on Tue Nov 27 22:26:48 2001 <BR>　　Copyright (c) Oracle Corporation 1993, 2000.　All Rights Reserved. <BR>　　Processing AA.sql to AA.plb <BR>　　运行AA.plb <BR>　　SQL&gt; @AA.plb ; <BR><BR>145. 如何监控事例的等待？ <BR>　 select event,sum(decode(wait_Time,0,0,1)) "Prev", <BR>　 sum(decode(wait_Time,0,1,0)) "Curr",count(*) "Tot" <BR>　 from v$session_Wait <BR>　 group by event order by 4; <BR><BR>146. 如何回滚段的争用情况？ <BR>　 select name, waits, gets, waits/gets "Ratio" <BR>　 from v$rollstat C, v$rollname D <BR>　 where C.usn = D.usn; <BR><BR>147. 如何监控表空间的 I/O 比例？ <BR>　 select B.tablespace_name name,B.file_name "file",A.phyrds pyr, <BR>　 A.phyblkrd pbr,A.phywrts pyw, A.phyblkwrt pbw <BR>　 from v$filestat A, dba_data_files B <BR>　 where A.file# = B.file_id <BR>　 order by B.tablespace_name; <BR><BR>148. 如何监控文件系统的 I/O 比例？ <BR>　 select substr(C.file#,1,2) "#", substr(C.name,1,30) "Name", <BR>　 C.status, C.bytes, D.phyrds, D.phywrts <BR>　 from v$datafile C, v$filestat D <BR>　 where C.file# = D.file#; <BR><BR>149. 如何在某个用户下找所有的索引？ <BR>　 select user_indexes.table_name, user_indexes.index_name,uniqueness, column_name <BR>　 from user_ind_columns, user_indexes <BR>　 where user_ind_columns.index_name = user_indexes.index_name <BR>　 and user_ind_columns.table_name = user_indexes.table_name <BR>　 order by user_indexes.table_type, user_indexes.table_name, <BR>　 user_indexes.index_name, column_position; <BR><BR>150. 如何监控 SGA 的命中率？ <BR>　 select a.value + b.value "logical_reads", c.value "phys_reads", <BR>　 round(100 * ((a.value+b.value)-c.value) / (a.value+b.value)) "BUFFER HIT RATIO" <BR>　 from v$sysstat a, v$sysstat b, v$sysstat c <BR>　 where a.statistic# = 38 and b.statistic# = 39 <BR>　 and c.statistic# = 40; <BR><BR>151. 如何监控 SGA 中字典缓冲区的命中率？ <BR>　 select parameter, gets,Getmisses , getmisses/(gets+getmisses)*100 "miss ratio", <BR>　 (1-(sum(getmisses)/ (sum(gets)+sum(getmisses))))*100 "Hit ratio" <BR>　 from v$rowcache <BR>　 where gets+getmisses &lt;&gt;0 <BR>　 group by parameter, gets, getmisses; <BR><BR>152. 如何监控 SGA 中共享缓存区的命中率，应该小于1% ？ <BR>　 select sum(pins) "Total Pins", sum(reloads) "Total Reloads", <BR>　 sum(reloads)/sum(pins) *100 libcache <BR>　 from v$librarycache; <BR><BR>　 select sum(pinhits-reloads)/sum(pins) "hit radio",sum(reloads)/sum(pins)　　"reload percent" <BR>　 from v$librarycache; <BR><BR>153. 如何显示所有数据库对象的类别和大小？ <BR>　 select count(name) num_instances ,type ,sum(source_size) source_size , <BR>　 sum(parsed_size) parsed_size ,sum(code_size) code_size ,sum(error_size)　　error_size, <BR>　 sum(source_size) +sum(parsed_size) +sum(code_size) +sum(error_size)　　size_required <BR>　 from dba_object_size <BR>　 group by type order by 2; <BR><BR>154. 监控 SGA 中重做日志缓存区的命中率，应该小于1% <BR>　 SELECT name, gets, misses, immediate_gets, immediate_misses, <BR>　 Decode(gets,0,0,misses/gets*100) ratio1, <BR>　 Decode(immediate_gets+immediate_misses,0,0, <BR>　 immediate_misses/(immediate_gets+immediate_misses)*100) ratio2 <BR>　 FROM v$latch WHERE name IN ('redo allocation', 'redo copy'); <BR><BR>155. 监控内存和硬盘的排序比率，最好使它小于 .10，增加 sort_area_size <BR>　 SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)', 'sorts　　　(disk)'); <BR><BR><BR>156. 如何监控当前数据库谁在运行什么SQL语句？ <BR>　 SELECT osuser, username, sql_text from v$session a, v$sqltext b <BR>　 where a.sql_address =b.address order by address, piece; <BR><BR>157. 如何监控字典缓冲区？ <BR>　 SELECT (SUM(PINS - RELOADS)) / SUM(PINS) "LIB CACHE" FROM V$LIBRARYCACHE; <BR>　 SELECT (SUM(GETS - GETMISSES - USAGE - FIXED)) / SUM(GETS) "ROW CACHE" FROM　　V$ROWCACHE; <BR>　 SELECT SUM(PINS) "EXECUTIONS", SUM(RELOADS) "CACHE MISSES WHILE EXECUTING" FROM　　V$LIBRARYCACHE; <BR>　 后者除以前者,此比率小于1%,接近0%为好。 <BR><BR>　 SELECT SUM(GETS) "DICTIONARY GETS",SUM(GETMISSES) "DICTIONARY CACHE GET MISSES" <BR>　 FROM V$ROWCACHE <BR><BR><BR>158. 监控 MTS <BR>　 select busy/(busy+idle) "shared servers busy" from v$dispatcher; <BR>　 此值大于0.5时，参数需加大 <BR>　 select sum(wait)/sum(totalq) "dispatcher waits" from v$queue where　　type='dispatcher'; <BR>　 select count(*) from v$dispatcher; <BR>　 select servers_highwater from v$mts; <BR>　 servers_highwater接近mts_max_servers时，参数需加大 <BR><BR>159. 如何知道当前用户的ID号? <BR>　　SQL&gt;SHOW USER; <BR>　　OR <BR>　　SQL&gt;select user from dual; <BR><BR>160. 如何查看碎片程度高的表? <BR>　 SELECT segment_name table_name , COUNT(*) extents <BR>　 FROM dba_segments WHERE owner NOT IN ('SYS', 'SYSTEM') GROUP BY segment_name <BR>　 HAVING COUNT(*) = (SELECT MAX( COUNT(*) ) FROM dba_segments GROUP BY　　　 segment_name); <BR><BR>162. 如何知道表在表空间中的存储情况? <BR>　 select segment_name,sum(bytes),count(*) ext_quan from dba_extents where <BR>　 tablespace_name='&amp;tablespace_name' and segment_type='TABLE' group by　　　 tablespace_name,segment_name; <BR><BR>163. 如何知道索引在表空间中的存储情况? <BR>　 select segment_name,count(*) from dba_extents where segment_type='INDEX' and　　　 owner='&amp;owner' <BR>　 group by segment_name; <BR><BR>164、如何知道使用CPU多的用户session? <BR>　 11是cpu used by this session <BR><BR>　 select a.sid,spid,status,substr(a.program,1,40)　　　 prog,a.terminal,osuser,value/60/100 value <BR>　 from v$session a,v$process b,v$sesstat c <BR>　 where c.statistic#=11 and c.sid=a.sid and a.paddr=b.addr order by value desc; <BR><BR>165. 如何知道监听器日志文件? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/NETWORK/LOG/LISTENER.LOG <BR><BR>166. 如何知道监听器参数文件? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/NETWORK/ADMIN/LISTENER.ORA <BR><BR>167. 如何知道TNS 连接文件? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/NETWORK/ADMIN/TNSNAMES.ORA <BR><BR>168. 如何知道Sql*Net 环境文件? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/NETWORK/ADMIN/SQLNET.ORA <BR><BR>169. 如何知道警告日志文件? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/ADMIN/SID/BDUMP/SIDALRT.LOG <BR><BR>170. 如何知道基本结构? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/RDBMS/ADMIN/STANDARD.SQL <BR><BR>171. 如何知道建立数据字典视图? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/RDBMS/ADMIN/CATALOG.SQL <BR><BR>172. 如何知道建立审计用数据字典视图? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/RDBMS/ADMIN/CATAUDIT.SQL <BR><BR>173. 如何知道建立快照用数据字典视图? <BR>　 以8I为例 <BR>　 $ORACLE_HOME/RDBMS/ADMIN/CATSNAP.SQL <BR><BR>
<SCRIPT>
var tixa_nadInIframe=false; <!-- iframe flag -->
var tixa_nadRowCount=1; <!--the row count of narrowad-->
var tixa_nadColumnCount=4; <!--the column count of narrowad-->
var tixa_nadHeight=85; <!--total height of narrowad-->
var tixa_nadWidth=700; <!--total width of narrowad-->
var tixa_nadBorderColor='DEB6BD'; <!--the color of the narrowad's border-->
var tixa_nadBgColor='FFF7F7';  <!--the color of the narrowad's background-->
var tixa_nadTitleColor='0000ff'; <!--the color of the ad's title-->
var tixa_nadDescColor='000000'; <!--the color of the ad's description-->
var tixa_adType='text'; <!--narrowad type-->
</SCRIPT>

<SCRIPT src="http://union.narrowad.com/proxy/narrowad.jsp?wid=767&amp;cid=4429"></SCRIPT><img src ="http://www.blogjava.net/TrampEagle/aggbug/31878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-21 22:49 <a href="http://www.blogjava.net/TrampEagle/articles/31878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE常用傻瓜問題1000問(之三)</title><link>http://www.blogjava.net/TrampEagle/articles/31876.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 21 Feb 2006 14:48:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31876.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31876.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31876.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31876.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31876.html</trackback:ping><description><![CDATA[引自：<A href="http://www.newebug.com/article/database/2166.shtml">http://www.newebug.com/article/database/2166.shtml</A><BR><BR>
<H2 align=center>ORACLE常用傻瓜問題1000問(之三)</H2>
<DIV align=center>
<P>(文档类别：<B><A title="数据库 技术文章" href="http://www.newebug.com/article/database/index.shtml">数据库</A></B>)　2004-7-15</P>
<TABLE width="95%" border=0>
<TBODY>
<TR>
<TD>88. CHR()的反函數是? <BR><BR>　　ASCII() <BR><BR>　　SELECT CHAR(65) FROM DUAL;　 <BR><BR>　　SELECT ASCII('A') FROM DUAL; <BR><BR><BR><BR>89. 字符串的連接 <BR><BR>　　SELECT CONCAT(COL1,COL2) FROM TABLE ; <BR><BR>　　SELECT COL1||COL2 FROM TABLE ; <BR><BR><BR><BR>90. 怎么把select出来的结果导到一个文本文件中？ <BR><BR>　　SQL&gt;SPOOL　C:\ABCD.TXT; <BR><BR>　　SQL&gt;select *　from table; <BR><BR>　　SQL &gt;spool off; <BR><BR><BR><BR>91. 怎样估算SQL执行的I/O数 ? <BR><BR>　　SQL&gt;SET AUTOTRACE ON ; <BR><BR>　　SQL&gt;SELECT * FROM TABLE; <BR><BR>　　OR <BR><BR>　　SQL&gt;SELECT *　FROM　v$filestat ; <BR><BR>可以查看IO数 <BR><BR><BR><BR>92. 如何在sqlplus下改变字段大小? <BR><BR>　　alter table table_name modify (field_name varchar2(100)); <BR><BR>　　改大行，改小不行（除非都是空的） <BR><BR><BR><BR>93. 如何查询某天的数据? <BR><BR>　　select * from table_name where trunc(日期字段)＝to_date('2003-05-02','yyyy-mm-dd'); <BR><BR><BR><BR>94. sql 语句如何插入全年日期？ <BR><BR>create table BSYEAR (d date); <BR>insert into BSYEAR <BR>select to_date('20030101','yyyymmdd')+rownum-1 <BR>from all_objects <BR>where rownum &lt;= to_char(to_date('20031231','yyyymmdd'),'ddd'); <BR><BR><BR><BR>95. 如果修改表名? <BR><BR>　alter table old_table_name rename to new_table_name; <BR><BR><BR><BR>96. 如何取得命令的返回状态值？ <BR><BR>sqlcode=0 <BR><BR><BR><BR>97. 如何知道用户拥有的权限? <BR><BR>　　SELECT * FROM dba_sys_privs ; <BR><BR><BR><BR>98. 从网上下载的ORACLE9I与市场上卖的标准版有什么区别？ <BR><BR>　　　　　从功能上说没有区别，只不过oracle公司有明文规定；从网站上下载的oracle产品不得用于 商业用途，否则侵权。 <BR><BR><BR><BR>99. 怎样判断数据库是运行在归档模式下还是运行在非归档模式下？ <BR><BR>进入dbastudio，历程--〉数据库---〉归档查看。 <BR><BR><BR><BR>100. sql&gt;startup pfile和ifile,spfiled有什么区别？ <BR><BR>pfile就是Oracle传统的初始化参数文件，文本格式的。 <BR>ifile类似于c语言里的include，用于把另一个文件引入 <BR>spfile是9i里新增的并且是默认的参数文件，二进制格式 <BR>startup后应该只可接pfile <BR><BR><BR><BR>101. 如何搜索出前N条记录？ <BR><BR>SELECT * FROM empLOYEE WHERE ROWNUM &lt; n <BR>ORDER BY empno; <BR><BR><BR><BR>102. 如何知道机器上的Oracle支持多少并发用户数? <BR><BR>　　　　SQL&gt;conn internal　; <BR>SQL&gt;show parameter processes ; <BR><BR><BR><BR>103. db_block_size可以修改嗎? <BR><BR>　　 一般不可以﹐不建議這樣做的。 <BR><BR><BR><BR>104. 如何统计两个表的记录总数? <BR><BR>　 select (select count(id) from aa)+(select count(id) from bb) 总数 from dual; <BR><BR><BR><BR>105. 怎样用Sql语句实现查找一列中第N大值？ <BR><BR>　 select * from <BR>(select t.*,dense_rank() over (order by sal) rank from employee) <BR>where rank = N; <BR><BR><BR><BR><BR><BR>106. 如何在给现有的日期加上2年？( <BR><BR>　　select add_months(sysdate,24) from dual; <BR><BR><BR><BR>107. USED_UBLK为负值表示什么意思? <BR><BR>　　　 It is "harmless". <BR><BR><BR><BR>108. Connect string是指什么? <BR><BR>　　　 应该是tnsnames.ora中的服务名后面的内容 <BR><BR><BR><BR>109. 怎样扩大REDO LOG的大小？ <BR><BR>　　　　建立一个临时的redolog组，然后切换日志，删除以前的日志，建立新的日志。 <BR><BR><BR><BR>110. tablespace 是否不能大于4G? <BR><BR>　 没有限制. <BR><BR><BR><BR>111. 返回大于等于N的最小整數值? <BR><BR>　　SELECT CEIL(N)　FROM DUAL; <BR><BR><BR><BR>112. 返回小于等于N的最小整數值? <BR><BR>　　SELECT FLOOR(N)　FROM DUAL; <BR><BR><BR><BR>113. 返回當前月的最后一天? <BR><BR>　　 SELECT LAST_DAY(SYSDATE)　FROM DUAL; <BR><BR><BR><BR>114. 如何不同用戶間數據導入? <BR><BR>　IMP　SYSTEM/MANAGER　FILE=AA.DMP　FROMUSER=USER_OLD　 TOUSER=USER_NEW　ROWS=Y　INDEXES=Y ; <BR><BR><BR><BR>115. 如何找数据库表的主键字段的名称? <BR><BR>　 SQL&gt;SELECT * FROM user_constraints WHERE CONSTRAINT_TYPE='P' and　 table_name='TABLE_NAME'; <BR><BR><BR>116. 兩個結果集互加的函數? <BR><BR>　 SQL&gt;SELECT * FROM BSEMPMS_OLD INTERSECT SELECT * FROM BSEMPMS_NEW; <BR>　SQL&gt;SELECT * FROM BSEMPMS_OLD UNION SELECT * FROM BSEMPMS_NEW; <BR>　SQL&gt;SELECT * FROM BSEMPMS_OLD UNION ALL SELECT * FROM BSEMPMS_NEW; <BR><BR><BR>117. 兩個結果集互減的函數? <BR>SQL&gt;SELECT * FROM BSEMPMS_OLD MINUS SELECT * FROM BSEMPMS_NEW; <BR><BR><BR>118. 如何配置Sequence? <BR><BR>　　建sequence seq_custid <BR>　create sequence seq_custid start 1 incrememt by 1; <BR>　建表时: <BR>　create table cust <BR>　{ cust_id smallint not null, <BR>　...} <BR>　insert 时: <BR>　insert into table cust <BR>　values( seq_cust.nextval, ...) <BR><BR><BR>日期的各部分的常用的的寫法 <BR><BR>119&gt;.取時間點的年份的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'YYYY') FROM DUAL; <BR><BR><BR><BR>120&gt;.取時間點的月份的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'MM') FROM DUAL; <BR><BR><BR><BR>121&gt;.取時間點的日的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'DD') FROM DUAL; <BR><BR><BR><BR>122&gt;.取時間點的時的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'HH24') FROM DUAL; <BR><BR><BR><BR>123&gt;.取時間點的分的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'MI') FROM DUAL; <BR><BR><BR><BR>124&gt;.取時間點的秒的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'SS') FROM DUAL; <BR><BR><BR><BR>125&gt;.取時間點的日期的寫法: <BR>　　 SELECT TRUNC(SYSDATE) FROM DUAL; <BR><BR><BR><BR>126&gt;.取時間點的時間的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'HH24:MI:SS') FROM DUAL; <BR><BR><BR><BR>127&gt;.日期,時間形態變為字符形態 <BR>　　 SELECT TO_CHAR(SYSDATE) FROM DUAL; <BR><BR><BR><BR>128&gt;.將字符串轉換成日期或時間形態: <BR>　　 SELECT TO_DATE('2003/08/01') FROM DUAL; <BR><BR><BR><BR>129&gt;.返回參數的星期几的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'D') FROM DUAL; <BR><BR><BR><BR>130&gt;.返回參數一年中的第几天的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'DDD') FROM DUAL; <BR><BR><BR><BR>131&gt;.返回午夜和參數中指定的時間值之間的秒數的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'SSSSS') FROM DUAL; <BR><BR><BR><BR>132&gt;.返回參數中一年的第几周的寫法: <BR>　　 SELECT TO_CHAR(SYSDATE,'WW') FROM DUAL; <BR><BR>
<SCRIPT>
var tixa_nadInIframe=false; <!-- iframe flag -->
var tixa_nadRowCount=1; <!--the row count of narrowad-->
var tixa_nadColumnCount=4; <!--the column count of narrowad-->
var tixa_nadHeight=85; <!--total height of narrowad-->
var tixa_nadWidth=700; <!--total width of narrowad-->
var tixa_nadBorderColor='DEB6BD'; <!--the color of the narrowad's border-->
var tixa_nadBgColor='FFF7F7';  <!--the color of the narrowad's background-->
var tixa_nadTitleColor='0000ff'; <!--the color of the ad's title-->
var tixa_nadDescColor='000000'; <!--the color of the ad's description-->
var tixa_adType='text'; <!--narrowad type-->
</SCRIPT>

<SCRIPT src="http://union.narrowad.com/proxy/narrowad.jsp?wid=767&amp;cid=4429"></SCRIPT>
</TD></TR></TBODY></TABLE></DIV><img src ="http://www.blogjava.net/TrampEagle/aggbug/31876.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-21 22:48 <a href="http://www.blogjava.net/TrampEagle/articles/31876.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE常用傻瓜問題1000問(之二)</title><link>http://www.blogjava.net/TrampEagle/articles/31875.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 21 Feb 2006 14:47:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31875.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31875.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31875.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31875.html</trackback:ping><description><![CDATA[引自：<A href="http://www.newebug.com/article/database/2165.shtml">http://www.newebug.com/article/database/2165.shtml</A><BR><BR>
<H2 align=center>ORACLE常用傻瓜問題1000問(之二)</H2>
<DIV align=center>
<P>(文档类别：<B><A title="数据库 技术文章" href="http://www.newebug.com/article/database/index.shtml">数据库</A></B>)　2004-7-15</P>
<TABLE width="95%" border=0>
<TBODY>
<TR>
<TD>46. 如何在字符串里加回车？ <BR><BR>　　select 'Welcome to visit'||chr(10)||'www.CSDN.NET' from dual ; <BR><BR><BR><BR>47. 中文是如何排序的？ <BR><BR>　　Oracle9i之前，中文是按照二进制编码进行排序的。 <BR><BR>　　在oracle9i中新增了按照拼音、部首、笔画排序功能。设置NLS_SORT值 <BR><BR>　　SCHINESE_RADICAL_M 按照部首（第一顺序）、笔划（第二顺序）排序 <BR><BR>　　SCHINESE_STROKE_M 按照笔划（第一顺序）、部首（第二顺序）排序 <BR><BR>　　SCHINESE_PINYIN_M 按照拼音排序 <BR><BR><BR><BR>48.　Oracle8i中对象名可以用中文吗？ <BR><BR>　　可以 <BR><BR><BR><BR>49. 如何改变WIN中SQL*Plus启动选项？ <BR><BR>SQL*PLUS自身的选项设置我们可以在$ORACLE_HOME/sqlplus/admin/glogin.sql中设置。 <BR><BR><BR><BR>50. 怎样修改oracel数据库的默认日期? <BR><BR>　 alter session set nls_date_format='yyyymmddhh24miss'; <BR>　 OR <BR><BR>　 可以在init.ora中加上一行 <BR>nls_date_format='yyyymmddhh24miss' <BR><BR><BR><BR>51. 如何将小表放入keep池中? <BR><BR>　 alter table xxx storage(buffer_pool keep); <BR><BR><BR><BR>52. 如何检查是否安装了某个patch? <BR><BR>　　check that　oraInventory <BR><BR><BR><BR>53. 如何使select语句使查询结果自动生成序号? <BR><BR>select rownum,COL from table; <BR><BR><BR><BR>54. 如何知道数据裤中某个表所在的tablespace? <BR><BR>select tablespace_name from user_tables where table_name='TEST'; <BR><BR>select * from user_tables中有个字段TABLESPACE_NAME，（oracle）; <BR><BR>select * from dba_segments where …; <BR><BR><BR><BR>55. 怎么可以快速做一个和原表一样的备份表? <BR><BR>　　create table new_table as (select * from old_table); <BR><BR><BR><BR>55. 怎么在sqlplus下修改procedure? <BR><BR>　select line,trim(text) t from user_source where name =’A’ order by line; <BR><BR><BR><BR>56. 怎样解除PROCEDURE被意外锁定? <BR><BR>　 alter system kill session ,把那个session给杀掉，不过你要先查出她的session id <BR><BR>　 or <BR><BR>　 把该过程重新改个名字就可以了。 <BR><BR><BR><BR>57. SQL Reference是个什么东西？ <BR><BR>　 是一本sql的使用手册，包括语法、函数等等，oracle官方网站的文档中心有下载. <BR><BR><BR><BR>58. 如何查看数据库的状态? <BR><BR>　 unix下 <BR>ps -ef | grep ora <BR>windows下 <BR>看服务是否起来 <BR>是否可以连上数据库 <BR><BR><BR><BR>59. 请问如何修改一张表的主键? <BR><BR>alter table aaa <BR>drop constraint aaa_key ; <BR>alter table aaa <BR>add constraint aaa_key primary key(a1,b1) ; <BR><BR><BR><BR>60. 改变数据文件的大小? <BR><BR>用 ALTER DATABASE .... DATAFILE .... ; <BR>手工改变数据文件的大小，对于原来的 数据文件有没有损害。 <BR><BR><BR><BR>61. 怎样查看ORACLE中有哪些程序在运行之中？ <BR><BR>　 查看v$sessions表 <BR><BR><BR><BR>62. 怎么可以看到数据库有多少个tablespace? <BR><BR>select　*　 from dba_tablespaces; <BR><BR><BR><BR>63. 如何修改oracle数据库的用户连接数？ <BR><BR>修改initSID.ora，将process加大，重启数据库. <BR><BR><BR><BR>64. 如何查出一条记录的最后更新时间? <BR><BR>　可以用logminer 察看 <BR><BR><BR><BR>65. 如何在PL/SQL中读写文件？ <BR><BR>UTL_FILE包允许用户通过PL/SQL读写操作系统文件。 <BR><BR><BR><BR>66. 怎樣把“&amp;”放入一條記錄中？ <BR><BR>insert into a values (translate ('at{&amp;}t','at{}','at')); <BR><BR><BR><BR>67. EXP　如何加ＱＵＥＲＹ参数？ <BR><BR>EXP USER/PASS FILE=A.DMP TABLES(BSEMPMS) <BR>QUERY='"WHERE EMP_NO=\'S09394\'\" ﹔ <BR><BR><BR><BR>68. 关于oracle8i支持简体和繁体的字符集问题？ <BR><BR>　 ZHS16GBK可以支 <BR><BR><BR><BR>69. Data Guard是什么软件？ <BR><BR>就是Standby的换代产品 <BR><BR><BR><BR>70. 如何創建SPFILE? <BR><BR>SQL&gt; connect / as sysdba <BR>SQL&gt; select * from v$version; <BR>SQL&gt; create pfile from spfile; <BR>SQL&gt; CREATE SPFILE FROM PFILE='E:\ora9i\admin\eygle\pfile\init.ora'; <BR><BR>文件已创建。 <BR>SQL&gt; CREATE SPFILE='E:\ora9i\database\SPFILEEYGLE.ORA' FROM PFILE='E:\ora9i\admin\eygle\pfile\init.ora'; <BR>文件已创建。 <BR><BR><BR><BR>71. 內核參數的應用? <BR><BR>shmmax <BR>　　含义：这个设置并不决定究竟Oracle数据库或者操作系统使用多少物理内存，只决定了最多可以使用的内存数目。这个设置也不影响操作系统的内核资源。 <BR>　　设置方法：0.5*物理内存 <BR>　　例子：Set shmsys:shminfo_shmmax=10485760 <BR>　　shmmin <BR>　　含义：共享内存的最小大小。 <BR>　　设置方法：一般都设置成为1。 <BR>　　例子：Set shmsys:shminfo_shmmin=1： <BR>　　shmmni <BR>　　含义：系统中共享内存段的最大个数。 <BR>　　例子：Set shmsys:shminfo_shmmni=100 <BR>　　shmseg <BR>　　含义：每个用户进程可以使用的最多的共享内存段的数目。 <BR>　　例子：Set shmsys:shminfo_shmseg=20： <BR>　　semmni <BR>　　含义：系统中semaphore identifierer的最大个数。 <BR>　　设置方法：把这个变量的值设置为这个系统上的所有Oracle的实例的init.ora中的最大的那个processes的那个值加10。 <BR>　　例子：Set semsys:seminfo_semmni=100 <BR>　　semmns <BR>　　含义：系统中emaphores的最大个数。 <BR>　　设置方法：这个值可以通过以下方式计算得到：各个Oracle实例的initSID.ora里边的processes的值的总和（除去最大的Processes参数）＋最大的那个Processes×2＋10×Oracle实例的个数。 <BR>　　例子：Set semsys:seminfo_semmns=200 <BR>　　semmsl: <BR>　　含义：一个set中semaphore的最大个数。 <BR>　　设置方法：设置成为10＋所有Oracle实例的InitSID.ora中最大的Processes的值。 <BR>　　例子：Set semsys:seminfo_semmsl=-200 <BR><BR>72. 怎样查看哪些用户拥有SYSDBA、SYSOPER权限？ <BR><BR>SQL&gt;conn sys/change_on_install <BR>SQL&gt;select * from V_$PWFILE_USERS; <BR><BR><BR>73. 如何单独备份一个或多个表？ <BR><BR>　 exp 用户/密码 tables=(表1,…,表2) <BR><BR><BR>74. 如何单独备份一个或多个用户？ <BR><BR>　exp system/manager owner=(用户1,用户2,…,用户n) file=导出文件 <BR><BR><BR>75. 如何对CLOB字段进行全文检索？ <BR><BR>SELECT * FROM A WHERE dbms_lob.instr(a.a,'K',1,1)&gt;0; <BR><BR><BR>76. 如何显示当前连接用户? <BR><BR>　 SHOW　USER <BR><BR><BR><BR>77. 如何查看数据文件放置的路径 ? <BR><BR>col file_name format a50 <BR>SQL&gt; select tablespace_name,file_id,bytes/1024/1024,file_name from dba_data_files order by file_id; <BR><BR><BR><BR>78. 如何查看现有回滚段及其状态 ? <BR><BR>SQL&gt; col segment format a30 <BR>SQL&gt; SELECT SEGMENT_NAME,OWNER,TABLESPACE_NAME,SEGMENT_ID,FILE_ID,STATUS FROM DBA_ROLLBACK_SEGS <BR><BR><BR><BR>79. 如何改变一个字段初始定义的Check范围？ <BR><BR>SQL&gt; alter table xxx drop constraint constraint_name; <BR>之后再创建新约束: <BR>SQL&gt; alter table xxx add constraint constraint_name check(); <BR><BR><BR><BR>80. Oracle常用系统文件有哪些？ <BR><BR>通过以下视图显示这些文件信息：v$database,v$datafile,v$logfile v$controlfile v$parameter; <BR><BR><BR><BR>81. 內連接INNER JOIN? <BR><BR>Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no; <BR><BR><BR><BR>82. 如何外連接? <BR><BR>　Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no(+); <BR><BR>　 Select a.* from bsempms a,bsdptms b wherea.dpt_no(+)=b.dpt_no; <BR><BR><BR><BR>83. 如何執行腳本SQL文件? <BR><BR>　SQL&gt;@$PATH/filename.sql; <BR><BR><BR><BR>84. 如何快速清空一個大表? <BR><BR>SQL&gt;truncate table table_name; <BR><BR><BR><BR>85. 如何查有多少個數据庫實例? <BR><BR>　SQL&gt;SELECT * FROM V$INSTANCE; <BR><BR><BR><BR>86. 如何查詢數据庫有多少表? <BR><BR>SQL&gt;select * from all_tables; <BR><BR><BR><BR>87. 如何測試SQL語句執行所用的時間? <BR><BR>SQL&gt;set timing on ; <BR><BR>　SQL&gt;select * from tablename; <BR><BR>
<SCRIPT>
var tixa_nadInIframe=false; <!-- iframe flag -->
var tixa_nadRowCount=1; <!--the row count of narrowad-->
var tixa_nadColumnCount=4; <!--the column count of narrowad-->
var tixa_nadHeight=85; <!--total height of narrowad-->
var tixa_nadWidth=700; <!--total width of narrowad-->
var tixa_nadBorderColor='DEB6BD'; <!--the color of the narrowad's border-->
var tixa_nadBgColor='FFF7F7';  <!--the color of the narrowad's background-->
var tixa_nadTitleColor='0000ff'; <!--the color of the ad's title-->
var tixa_nadDescColor='000000'; <!--the color of the ad's description-->
var tixa_adType='text'; <!--narrowad type-->
</SCRIPT>

<SCRIPT src="http://union.narrowad.com/proxy/narrowad.jsp?wid=767&amp;cid=4429"></SCRIPT>
</TD></TR></TBODY></TABLE></DIV><img src ="http://www.blogjava.net/TrampEagle/aggbug/31875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-21 22:47 <a href="http://www.blogjava.net/TrampEagle/articles/31875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE常用問題1000問（一）</title><link>http://www.blogjava.net/TrampEagle/articles/31874.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 21 Feb 2006 14:44:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31874.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31874.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31874.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31874.html</trackback:ping><description><![CDATA[引自：<A href="http://www.newebug.com/article/database/2164.shtml">http://www.newebug.com/article/database/2164.shtml</A><BR>chensheng913 [原作] <BR><BR>大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家, 希望對大家有幫助! 和大家一起探討, 共同進步! <BR><BR>　　　　對ORACLE高手來說是不用看的. <BR><BR><BR><BR>1. Oracle安裝完成后的初始口令? <BR><BR>　　internal/oracle <BR><BR>　　sys/change_on_install <BR><BR>　　system/manager <BR><BR>　　scott/tiger <BR><BR>　　sysman/oem_temp <BR><BR><BR><BR>2. ORACLE9IAS WEB CACHE的初始默认用户和密码？ <BR><BR>　 administrator/administrator <BR><BR><BR><BR>3. oracle 8.0.5怎么创建数据库? <BR><BR>　 用orainst。如果有motif界面，可以用orainst /m <BR><BR><BR><BR>4. oracle 8.1.7怎么创建数据库? <BR><BR>　 dbassist <BR><BR><BR><BR>5. oracle 9i 怎么创建数据库? <BR><BR>　 dbca <BR><BR><BR><BR>6. oracle中的裸设备指的是什么? <BR><BR>　裸设备就是绕过文件系统直接访问的储存空间 <BR><BR><BR><BR>7. oracle如何区分 64-bit/32bit 版本？？？ <BR><BR>$ sqlplus '/ AS SYSDBA' <BR>SQL*Plus: Release 9.0.1.0.0 - Production on Mon Jul 14 17:01:09 2003 <BR>(c) Copyright 2001 Oracle Corporation. All rights reserved. <BR>Connected to: <BR>Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production <BR>With the Partitioning option <BR>JServer Release 9.0.1.0.0 - Production <BR>SQL&gt; select * from v$version; <BR>BANNER <BR>---------------------------------------------------------------- <BR>Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production <BR>PL/SQL Release 9.0.1.0.0 - Production <BR>CORE 9.0.1.0.0 Production <BR>TNS for Solaris: Version 9.0.1.0.0 - Production <BR>NLSRTL Version 9.0.1.0.0 - Production <BR>SQL&gt; <BR><BR><BR><BR>8. SVRMGR什么意思？ <BR><BR>svrmgrl，Server Manager. <BR>9i下没有，已经改为用SQLPLUS了 <BR>sqlplus /nolog <BR>变为归档日志型的 <BR><BR><BR><BR>9. 请问如何分辨某个用户是从哪台机器登陆ORACLE的? <BR><BR>SELECT machine , terminal FROM V$SESSION; <BR><BR><BR><BR>10. 用什么语句查询字段呢？ <BR><BR>desc table_name 可以查询表的结构 <BR>select field_name,... from ... 可以查询字段的值 <BR><BR>select * from all_tables where table_name like '%' <BR>select * from all_tab_columns where table_name='??' <BR><BR><BR><BR>11. 怎样得到触发器、过程、函数的创建脚本？ <BR><BR>desc user_source <BR>user_triggers <BR><BR><BR><BR>12. 怎样计算一个表占用的空间的大小？ <BR><BR>select owner,table_name, <BR>NUM_ROWS, <BR>BLOCKS*AAA/1024/1024 "Size M", <BR>EMPTY_BLOCKS, <BR>LAST_ANALYZED <BR>from dba_tables <BR>where table_name='XXX'; <BR><BR>Here: AAA is the value of db_block_size ; <BR>XXX is the table name you want to check <BR><BR><BR><BR>13. 如何查看最大会话数？ <BR><BR>SELECT * FROM V$PARAMETER WHERE NAME LIKE 'proc%'; <BR><BR>SQL&gt; <BR>SQL&gt; show parameter processes <BR><BR>NAME TYPE value <BR>------------------------------------ ------- ------------------------------ <BR>aq_tm_processes integer 1 <BR>db_writer_processes integer 1 <BR>job_queue_processes integer 4 <BR>log_archive_max_processes integer 1 <BR>processes integer 200 <BR><BR>这里为200个用户。 <BR><BR>select * from v$license; <BR>其中sessions_highwater纪录曾经到达的最大会话数 <BR><BR><BR><BR>14. 如何查看系统被锁的事务时间？ <BR><BR>select * from v$locked_object ; <BR><BR><BR><BR>15. 如何以archivelog的方式运行oracle。 <BR><BR>init.ora <BR>log_archive_start = true <BR><BR>RESTART DATABASE <BR><BR><BR><BR>16. 怎么获取有哪些用户在使用数据库 <BR><BR>select username from v$session; <BR><BR><BR><BR>17. 数据表中的字段最大数是多少? <BR><BR>表或视图中的最大列数为 1000 <BR><BR><BR><BR>18. 怎样查得数据库的SID ? <BR><BR>select name from v$database; <BR>也可以直接查看 init.ora文件 <BR><BR><BR><BR>19. 如何在Oracle服务器上通过SQLPLUS查看本机IP地址 ? <BR><BR>select sys_context('userenv','ip_address') from dual; <BR><BR>如果是登陆本机数据库，只能返回127.0.0.1，呵呵 <BR><BR><BR><BR>20. unix 下怎么调整数据库的时间？ <BR><BR>su -root <BR>date -u 08010000 <BR><BR><BR><BR>21. 在ORACLE TABLE中如何抓取MEMO類型欄位為空的資料記錄? <BR><BR>select remark from oms_flowrec where trim(' ' from remark) is not null ; <BR><BR><BR><BR><BR>22. 如何用BBB表的資料去更新AAA表的資料(有關聯的字段) <BR><BR>UPDATE AAA SET BNS_SNM=(SELECT BNS_SNM FROM BBB WHERE AAA.DPT_NO=BBB.DPT_NO) WHERE BBB.DPT_NO IS NOT NULL; <BR><BR><BR><BR>23. P4電腦安裝方法 <BR><BR>　 將SYMCJIT.DLL改為SYSMCJIT.OLD <BR><BR><BR><BR>24. 何查詢SERVER是不是OPS? <BR><BR>　 SELECT *　FROM V$OPTION; <BR><BR>　 如果PARALLEL SERVER=TRUE則有OPS能 <BR><BR><BR><BR>25. 何查詢每個用戶的權限? <BR><BR>　　SELECT *　FROM DBA_SYS_PRIVS; <BR><BR><BR><BR>26. 如何將表移動表空間? <BR><BR>　ALTER TABLE TABLE_NAME MOVE TABLESPACE_NAME; <BR><BR><BR><BR>27. 如何將索引移動表空間? <BR><BR>　 ALTER INDEX INDEX_NAME REBUILD TABLESPACE TABLESPACE_NAME; <BR><BR><BR><BR>28. 在LINUX,UNIX下如何啟動DBA STUDIO? <BR><BR>　　OEMAPP　DBASTUDIO <BR><BR><BR><BR>29. 查詢鎖的狀況的對象有? <BR><BR>　　V$LOCK,　V$LOCKED_OBJECT,　V$SESSION,　V$SQLAREA,　V$PROCESS ; <BR><BR>　　查詢鎖的表的方法: <BR><BR>SELECT S.SID SESSION_ID, S.USERNAME, DECODE(LMODE, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(LMODE)) MODE_HELD, DECODE(REQUEST, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(REQUEST)) MODE_REQUESTED, O.OWNER||'.'||O.OBJECT_NAME||' ('||O.OBJECT_TYPE||')', S.TYPE LOCK_TYPE, L.ID1 LOCK_ID1, L.ID2 LOCK_ID2 FROM V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION S WHERE L.SID = S.SID AND L.ID1 = O.OBJECT_ID ; <BR><BR><BR><BR>30. 如何解鎖? <BR><BR>　　ALTER SYSTEM KILL SESSION　‘SID,SERIR#’; <BR><BR><BR><BR>31. SQLPLUS下如何修改編輯器? <BR><BR>DEFINE _EDITOR="&lt;编辑器的完整路经&gt;"　-- 必须加上双引号 <BR>来定义新的编辑器，也可以把这个写在$ORACLE_HOME/sqlplus/admin/glogin.sql里面使它永久有效。 <BR><BR><BR><BR>32. ORACLE產生隨機函數是? <BR><BR>　　DBMS_RANDOM.RANDOM <BR><BR><BR><BR>33. LINUX下查詢磁盤競爭狀況命令? <BR><BR>　　Sar　-d <BR><BR><BR><BR>33. LINUX下查詢CPU競爭狀況命令? <BR><BR>　　sar　 -r <BR><BR><BR><BR>34. 查詢當前用戶對象? <BR><BR>　　SELECT *　FROM USER_OBJECTS; <BR><BR>　　SELECT *　FROM DBA_SEGMENTS; <BR><BR><BR><BR>35. 如何獲取錯誤信息? <BR><BR>　 SELECT *　FROM　USER_ERRORS; <BR><BR><BR><BR>36. 如何獲取鏈接狀況? <BR><BR>　 SELECT * FROM DBA_DB_LINKS; <BR><BR><BR><BR>37. 查看數據庫字符狀況? <BR><BR>　　SELECT *　FROM NLS_DATABASE_PARAMETERS; <BR><BR>　　SELECT *　FROM V$NLS_PARAMETERS; <BR><BR><BR><BR>38. 查詢表空間信息? <BR><BR>　　SELECT *　FROM　DBA_DATA_FILES; <BR><BR><BR><BR>39. ORACLE的INTERAL用戶要口令? <BR><BR>　 修改 SQLNET.ORA <BR><BR>　 SQLNET.AUTHENTICATION_SERVICES=(NTS) <BR><BR><BR><BR>40. 出現JAVA.EXE的解決辦法? <BR><BR>　 一般是將ORACLEORAHOMEXIHTTPSERVER改成手工啟動可以的 <BR><BR>　 X是8或9 <BR><BR><BR><BR>41. 如何给表、列加注释？ <BR><BR>SQL&gt;comment on table 表 is '表注释'; <BR><BR>注释已创建。 <BR><BR>SQL&gt;comment on column 表.列 is '列注释'; <BR><BR>注释已创建。 <BR><BR>SQL&gt; select * from user_tab_comments where comments is not null; <BR><BR><BR><BR>42. 如何查看各个表空间占用磁盘情况？ <BR><BR>SQL&gt; col tablespace format a20 <BR>　　　SQL&gt; select <BR>　　　b.file_id　　　　　　　　　　　　　　　　　　　　　　　　　　　　　文件ID号, <BR>　　　b.tablespace_name　　　　　　　　　　　　　　　　　　　　　　　　　　 表空间名, <BR>　　　b.bytes　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 字节数, <BR>　　　(b.bytes-sum(nvl(a.bytes,0)))　　　　　　　　　　　　已使用, <BR>　　　sum(nvl(a.bytes,0))　　　　　　　　　　　　　　　　　　　　　　　　　　 剩余空间, <BR>　　　sum(nvl(a.bytes,0))/(b.bytes)*100　　　　　　　　　　 剩余百分比 <BR>　　　from dba_free_space a,dba_data_files b <BR>　　　where a.file_id=b.file_id <BR>　　　group by b.tablespace_name,b.file_id,b.bytes <BR>　　　order by b.file_id <BR><BR>43. 如把ORACLE设置为MTS或专用模式？ <BR><BR>#dispatchers="(PROTOCOL=TCP) (SERVICE=SIDXDB)" <BR>加上就是MTS，注释就是专用模式，SID是指你的实例名。 <BR><BR><BR><BR>44. 如何才能得知系统当前的SCN号 ? <BR><BR>select max(ktuxescnw * power(2, 32) + ktuxescnb) from x$ktuxe; <BR><BR><BR><BR>45. 请问如何在ORACLE中取毫秒? <BR><BR>9i之前不支持,9i开始有timestamp. <BR><BR>9i可以用select systimestamp from dual; <BR><img src ="http://www.blogjava.net/TrampEagle/aggbug/31874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-21 22:44 <a href="http://www.blogjava.net/TrampEagle/articles/31874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 JTA 处理 DB2 UDB 和 Informix Dynamic Server 中的分布式事务</title><link>http://www.blogjava.net/TrampEagle/articles/31648.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Mon, 20 Feb 2006 06:53:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/31648.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/31648.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/31648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/31648.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/31648.html</trackback:ping><description><![CDATA[下文引自：<A href="http://mywelt.net/?q=node/2046">http://mywelt.net/?q=node/2046</A><BR><BR>
<P>Uwe Weber<BR>Informix 和 DB2 UDB 的 IT 专家, IBM Germany</P>
<P><A name=IDATCYVB><SPAN class=atitle2>简介</SPAN></A><BR>在现代企业环境中，用多个数据库和多种品牌的数据库来存储公司数据已经不足为奇。最终，这些数据将会在不同数据库外进行比较、合并。</P>
<P>如果您有一个异构的数据库环境，并且计划将不同数据库中的数据收集到一个单独的应用程序中，那么您就应该可以使用传统技术执行该任务。在使用 <A class=glossary-term href="http://mywelt.net/?q=glossary#term166"><ACRONYM title="Java: Java is a reflective, object-oriented programming language developed initially by James Gosling and colleagues at Sun Microsystems. Initially called Oak (named after the oak trees outside Gosling's office), it was intended to replace C++, although the feature set better resembles that of Objective-C. Java should not be confused with JavaScript, which shares only the name and a similar C-like syntax. Sun Microsystems currently maintains and updates Java regularly.">Java</ACRONYM></A> 时，您将通过 <A class=glossary-term href="http://mywelt.net/?q=glossary#term171"><ACRONYM title="JDBC: Java Database Connectivity, or JDBC, is an API for the Java programming language that defines how a client may access a database.">JDBC</ACRONYM></A> 处理所有的数据库操作。清单 1 展示了在 Java 应用程序中如何连接 DB2 UDB 和 IDS 的代码片断。</P>
<P><A name=listing1><B>清单 1. 使用 JDBC 建立到不同数据库的连接</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="70%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
  1 try { // load JDBC drivers
  2     Class.forName (JDBC_DRIVER_DB2);
  3     Class.forName (JDBC_DRIVER_IDS);
  4 }
  5 catch (Exception e) {
  6     // error handling
  7 }
  8
  9 try { // establish connection and proceed with operation
 10     con_db2 = DriverManager.getConnection (DBURL_DB2);
 11     con_ids = Drivermanager.getConnection (DBURL_IDS);
 12
 13     Statement stmt_db2 = con_db2.createStatement ();
 14     Statement stmt_ids = con_ids.createStatement ();
 15
 16     ResultSet rs_db2 = stmt_db2.executeQuery (<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SQL</I>);
 17     ResultSet rs_ids = stmt_ids.executeQuery (<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SQL</I>);
 18
 19     // do something very important with the result sets...
 20 }
 21 catch (SQLException e) {
 22     // error handling
 23 }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><A name=IDANDYVB><SPAN class=atitle2>两阶段提交协议简介</SPAN></A><BR>清单 1 中的演示允许您修改不同数据库中的数据。代替执行查询，它可以使用 JDBC 方法 <CODE>executeUpdate()</CODE> 执行数据修改。 </P>
<P>但是如果您需要在<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">单个</B>事务中封装到 DB2 和 IDS 表的新一行的 <CODE>insert</CODE>，要做什么呢？<BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">意思就是说，如果其中一条 insert 语句失败了，就应该将数据库（这里：两种数据库！）的初始状态恢复为客户机未执行任何动作的状态。该行为可以通过使用<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">两阶段提交（Two-Phase-Commit）</B>协议完成。这一标准化协议描述了如何实现<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">分布式事务（XA）</I>或<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">分布式工作单元（Distributed Unit of Work，DUOW）</I>的技术，以达到跨数据库系统的一致状态（根据 ACID）。</P>
<P>常规事务（单阶段提交）中，由 <CODE>COMMIT</CODE> 或 <CODE>ROLLBACK</CODE> 所执行的事务终止是一种决定性的操作，与之相反，两阶段提交（Two-Phase-Commit）事务是分为两步（阶段）进行的。</P>
<P>首先，两阶段提交（Two-Phase-Commit）事务的启动与常规的单阶段提交（One-Phase-Commit）事务类似。接着，应用程序/客户机对该两阶段提交（Two-Phase-Commit）操作中所涉及的所有数据库执行其修改工作。现在，在最终提交该事务之前，客户机通知参与的数据库<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">准备</I>提交（第 1 阶段）。如果客户机从数据库收到一条“okay”，就发出命令向数据库提交该事务（第 2 阶段）。最后分布式事务（Distributed Transaction）结束。</P>
<P>两阶段提交（Two-Phase-Commit）中的第 1 阶段十分重要。通过首先询问数据库是否可以进行提交，一旦某一参与的数据库报告错误，就有机会立即中止整个事务。因而，第 2 阶段将由 <CODE>ROLLBACK</CODE>，而非 <CODE>COMMIT</CODE> 完成。</P>
<P>图 1 提供了对于两阶段提交（Two-Phase-Commit）协议如何工作的图形化印象。正如所演示的，分布式事务（Distributed Transaction）使用由元组表示的描述符（例如：[x,b1]）。其意思是，一个分布式事务（Distributed Transaction）包含两个元素。首先，有一个惟一<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">全局事务 ID（global transaction id）</I> —— 代表分布式事务（Distributed Transaction）的简单标识符 - 由 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">x</I> 表示，第二个是<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">分支 ID（branch id）</I>，它描述整个事务的一部分。一般，分支指的是一个数据库连接。如果您有一个将处理两个参与数据库的分布式事务（Distributed Transaction），您就可以用诸如 [100,1] 的描述符表示一个数据库，用诸如 [100,2] 的描述符表示另一数据库。因此本例中，就有一个编号为 100 的全局事务，其中包含两个 ID 分别为 1 和 2 的分支。</P>
<P>“但是”，您或许会问，“如果在两阶段提交（Two-Phase-Commit）协议的第 2 阶段中出现错误，又将发生什么事情呢？” <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">“的确，您将陷入麻烦中！” <BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">实际上，稍后我们将会讨论该主题。 </P>
<P><A name=figure1><B>图 1. 两阶段提交中的时间线和应用程序流</B></A><BR><IMG height=308 src="http://www.ibm.com/developerworks/db2/library/techarticle/dm-0505weber/tpc-flow.gif" width=475 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>请看 清单 2。在第 16-19 行代码中，您可能错觉地认为第 17 和 18 行的语句都是属于由 <CODE>con_db2.setAutoCommit(false)</CODE>（第 16 行）所定义的事务边界的一部分。而事实却是该行代码启动了一个显式事务，用于连接到由 <CODE>con_db2.commit()</CODE>（第 19 行）所提交的 DB2 数据库。第 18 行中所做的修改不受该事务的影响。本例<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">没有</B>使用两阶段提交（Two-Phase-Commit）协议，因此，它不是一个分布式事务（Distributed Transaction）。无论是到 DB2 数据库的连接，还是到 Informix Dynamic Server（IDS）的连接，它们都没有意识到彼此的存在。</P>
<P><A name=listing2><B>清单 2. 非“两阶段提交”的应用程序</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
  1 try {
  2     Class.forName (JDBC_DRIVER_DB2);
  3     Class.forName (JDBC_DRIVER_IDS);
  4 }
  5 catch (Exception e) {
  6     // error handling
  7 }
  8
  9 try {
 10     con_db2 = DriverManager.getConnection (DBURL_DB2);
 11     con_ids = Drivermanager.getConnection (DBURL_IDS);
 12
 13     Statement stmt_db2 = con_db2.createStatement ();
 14     Statement stmt_ids = con_ids.createStatement ();
 15   
 16     con_db2.setAutoCommit (false);
 17     stmt_db2.executeUpdate (<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SQL</I>);
 18     stmt_ids.executeUpdate (<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SQL</I>);
 19     con_db2.commit ();
 20   
 21     // further processing
 22 }
 23 catch (SQLException e) {
 24    // error handling
 25 }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><A name=IDA2GYVB><SPAN class=atitle2>JTA 和事务管理器（TM）</SPAN></A><BR><A class=glossary-term href="http://mywelt.net/?q=glossary#term233"><ACRONYM title="Java Transaction API: The Java Transaction API is one of the J2EE APIs allowing distributed transactions to be done across multiple XA resources.">Java Transaction API</ACRONYM></A> 允许您操作应用程序中的分布式事务（Distributed Transaction）。JTA 中有一组方法，它将传统的 JDBC 调用封装到了两阶段提交（Two-Phase-Commit）协议中。</P>
<P>在异构环境中，您通常会发现一个事务管理器（Transaction Manager），负责处理分布式事务。（实际上，事务管理器可以完成大量的工作负载平衡。）因此，不仅存在到数据库的直接连接，还有到事务管理器（Transaction Manager）的连接。这就是 JTA 发挥作用的地方：JTA 是 Java 应用程序和事务管理器（Transaction Manager）之间的接口。图 2 演示了一个包含分布式事务的典型环境。</P>
<P>由于存在事务管理器（Transaction Manager），它通常包含在应用程序服务器（Application Server）中，就不再有两层（Two-Tier）架构。传统的客户/服务器（Client/Server）架构已经由三层（Tree-Tier）架构所取代，三层架构包含<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">应用程序/客户机</I>、<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">事务管理器（Transaction Manager）/应用程序服务器（Application Server）</I>和<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">数据库服务器</I>，而数据库服务器一般称作 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">XA Resource</I>。</P>
<P><A name="figure 2"><B>图 2. 三层架构</B></A><BR><IMG height=324 src="http://www.ibm.com/developerworks/db2/library/techarticle/dm-0505weber/xa_overview.gif" width=437 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>
<OL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>包含 SQL 和 JTA 调用的 Java 应用程序。 
<LI>管理分布式事务的应用程序服务器（Application Server）。 
<LI>参与分布式事务的数据库。 
<LI>Java 应用程序向应用程序服务器（Application Server）提交常规 SQL 语句和通用的 XA 调用。 
<LI>应用程序所发送的消息由应用程序服务器（Application Server）进行处理，并使用 SQL 和数据库供应商特定的 XA 调用发送给数据库。</LI></OL>
<P>
<P>通常，应用程序服务器（Application Server）提供了应用程序可以使用的多种服务。在谈到分布式事务时，该服务就称作 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">XA Resource</I>。当然，在应用程序可以使用 XA Resource 之前，首先要在应用程序服务器中注册和配置 XA Resource。</P>
<P>现在，如果您计划在应用程序中使用 JTA，就必须修改代码，以便还可以与应用程序服务器（Application Server）进行通信。这包括一些附加的方法调用和指定的错误/异常处理。请参阅 清单 3，以了解如何工作。</P>
<P><A name=IDAUY3VB><SPAN class=atitle2>用 JTA 进行两阶段提交的必要条件</SPAN></A><BR>首先，在编写 JTA 应用程序时，您需要合适的 JDK。好消息就是在使用当前的 <A class=glossary-term href="http://mywelt.net/?q=glossary#term182"><ACRONYM title="JDK: The Java Development Kit (JDK) is a Sun product aimed at Java developers. Since the introduction of Java, it has been by far the most widely used Java SDK.">JDK</ACRONYM></A> 时，不需要任何附加包。大多数的 JTA 相关类都在 <CODE>javax.transaction</CODE> 和 <CODE>javax.transaction.xa</CODE> 中。</P>
<P>您需要用于 DB2 UDB 和 Informix Dynamic Server 的 JDBC 驱动程序。您将需要 Type 4 JDBC 用于 Informix Dynamic Server。DB2 要求您来选择需要哪个 JDBC 驱动程序。有 Type 2、3 和 4 JDBC。在用 JTA 进行编程时，您必须使用 Type 2 或 4 JDBC 驱动程序。为了方便，本文中所演示的所有例子都使用 Type 4 JDBC 驱动程序用于 DB2。（关于各驱动程序之间差别的解释，请查阅手册。）</P>
<P>以上描述说明了应用程序服务器（Application Server）或事务管理器（Transaction Manager）的存在。在下面的例子中，您不会看到“外部”应用程序服务器（Application Server），因为已经使用 DB2XADataSource 和 IfxXADataSource 类直接将之构建到您的应用程序中了。如果您使用一个真正的应用程序服务器（Application Server），那么该应用程序服务器将使用这些类来连接到数据库的本地 XA 调用。</P>
<P>下面的例子（清单 3）演示了一个小型应用程序，该应用程序使用 JTA 实现两阶段提交（Two-Phase-Commit）协议。该例子并不完整，是为了让代码更加易读。</P>
<P><A name=listing3><B>清单 3. 两阶段提交的应用程序</B></A></P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 19 import java.io.BufferedReader;
 20 import java.io.FileInputStream;
 21 import java.io.IOException;
 22 import java.io.InputStreamReader;
 23
 24 import java.sql.Connection;
 25 import java.sql.SQLException;
 26 import java.sql.Statement;
 27
 28 import java.util.Properties;
 29
 30 import javax.sql.XAConnection;
 31 import javax.transaction.xa.XAException;
 32 import javax.transaction.xa.XAResource;
 33 import javax.transaction.xa.Xid;
 34
 35 import com.ibm.db2.jcc.DB2XADataSource;
 36 import com.ibm.db2.jcc.DB2Xid;
 37
 38 import com.informix.jdbcx.IfxXADataSource;
 39 import com.informix.jdbcx.IfxXid;
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>在第 19-39 行中，您看到了该应用程序中所使用的所有类。大多数类是您所知道的。第 30-33 行中导入的类是使用 JTA 所必要的。同样有意思的是第 35、36 和 38、39 行中的数据库供应商的特定类。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">xyz</I>XADataSource 类包含了用于启用两阶段提交协议的本地 XA 代码。 </P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 44 class DBX {
 45
 46     private Properties props;
 47     private String propertyfile = "jtadb2ifmx.properties";
 48
 56     DBX () {
 57
 58         Connection      db2con = null;
 59         Connection      ifxcon = null;
 60         DB2XADataSource db2ds = null;
 61         IfxXADataSource ifxds = null;
 62         Xid             db2xid = null;
 63         Xid             ifxxid = null;
 64         XAConnection    db2xacon = null;
 65         XAConnection    ifxxacon = null;
 66         XAResource      db2xares = null;
 67         XAResource      ifxxares = null;
 68
 69
 70         // read the properties
 71         props = new Properties ();
 72
 73         try {
 74             props.load (new FileInputStream (propertyfile));
 75         }
 76         catch (IOException io) {
 77             System.err.println ("Error while accessing the properties file (" +
 78                                 propertyfile + "). Abort.");
 79             System.exit (1);
 80         }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">DBX</I> 类仅仅包含一个私有成员，用于负责属性文件。在该文件中，有一些数据库特定的设置，例如到引擎的端口或登录信息。</P>
<P>该类的构造函数实例化了 SQL 和 XA 相关类： </P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>Connection：</B> 表示到数据库的传统 SQL（JDBC）连接。 
<LI><B>DB2XADataSource</B> 和 <B>IfxXADataSource：</B> 这些类包含到数据库的本地 XA 调用。使用这些类来启用两阶段提交协议（Two-Phase-Commit-Protocol）。如果有一个应用程序服务器（Application Server），就不需要在程序中处理这些类，因为应用程序服务器（Application Server）封装乐应用程序的这部分。 
<LI><B>Xid：</B> 指一个 XA 事务。本例中，使用了两个不同的数据库，所以需要两个不同的 Xid —— 每个数据库连接（分支）一个。 
<LI><B>XAConnection：</B> JTA 中的一部分。该类允许您启动（提交、准备提交 ...）分布式事务（Distributed Transaction）。 
<LI><B>XAResource：</B> 该资源指的是应用程序服务器（Application Server）所提供的一个服务。同样，本例中，我们不使用应用程序服务器（Application Server）。因此，必须在该应用程序中进行创建和初始化。 </LI></UL>
<P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 83         db2ds = initDB2XADataSource ();
 84         ifxds = initIfxXADataSource ();
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>这些代码行调用一个方法来设置 XADataSource（参见下面）。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
360     IfxXADataSource initIfxXADataSource () {
361
362         System.out.print ("Create an IDS XA data source: ");
363         IfxXADataSource ds = new IfxXADataSource ();
364         ds.setDescription ("IDS XA data source");
365         ds.setServerName (props.getProperty ("ifx.connection.instancename"));
366         ds.setIfxIFXHOST (props.getProperty ("ifx.connection.host"));
367         ds.setPortNumber (Integer.parseInt
368             (props.getProperty ("ifx.connection.port")));
369         ds.setDatabaseName (props.getProperty ("ifx.connection.databasename"));
370
371         System.out.println ("Okay.");
372         return ds;
373     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>为了方便，这里同时演示了用于 XADataSource 的 IDS 和 DB2 设置，因为它们十分相似。 </P>
<P>在安装 IfxDataSource（第 363 行）之后，需要将多个设置指定到数据源对象。这些设置是从属性文件读取的。在设置传统的 JDBC 数据库连接时，所做的这些设置可以与数据库 URL 相比。请注意，没有将任何登录信息指定给数据源对象。登录信息仍然是数据库连接本身中的一部分。 </P>
<P>正如上面所提到的，如果存在应用程序服务器（Application Server），还可以由它来进行这一初始化。</P>
<P>在用正确的参数初始化 XADataSource 之后，就将 XADataSource 返回给方法调用者。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 85         db2xacon = initDB2XAConnection (db2ds);
 86         ifxxacon = initIfxXAConnection (ifxds);
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>在第 85 和 86 行的代码中，创建了到数据库的 XA Connection。下面描述了如何初始化这些 XA Connection。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
329     XAConnection initIfxXAConnection (IfxXADataSource ifxdatasource) {
330
331         XAConnection xacon = null;
332
333
334         try {
335             System.out.print ("Set up IDS XA connection: ");
336             xacon = ifxdatasource.getXAConnection (
337                 props.getProperty ("ifx.connection.username"),
338                 props.getProperty ("ifx.connection.password"));
339
340             System.out.println ("Okay.");
341         }
342         catch (SQLException e) {
343             sqlerr (e);
344         }
345
346         return xacon;
347     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>为了设置 XAConnection，要使用前面初始化的 DataSource 对象。第 336 行使用 XADataSource 创建了 XAConnection。为了完成 XAConnection，只需要将身份验证信息传递给该对象。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 87         db2xares = initXAResource (db2xacon);
 88         ifxxares = initXAResource (ifxxacon);
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>现在，您准备创建 XAResource 对象了。这些对象将允许您操作两阶段提交（Two-Phase-Commit）。 </P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
388     XAResource initXAResource (XAConnection xacon) {
389
390         XAResource xares = null;
391
392
393         try {
394             System.out.print ("Setting up a XA resource: ");
395             xares = xacon.getXAResource ();
396             System.out.println ("Okay.");
397         }
398         catch (SQLException e) {
399             sqlerr (e);
400         }
401
402         return xares;
403     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>XAResource 对象的安装没有什么特别的。该对象是通过调用 XAConnection 中的 <CODE>getXAResource()</CODE> 来创建的。</P>
<P>在完成所有关于 XA 的准备之后，就创建到数据库的 JDBC 连接。 </P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 89         db2con = getDatabaseConnection (db2xacon);
 90         ifxcon = getDatabaseConnection (ifxxacon);
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>在 <CODE>getDatabaseConnection()</CODE> 方法中，建立了一个 JDBC 数据库连接。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
250     Connection getDatabaseConnection (XAConnection xacon) {
251
252         Connection con = null;
253
254         try {
255             System.out.print ("Establish database connection: ");
256             con = xacon.getConnection ();
257             System.out.println ("Okay.");
258         }
259         catch (SQLException e) {
260             sqlerr (e);
261         }
262
263         return con;
264     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>这看上去有些混乱。既然已经在第 336 行中设置了 XAConnection，我们为何还需要 JDBC 连接呢？我们为何仍然需要一个“传统”连接的理由是所有其他 JDBC 操作和类（Statement、ResultSet ...）都基于或使用 <CODE>Connection</CODE> 对象。如果您看一看 JDBC 类的层次结构图，将会发现 <CODE>XAConnection</CODE> 并非是 <CODE>Connection</CODE>，反之亦然。<CODE>XAConnection</CODE>（实际上，它是 <CODE>ConnectionPool</CODE> 的子类）使用 <CODE>Connection</CODE>（层次化）。 </P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 93         db2xid = createDB2XID ();
 94         ifxxid = createIfxXID ();
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>启动 XA 事务之前的最后一步就是为数据库创建 XA ID 对象。在分布式事务（Distributed Transaction）中进行操作时，总是要使用这个 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">xid</I>。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
183     Xid createIfxXID () {
184
185         Xid xid = null;
186
187         byte [] gid = new byte[1];
188         byte [] bid = new byte[1];
189
190         gid[0] =
191             (Byte.decode (props.getProperty ("xid.global"))).byteValue ();
192         bid[0] =
193             (Byte.decode (props.getProperty ("xid.branch.ifx"))).byteValue ();
194
195         System.out.print ("Creating an XID (" + Byte.toString (gid[0]) + ", " +
196                           Byte.toString (bid[0]) + ") for Informix: ");
197
198         xid = new IfxXid (0, gid, bid);
199         System.out.println ("Okay.");
200         return xid;
201     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>createIfxXID 方法创建一个 XID（这里：用于 IDS 连接）。正如“两阶段提交协议简介”小节中提到的，XA 事务包含定义该事务的两个元素。上面例子中的重要部分在第 198 行中。IDS XID 是同三个参数创建的。第一个参数是 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">format ID</I>，它描述在什么格式中构建分布式事务（Distributed Transaction）。您可以省略这一格式信息。第二个参数定义了<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">全局事务 ID（global transaction ID）</I>。该 ID 对于所有参与数据库来说是惟一的。第三个参数表示该全局事务中的事务分支。 </P>
<P>在（为 DB2 和 IDS）构建 XID 之后，我们可以使用它们来修改单个事务中的数据。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
 98         execBranch (db2con, db2xares, db2xid);
 99         execBranch (ifxcon, ifxxares, ifxxid);
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><CODE>execBranch()</CODE> 方法包含了上面为每个连接所定义的 XA 事务中的修改。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
215     void execBranch (Connection con, XAResource xares, Xid xid) {
216
217         String sql = props.getProperty ("sql.statement");
218
219         try {
220             xares.start (xid, javax.transaction.xa.XAResource.TMNOFLAGS);
221
222                 Statement stmt = con.createStatement ();
223                 stmt.executeUpdate (sql);
224
225             xares.end (xid, javax.transaction.xa.XAResource.TMSUCCESS);
226         }
227         catch (XAException e) {
228             System.err.println ("XA exception caught:");
229             System.err.println ("Cause  : " + e.getCause ());
230             System.err.println ("Message: " + e.getMessage ());
231             e.printStackTrace ();
232         }
233         catch (SQLException e) {
234             sqlerr (e);
235         }
236     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>第 219-226 行代码包含了分布式事务（Distributed Transaction）中为相应分支所使用的真正 SQL 语句。分支边界在第 220 行中以 <CODE>start</CODE> 方法开始。传递给该方法的参数就是我们已经知道的事务 ID，而第二个参数包含了用于该 XA 事务的一些附加信息。因为这是第一个两阶段提交（Two-Phase-Commit）协议操作，所以不需要向该方法传递任何特殊信息。<CODE>TMNOFLAGS</CODE> 说明了这一事实。分支边界终止于第 225 行。标志 <CODE>TMSUCCESS</CODE> 描述所有操作都成功。</P>
<P>在 IDS 和 DB2 的分支都执行之后，全局事务就准备提交这些修改。当然，在可以向数据库传送最后的提交之前，必须询问数据库是否准备进行提交。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
104         if (prepareCommit (db2xares, db2xid) == XAResource.XA_OK &amp;&amp;
105             prepareCommit (ifxxares, ifxxid) == XAResource.XA_OK) {
106             // both branches are ready to commit
107             commitBranch (db2xares, db2xid);
108             commitBranch (ifxxares, ifxxid);
109         }
110         else {
111             // a resource reported an error
112             rollbackBranch (db2xares, db2xid);
113             rollbackBranch (ifxxares, ifxxid);
114         }
116     } // end of constructor
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>第 104 和 105 行通知数据库<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">准备提交</I>。如果数据库报告 <CODE>XAResource.XA_OK</CODE>，就可以提交整个事务。否则，该事务就将被 <CODE>ROLLBACK</CODE> 中止。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
417     int prepareCommit (XAResource xares, Xid xid) {
418
419         int rc = 0;
420
421         System.out.print ("Prepare XA branch (" +
422             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
423             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
424
425         try {
426             xares.prepare (xid);
427         }
428         catch (XAException e) {
429             xaerr (e);
430         }
431
432         System.out.println ("Okay.");
433         return rc;
434     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><CODE>prepareCommit()</CODE> 方法中最重要的一行在第 426 行中。<CODE>prepare</CODE> 方法引起数据库调用两阶段提交协议（Two-Phase-Commit）的“第 1 阶段”。</P>
<P>根据“第 1 阶段”的结果，将提交或中止该分布式事务（Distributed Transaction）。下面是将用于发出这些必要操作的两个方法。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
128     void commitBranch (XAResource xares, Xid xid) {
129
130         System.out.print ("Commit XA branch (" +
131             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
132             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
133
134         try {
135             // second parameter is 'false' since we have a two phase commit
136             xares.commit (xid, false);
137         }
138         catch (XAException e) {
139             xaerr (e);
140         }
141
142         System.out.println ("Okay.");
143     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P>如果“第 1 阶段”未报告任何错误，就在第 136 行中为 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">xid</I> 所描述的事务分支提交“第 2 阶段”。方法 <CODE>commit()</CODE> 中的第二个参数区分单阶段或两阶段提交操作。因为我们具有一个两阶段提交操作，所以必须将该值设置为 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">false</I>。</P>
<P>下面的例子展示了如何为数据库回滚事务分支。</P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc border=1>
<TBODY>
<TR>
<TD><PRE><CODE>
446     void rollbackBranch (XAResource xares, Xid xid) {
447
448         System.out.print ("Rollback XA branch (" +
449             Byte.toString ((xid.getGlobalTransactionId ())[0]) + ", " +
450             Byte.toString ((xid.getBranchQualifier ())[0]) + "): ");
451
452         try {
453             xares.rollback (xid);
454         }
455         catch (XAException e) {
456             xaerr (e);
457         }
458
459         System.out.println ("Okay.");
460     }
</CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><A name=IDA453VB><SPAN class=atitle2>问题解答</SPAN></A><BR>本文中的例子演示了如何在 Java 中使用 JTA 实现两阶段提交（Two-Phase-Commit）协议。在该应用程序中，如果一个事务分支报告了错误，您就要负责进行错误处理。但是“两阶段提交协议简介”小节中提到仍然存在一个问题，那就是如果第 2 阶段中一个事务分支发生故障，该怎么办呢？</P>
<P>如果再次查看程序代码，您可以看到在“第 1 阶段”和“第 2 阶段”之间有一个很小的时间间隔。在这一时间间隔中，出于某种理由，其中某一参与数据库可能崩溃。如果发生了，我们将陷入分布式事务已经部分提交的情形中。</P>
<P>假定下列情形：在“第 1 阶段”之后，您从 DB2 和 IDS 数据库中都收到了“okay”。在下一步中，应用程序成功提交了 DB2 的事务分支。接着，应用程序通知 DB2 事务分支提交事务。现在，在应用程序可以通知 IDS 事务分支提交它这一部分之前，IDS 引擎由于断电发生崩溃。这就是一种部分提交全局事务的情形。您现在该怎么办呢？</P>
<P>在重启之后，DB2 和 IDS 都将尝试恢复打开的事务分支。该引擎等待来自应用程序的提示如何做。如果应用程序没有准备重新发送“第 2 阶段”的提交，该事务分支将被引擎所启动的试探性回滚中止。这是非常糟糕的，因为这将使该全局事务处于不一致状态。</P>
<P>一种解决方案是用一个小型应用程序连接引擎中打开的事务分支，并通知引擎提交或回滚这一打开的事务。如果您使用 IDS 作为后端，那么还有一个隐藏的 onmode 标志，允许您结束打开的事务分支。（onmode -Z <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">xid</I>）。</P>
<P>在 DB2 UDB 中，您可以发出 <CODE>LIST INDOUBT TRANSACTIONS</CODE> 来获得打开的 XA 事务的有关信息。您必须查看&nbsp;DB2 Information Center 中的描述来解决该问题。</P>
<P>上面描述的情形是一个很好的例子，也是使用应用程序服务器（Application Server）或事务监控器（Transaction Monitor）的理由。在使用一个中间层服务器时，就由该服务器负责保持事情正常。</P>
<P><A name=IDA0A4VB><SPAN class=atitle2>备选方案</SPAN></A><BR>清单 1&nbsp; &nbsp;演示了在应用程序中从数据库读取数据并处理结果的可行方法。如果您的应用程序是“只读”应用程序，IBM® 就提供了另一种解决方案，称作 WebSphere® Information Integrator。WebSphere Information Integrator 使用来自 DB2 UDB（或 DB2 Data Joiner、DB2 Relational Connect）的联邦数据库技术，以将多个数据库（通常：数据源）虚拟化（virtualize）到一个数据库中。不同的、非本地的数据库中的表都链接到 DB2 UDB 中。该操作对于客户机应用程序是完全透明的。客户机可以访问其他数据库中的所有远程表，就像它们是本地 DB2 UDB 表一样。正如 清单 1 &nbsp;中引用的，不再需要连接两个数据库。到 DB2 UDB 的单个连接就已经足够了，因为 DB2 中可以看到 IDS 数据库中的所有表。</P>
<P>目前，WebSphere Information Integrator 不支持两阶段提交，然而，将来的版本将支持两阶段提交协议；这将带来实现企业应用程序的新方法。</P>
<P><A name=resources><SPAN class=atitle2>参考资料 </SPAN></A></P>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www-128.ibm.com/developerworks/db2/library/techarticle/dm-0505weber/index.html" target=_blank xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">英文原文</A>。<BR>
<LI><A href="http://publib.boulder.ibm.com/infocenter/db2help/index.jsp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IBM DB2 Information Center</A><BR>
<LI><A href="http://publib.boulder.ibm.com/infocenter/ids9help/index.jsp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IBM Informix Information Center</A><BR>
<LI><A href="http://java.sun.com/products/jta/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Java Transaction API</A><BR>
<LI><A href="http://www-306.ibm.com/software/data/informix/pubs/library/dsdk_9.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IBM Informix JDBC Programmers Guide</A><BR>
<LI><A href="ftp://ftp.software.ibm.com/ps/products/db2/info/vr82/pdf/en_US/db2a1e81.pdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">IBM DB2 Application Developers Guide Pt. II</A></LI></UL>
<P>
<P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><SPAN class=atitle2><STRONG>关于作者</STRONG></SPAN><BR>Uwe Weber 是一位 Informix 和 DB2 UDB 方面的 IT 专家。他居住在德国的慕尼黑。Uwe 的 IT 经历始于 1997 年，从那时起，他作为一名 Informix 产品讲师开始在 Informix 工作。IBM 于 2001 年收购 Informix 之后，他调去了技术预售部门，与 EMEA Central 的客户一起工作。</TD></TR></TBODY></TABLE></P><img src ="http://www.blogjava.net/TrampEagle/aggbug/31648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-20 14:53 <a href="http://www.blogjava.net/TrampEagle/articles/31648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQLServer和Oracle的常用函数对比</title><link>http://www.blogjava.net/TrampEagle/articles/30645.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 14 Feb 2006 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30645.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30645.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30645.html</trackback:ping><description><![CDATA[原文引自：<a href="http://searchdatabase.techtarget.com.cn/askexperts/58/2110558.shtml?ticket=ST-1748-0uUkyzEFE0RfOYVueR2j">http://searchdatabase.techtarget.com.cn/askexperts/58/2110558.shtml?ticket=ST-1748-0uUkyzEFE0RfOYVueR2j</a><br /><br /><strong>数学函数</strong><p>　　1.绝对值</p><p>　　S:select abs(-1) value</p><p>　　O:select abs(-1) value from dual</p><p>　　2.取整(大)</p><p>　　S:select ceiling(-1.001) value</p><p>　　O:select ceil(-1.001) value from dual</p><p>　　3.取整(小)</p><p>　　S:select floor(-1.001) value</p><p>　　O:select floor(-1.001) value from dual</p><p>　　4.取整(截取)</p><p>　　S:select cast(-1.002 as int) value</p><p>　　O:select trunc(-1.002) value from dual</p><p>　　5.四舍五入</p><p>　　S:select round(1.23456,4) value 1.23460</p><p>　　O:select round(1.23456,4) value from dual 1.2346</p><p>　　6.e为底的幂</p><p>　　S:select Exp(1) value 2.7182818284590451</p><p>　　O:select Exp(1) value from dual 2.71828182</p><p>　　7.取e为底的对数</p><p>　　S:select log(2.7182818284590451) value 1</p><p>　　O:select ln(2.7182818284590451) value from dual; 1</p><p>　　8.取10为底对数</p><p>　　S:select log10(10) value 1</p><p>　　O:select log(10,10) value from dual; 1</p><p>　　9.取平方</p><p>　　S:select SQUARE(4) value 16</p><p>　　O:select power(4,2) value from dual 16</p><p>　　10.取平方根</p><p>　　S:select SQRT(4) value 2</p><p>　　O:select SQRT(4) value from dual 2</p><p>　　11.求任意数为底的幂</p><p>　　S:select power(3,4) value 81</p><p>　　O:select power(3,4) value from dual 81</p><p>　　12.取随机数</p><p>　　S:select rand() value</p><p>　　O:select sys.dbms_random.value(0,1) value from dual;</p><p>　　13.取符号</p><p>　　S:select sign(-8) value -1</p><p>　　O:select sign(-8) value from dual -1</p><p>　　14.圆周率</p><p>　　S:SELECT PI() value 3.1415926535897931</p><p>　　O:不知道</p><p>　　15.sin,cos,tan 参数都以弧度为单位</p><p>　　例如:select sin(PI()/2) value 得到1(<a class="bluekey" href="http://www.yesky.com/key/4128/19128.html" target="_blank">SQLServer</a>)</p><p>　　16.Asin,Acos,Atan,Atan2 返回弧度</p><p>　　17.弧度角度互换(SQLServer，Oracle不知道)</p><p>　　DEGREES:弧度-〉角度</p><p>　　RADIANS:角度-〉弧度</p><p>　　<strong>数值间比较</strong></p><p>　　18. 求集合最大值</p><p>　　S:select max(value) value from</p><p>　　(select 1 value</p><p>　　union</p><p>　　select -2 value</p><p>　　union</p><p>　　select 4 value</p><p>　　union</p><p>　　select 3 value)a</p><p>　　O:select <a class="bluekey" href="http://www.yesky.com/key/445/20445.html" target="_blank">greatest</a>(1,-2,4,3) value from dual</p><p>　　19. 求集合最小值</p><p>　　S:select min(value) value from</p><p>　　(select 1 value</p><p>　　union</p><p>　　select -2 value</p><p>　　union</p><p>　　select 4 value</p><p>　　union</p><p>　　select 3 value)a</p><p>　　O:select least(1,-2,4,3) value from dual</p><p>　　20.如何处理null值(F2中的null以10代替)</p><p>　　S:select F1,IsNull(F2,10) value from Tbl</p><p>　　O:select F1,nvl(F2,10) value from Tbl</p><p>　　21.求字符序号</p><p>　　S:select ascii('a') value</p><p>　　O:select ascii('a') value from dual</p><p>　　22.从序号求字符</p><p>　　S:select char(97) value</p><p>　　O:select chr(97) value from dual</p><p>　　23.连接</p><p>　　S:select '11'+'22'+'33' value</p><p>　　O:select CONCAT('11','22')||33 value from dual</p><p>　　23.子串位置 --返回3</p><p>　　S:select CHARINDEX('s','sdsq',2) value</p><p>　　O:select INSTR('sdsq','s',2) value from dual</p><p>　　23.模糊子串的位置 --返回2,参数去掉中间%则返回7</p><p>　　S:select patindex('%d%q%','sdsfasdqe') value</p><p>　　O:oracle没发现，但是instr可以通过第四个参数控制出现次数</p><p>　　select INSTR('sdsfasdqe','sd',1,2) value from dual 返回6</p><p>　　24.求子串</p><p>　　S:select substring('abcd',2,2) value</p><p>　　O:select substr('abcd',2,2) value from dual</p><p>　　25.子串代替 返回aijklmnef</p><p>　　S:SELECT STUFF('abcdef', 2, 3, 'ijklmn') value</p><p>　　O:SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual</p><p>　　26.子串全部替换</p><p>　　S:没发现</p><p>　　O:select Translate('fasdbfasegas','fa','我' ) value from dual</p><p>　　27.长度</p><p>　　S:len,datalength</p><p>　　O:length</p><p>　　28.大小写转换 lower,upper</p><p>　　29.单词首字母大写</p><p>　　S:没发现</p><p>　　O:select INITCAP('abcd dsaf df') value from dual</p><p>　　30.左补空格(LPAD的第一个参数为空格则同space函数)</p><p>　　S:select space(10)+'abcd' value</p><p>　　O:select LPAD('abcd',14) value from dual</p><p>　　31.右补空格(RPAD的第一个参数为空格则同space函数)</p><p>　　S:select 'abcd'+space(10) value</p><p>　　O:select RPAD('abcd',14) value from dual</p><p>　　32.删除空格</p><p>　　S:ltrim,rtrim</p><p>　　O:ltrim,rtrim,trim</p><p>　　33. 重复<a class="bluekey" href="http://www.yesky.com/key/4578/14578.html" target="_blank">字符串</a></p><p>　　S:select REPLICATE('abcd',2) value</p><p>　　O:没发现</p><p>　　34.发音相似性比较(这两个单词返回值一样，发音相同)</p><p>　　S:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')</p><p>　　O:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') from dual</p><p>　　SQLServer中用SELECT DIFFERENCE('Smithers', 'Smythers') 比较soundex的差</p><p>　　返回0-4，4为同音，1最高</p><p>　　<strong>日期函数</strong></p><p>　　35.系统时间</p><p>　　S:select getdate() value</p><p>　　O:select sysdate value from dual</p><p>　　36.前后几日</p><p>　　直接与整数相加减</p><p>　　37.求日期</p><p>　　S:select convert(char(10),getdate(),20) value</p><p>　　O:select trunc(sysdate) value from dual</p><p>　　select to_char(sysdate,'yyyy-mm-dd') value from dual</p><p>　　38.求时间</p><p>　　S:select convert(char(8),getdate(),108) value</p><p>　　O:select to_char(sysdate,'hh24:mm:ss') value from dual</p><p>　　39.取日期时间的其他部分</p><p>　　S:DATEPART 和 DATENAME 函数 (第一个参数决定)</p><p>　　O:to_char函数 第二个参数决定</p><p>　　参数---------------------------------下表需要补充</p><p>　　year yy, yyyy</p><p>　　quarter qq, q (季度)</p><p>　　month mm, m (m O无效)</p><p>　　dayofyear dy, y (O表星期)</p><p>　　day dd, d (d O无效)</p><p>　　week wk, ww (wk O无效)</p><p>　　weekday dw (O不清楚)</p><p>　　Hour hh,hh12,hh24 (hh12,hh24 S无效)</p><p>　　minute mi, n (n O无效)</p><p>　　<a class="bluekey" href="http://www.yesky.com/key/4225/19225.html" target="_blank">second</a> ss, s (s O无效)</p><p>　　millisecond ms (O无效)</p><p>　　----------------------------------------------</p><p>　　40.当月最后一天</p><p>　　S:不知道</p><p>　　O:select LAST_DAY(sysdate) value from dual</p><p>　　41.本星期的某一天(比如星期日)</p><p>　　S:不知道</p><p>　　O:SELECT Next_day(sysdate,7) vaule FROM DUAL;</p><p>　　42.字符串转时间</p><p>　　S:可以直接转或者select cast('2004-09-08'as datetime) value</p><p>　　O:SELECT To_<a class="bluekey" href="http://www.yesky.com/key/4126/14126.html" target="_blank">date</a>('2004-01-05 22:09:38','yyyy-mm-dd hh24-mi-ss') vaule FROM DUAL;</p><p>　　43.求两日期某一部分的差(比如秒)</p><p>　　S:select datediff(ss,getdate(),getdate()+12.3) value</p><p>　　O:直接用两个日期相减(比如d1-d2=12.3)</p><p>　　SELECT (d1-d2)*24*60*60 vaule FROM DUAL;</p><p>　　44.根据差值求新的日期(比如分钟)</p><p>　　S:select dateadd(mi,8,getdate()) value</p><p>　　O:SELECT sysdate+8/60/24 vaule FROM DUAL;</p><p>　　45.求不同时区时间</p><p>　　S:不知道</p><p>　　O:SELECT New_time(sysdate,'ydt','gmt' ) vaule FROM DUAL;</p><p>　　-----时区参数,北京在东8区应该是Ydt-------</p><p>　　AST ADT 大西洋标准时间</p><p>　　BST BDT 白令海标准时间</p><p>　　CST CDT 中部标准时间</p><p>　　EST EDT 东部标准时间</p><p>　　GMT 格林尼治标准时间</p><p>　　HST HDT 阿拉斯加?夏威夷标准时间</p><p>　　MST MDT 山区标准时间</p><p>　　NST 纽芬兰标准时间</p><p>　　PST PDT 太平洋标准时间</p><p>　　YST YDT YUKON标准时间</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/30645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-14 17:33 <a href="http://www.blogjava.net/TrampEagle/articles/30645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle安全全接触（完整版）</title><link>http://www.blogjava.net/TrampEagle/articles/30644.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 14 Feb 2006 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30644.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30644.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30644.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30644.html</trackback:ping><description><![CDATA[原文引自：<a href="http://searchdatabase.techtarget.com.cn/tips/421/2142421.shtml">http://searchdatabase.techtarget.com.cn/tips/421/2142421.shtml</a><br /><br />随着计算机的普及以及网络的发展，数据库已经不再仅仅是那些程序员所专有的话题。而Oracle数据库更是凭借其性能卓越，操作方便灵活的特点，在数据库的市场中已经占据了一席之地。但是同样随着网络技术的不断进步，数据信息的不断增加，数据安全已经不再是以前的“老生长谈”，也更不是以前书本上那些“可望不可及”的条条框框。 
<p>　　或许很久以前，大家都觉得Oracle数据库的安全并不存在隐患，因为Oracle公司在去年11月份开始促销其数据库软件时提出的口号是“只有Oracle9i能够做到绝对安全”。但是不管它这么说是为了促销，还是为了扩大知名度，总之伴去年12 月份，英国的安全专家 David Litchfield 发现的9iAS 中存在的程序错误导致的缓冲溢出漏洞以及后来，PenTest Limited 和 eEye Digital Security 各自提出了一个小的漏洞，所有使用Oracle公司产品的人都不由地紧张了原本松弛的大脑--这个对于用户来说，毕竟关系到了自己的“身家性命”。</p><p>　　下面笔者将带着大家走进Oracle数据安全的世界。由于笔者水平有限，所以不足之处在所难免，望大家不吝赐教。</p><p>　　(一)Oracle数据库的一些基本常识</p><p>　　这里仅仅是为了以后的安全奠定一些基础，因为我们后面要用到它们。</p><p>　　1.Oracle所包含的组件:</p><p>　　在 Oracle，数据库是指整个 Oracle RDBMS 环境，它包括以下组件:</p><p>　　·Oracle 数据库进程和缓冲(实例)。</p><p>　　·SYSTEM 表空间包含一个集中系统类目，它可以由一个或多个数据文件构成。</p><p>　　·其它由数据库管理员 (DBA)(可选)定义的表空间，每个都由一个或多个数据文件构成。</p><p>　　·两个以上的联机恢复日志。</p><p>　　·归档恢复日志(可选)。</p><p>　　·其它文件(控制文件、Init.ora、Config.ora 等)。</p><p>　　每个 Oracle 数据库都在一个中央系统类目和数据字典上运行，它位于SYSTEM 表空间。</p><p>　　2.关于“日志”</p><p>　　Oracle数据库使用几种结构来保护数据:数据库后备、日志、回滚段和控制文件。下面我们将大体上了解一下作为主要结构之一的“日志”:</p><p>　　每一个Oracle数据库实例都提供日志，记录数据库中所作的全部修改。每一个运行的Oracle数据库实例相应地有一个在线日志，它与Oracle后台进程LGWR一起工作，立即记录该实例所作的全部修改。归档(离线)日志是可选择的，一个Oracle数据库实例一旦在线日志填满后，可形成在线日志归档文件。归档的在线日志文件被唯一标识并合并成归档日志。</p><p>　　·关于在线日志:一个Oracle数据库的每一实例有一个相关联的在线日志。一个在线日志由多个在线日志文件组成。在线日志文件(online redo log file)填入日志项(redo entry)，日志项记录的数据用于重构对数据库所作的全部修改。</p><p>　　·关于归档日志:Oracle要将填满的在线日志文件组归档时，则要建立归档日志(archived redo log)。其对数据库备份和恢复有下列用处:</p><p>　　&lt;1&gt;数据库后备以及在线和归档日志文件，在操作系统和磁盘故障中可保证全部提交的事物可被恢复。</p><p>　　&lt;2&gt;在数据库打开和正常系统使用下，如果归档日志是永久保存，在线后备可以进行和使用。</p><p>　　数据库可运行在两种不同方式下:NOARCHIVELOG方式或ARCHIVELOG 方式。数据库在NOARCHIVELOG方式下使用时，不能进行在线日志的归档。如果数据库在ARCHIVELOG方式下运行，可实施在线日志的归档。</p><p>　　3.物理和逻辑存储结构:</p><p>　　Oracle RDBMS是由表空间组成的，而表空间又是由数据文件组成的。表空间数据文件被格式化为内部的块单位。块的大小，是由DBA在Oracle第一次创建的时候设置的，可以在512到8192个字节的范围内变动。当一个对象在Oracle表空间中创建的时候，用户用叫做长度的单位(初始长度((initial extent)、下一个长度(next extent)、最小长度(min extents)、以及最大长度(max extents))来标明该对象的空间大小。一个Oracle长度的大小可以变化，但是要包含一个由至少五个连续的块构成的链。</p><p>　　4.Oracle与Microsoft SQL Server比较下的联网协议:</p><p>　　(二)Oracle数据安全的维护</p><p>　　记得某位哲学家说过:“事物的变化离不开内因和外因。”那么对于Oracle数据安全这个话题而言，也势必分为“内”和“外”两个部分。那么好，我们就先从“内”开始说起:</p><p>　　§1.从Oracle系统本身说起</p><p>　　我们先抛开令人闻风色变的“hacker”和其他一些外部的原因，先想一下我们的数据库。什么硬盘<a class="bluekey" href="http://www.yesky.com/key/2963/167963.html" target="_blank">损坏</a>，什么软件受损，什么操作事物……一系列由于我们的“疏忽”而造成的系统问题就完全可以让我们辛苦建立的数据库中的数据一去不复返。那么，我们就先从自己身上找找原因吧。</p><p>　　【一】解决系统本身问题的方法--数据库的备份及恢复</p><p>　　·数据库的备份:</p><p>　　关于Oracle数据库的备份，标准地有三中办法:导出/导入(Export/Import)、冷备份、热备份。导出备份是一种逻辑备份，冷备份和热备份是物理备份。</p><p>　　&lt;1&gt;导出/导入(Export/Import)</p><p>　　利用Export可将数据从数据库中提取出来，利用Import则可将提取出来的数据送回Oracle数据库中去。</p><p>　　a.简单导出数据(Export)和导入数据(Import)</p><p>　　Oracle支持三种类型的输出:</p><p>　　(1)表方式(T方式)，将指定表的数据导出。</p><p>　　(2)用户方式(U方式)，将指定用户的所有对象及数据导出。</p><p>　　(3)全库方式(Full方式)，将数据库中的所有对象导出。</p><p>　　数据导出(Import)的过程是数据导入(Export)的逆过程，它们的数据流向不同。</p><p>　　b.增量导出/导入</p><p>　　增量导出是一种常用的数据备份方法，它只能对整个数据库来实施，并且必须作为SYSTEM来导出。在进行此种导出时，系统不要求回答任何问题。导出文件名缺省为export.dmp，如果不希望自己的输出文件定名为export.dmp，必须在命令行中指出要用的文件名。</p><p>　　增量导出包括三个类型:</p><p>　　(1)“完全”增量导出(Complete)</p><p>　　即备份整个数据库，比如:</p><p>　　$exp system/manager inctype=complete file=990702.dmp</p><p>　　(2)“增量型”增量导出</p><p>　　备份上一次备份后改变的数据。比如:</p><p>　　$exp system/manager inctype=incremental file=990702.dmp</p><p>　　(3)“累计型”增量导出(Cumulative)</p><p>　　累计型导出方式只是导出自上次“完全” 导出之后数据库中变化了的信息。比如:</p><p>　　$exp system/manager inctype=cumulative file=990702.dmp</p><p>　　数据库管理员可以排定一个备份日程表，用数据导出的三个不同方式合理高效地完成。比如数据库的备份任务可作如下安排:</p><p>　　·星期一:完全导出(A)</p><p>　　·星期二:增量导出(B)</p><p>　　·星期三:增量导出(C)</p><p>　　·星期四:增量导出(D)</p><p>　　·星期五:累计导出(E)</p><p>　　·星期六:增量导出(F)</p><p>　　·星期日:增量导出(G)</p><p>　　如果在星期日，数据库遭到意外破坏，数据库管理员可按以下步骤来<a class="bluekey" href="http://www.yesky.com/key/2959/167959.html" target="_blank">恢复数据</a>库:</p><p>　　第一步:用命令CREATE DATABASE重新生成数据库结构;</p><p>　　第二步:创建一个足够大的附加回段。</p><p>　　第三步:完全增量导入A:</p><p>　　$imp system./manager inctype= RECTORE FULL=Y FILE=A</p><p>　　第四步:累计增量导入E:</p><p>　　$imp system/manager inctype= RECTORE FULL=Y FILE =E</p><p>　　第五步:最近增量导入F:</p><p>　　$imp system/manager inctype=RESTORE FULL=Y FILE=F</p><p>　　&lt;2&gt;冷备份</p><p>　　冷备份发生在数据库已经正常关闭的情况下，当正常关闭时会提供给我们一个完整的数据库。冷备份是将关键性文件拷贝到另外位置的一种说法。对于备份Oracle信息而言，冷备份是最快和最安全的方法。冷备份的优点是:</p><p>　　·是非常快速的备份方法(只需拷贝文件)</p><p>　　·容易归档(简单拷贝即可)</p><p>　　·容易恢复到某个时间点上(只需将文件再拷贝回去)</p><p>　　·能与归档方法相结合，作数据库“最新状态”的恢复。</p><p>　　·低度维护，高度安全。</p><p>　　但冷备份也有如下不足:</p><p>　　·单独使用时，只能提供到“某一时间点上”的恢复。</p><p>　　·在实施备份的全过程中，数据库必须要作备份而不能作其它工作。也就是说，在冷备份过程中，数据库必须是关闭状态。</p><p>　　·若磁盘空间有限，只能拷贝到磁带等其它外部存储设备上，速度会很慢。</p><p>　　·不能按表或按用户恢复。</p><p>　　如果可能的话(主要看效率)，应将信息备份到磁盘上，然后启动数据库(使用户可以工作)并将所备份的信息拷贝到磁带上(拷贝的同时，数据库也可以工作)。冷备份中必须拷贝的文件包括:</p><p>　　·所有数据文件</p><p>　　·所有控制文件</p><p>　　·所有联机REDO LOG文件</p><p>　　·Init.ora文件(可选)</p><p>　　值得注意的是冷备份必须在数据库关闭的情况下进行，当数据库处于打开状态时，执行数据库文件系统备份是无效的</p><p>　　下面是做冷备份的完整例子:</p><p>　　(1) 关闭数据库$sqldba lmode=y</p><p>　　SQLDBA &gt;connect internal;</p><p>　　SQLDBA &gt;shutdown normal;</p><p>　　(2) 用拷贝命令备份全部的时间文件、重做日志文件、控制文件、初始化参数文件</p><p>　　SQLDBA &gt;! cp &lt; file &gt; &lt; backup <a class="bluekey" href="http://www.yesky.com/key/3144/168144.html" target="_blank">directory</a> &gt;</p><p>　　(3) 重启Oracle数据库</p><p>　　$sqldba lmode=y</p><p>　　SQLDBA &gt;connect internal;</p><p>　　SQLDBA &gt;startup;</p><p>　　&lt;3&gt;热备份</p><p>　　热备份是在数据库运行的情况下，采用archivelog mode方式备份数据的方法。所以，如果你有昨天夜里的一个冷备份而且又有今天的热备份文件，在发生问题时，就可以利用这些资料恢复更多的信息。热备份要求数据库在Archivelog方式下操作，并需要大量的档案空间。一旦数据库运行在archivelog状态下，就可以做备份了。热备份的命令文件由三部分组成:</p><p>　　1.数据文件一个表空间一个表空间地备份。</p><p>　　(1)设置表空间为备份状态</p><p>　　(2)备份表空间的数据文件</p><p>　　(3)恢复表空间为正常状态</p><p>　　2.备份归档log文件。</p><p>　　(1)临时停止归档进程</p><p>　　(2)log下那些在archive redo log目标目录中的文件</p><p>　　(3)重新启动archive进程</p><p>　　(4)备份归档的redo log 文件</p><p>　　3.用alter database backup controlfile命令来备份拷贝文件</p><p>　　热备份的优点是:</p><p>　　·可在表空间或数据文件级备份，备份时间短。</p><p>　　·备份时数据库仍可使用。</p><p>　　·可达到秒级恢复(恢复到某一时间点上)。</p><p>　　·可对几乎所有数据库实体作恢复。</p><p>　　·恢复是快速的，在大多数情况下在数据库仍工作时恢复。</p><p>　　热备份的不足是:</p><p>　　·不能出错，否则后果严重。</p><p>　　·若热备份不成功，所得结果不可用于时间点的恢复。</p><p>　　·因难于维护，所以要特别仔细小心，不允许“以失败而告终”。</p><p>　　【二】来自内部的另外一个隐患--用户管理以及密码问题</p><p>　　在这里，其实作为一个差不多点的数据库管理员都很清楚，Oracle数据库本身就使用了很多种手段来加强数据库的安全性，经常见到的就有密码，角色，权限等等。那么我们就从最简单的DBSNMP</p><p>　　说起:</p><p>　　Oralce数据库如果采用典型安装后，自动创建了一个叫做DBSNMP的用户，该用户负责运行Oracle系统的智能代理(Intelligent Agent)，该用户的缺省密码也是“DBSNMP”。如果忘记修改该用户的口令，任何人都可以通过该用户存取数据库系统。现在我们来看一下该用户具有哪些权限和角色，然后来分析一下该用户对数据库系统可能造成的损失。</p><p>　　启动SQL/PLUS程序，使用该用户登录进入:</p><p>　　SQL&gt; select * from session_privs;</p><p>　　CREATE SESSION</p><p>　　ALTER SESSION</p><p>　　UNLIMITED TABLESPACE</p><p>　　CREATE TABLE</p><p>　　CREATE CLUSTER</p><p>　　CREATE SYNONYM</p><p>　　CREATE PUBLIC SYNONYM</p><p>　　CREATE VIEW</p><p>　　CREATE SEQUENCE</p><p>　　CREATE DATABASE LINK</p><p>　　CREATE PROCEDURE</p><p>　　CREATE TRIGGER</p><p>　　ANALYZE ANY</p><p>　　CREATE TYPE</p><p>　　CREATE OPERATOR</p><p>　　CREATE INDEXTYPE</p><p>　　可以看到该用户不是SYS或SYSTEM管理用户，然而，它却具有两个系统级权限:UNLIMITED TABLESPACE和CREATE PUBLIC SYNONYM。</p><p>　　看到这两个权限你应该马上想到，这些都是安全隐患，尤其是UNLIMITED TABLESPACE，它是破坏数据库系统的攻击点之一。如果这时候你还依然认为，即使有人利用这个没有修改的口令登录进数据库也造成不了什么损失的话，我就不得不提醒你:该用户具有UNLIMITED TABLESPACE的系统权限，它可以写一个小的脚本，然后恶意将系统用垃圾数据填满，这样数据库系统也就无法运行，并将直接导致最终的瘫痪。目前很多数据库系统都要求7X24的工作，如果出现了系统用垃圾数据填满的情况，那么，等数据库系统恢复时，恐怕不可挽回的损失已经造成了。</p><p>　　可是除了 DBSNMP 还有很多其他的用户，怎么办呢?让我们先看一下目前普遍存在于Oracle数据库中的用户管理问题:</p><p>　　(1)权限过大:对ORACLE数据库编程和浏览的一般用户常常具有DBA (数据库管理员权限)，</p><p>　　能对数据库系统做任何修改或删除。</p><p>　　(2)安全性差:很多ORACLE用户缺省存储位置都在系统表空间，这样不仅影响系统的正常工</p><p>　　作，而且不同用户的数据信息互相影响、透明，保密性差。随着数据的不断加入，</p><p>　　有可能使整个数据库系统崩溃。</p><p>　　(3)密码有规律:在ORACLE调试初期形成的用户名和密码一致的不良习惯保留到现在;系统用户SYS和SYSTEM的密码也众所皆知。</p><p>　　知道了这些普遍的“毛病”，我们怎么做呢?下面是我的一些建议:</p><p>　　(1)ORACLE DBA (数据库管理员)的规范</p><p>　　·SUN Solaris操作系统下ORACLE用户密码应严格保密，绝不该把密码设成</p><p>　　ORACLE;并指定专门的数据库管理员定期修改。</p><p>　　·ORACLE初始化建立的SYS和SYSTEM系统管理员用户密码应由原来MANAGER改成别的不易被记忆的字符串。</p><p>　　·ORACLE WEB SERVER的管理端口具备DBA浏览数据库的能力，因此其管理者</p><p>　　ADMIN的密码也应保密，不该把密码设成MANAGER;并指定专门的数据库管理员定</p><p>　　期修改。</p><p>　　·ORACLE DBA最好在SUN SPARC服务器控制台上用窗口式界面实现管理。前提</p><p>　　是ORACLE用户启动服务器，然后在窗口式命令行下输入SVRMGRM，即启动了ORACLE SERVER MANAGER菜单式管理;用SYSDBA身份登录后，就可做数据库系统维护工作了</p><p>　　(2)SQL*PLUS编程用户的规范</p><p>　　·存储结构的规范</p><p>　　考虑到用SQL*PLUS编程可实现各行各业、各公司、各部门多种多样的应用需求，我们的SQL*PLUS编程用户也应该朝这个方向规范:不同种类的应用必须有不同的用户;不同种类的应用必须有不同的存储位置，包括物理文件、缺省表空间、临时表空间的创建和规划:当准备编写某一较大规模(从ORACLE数据量和面向用户量考虑)应用程序时，首先应该创建一个逻辑的存储位置-表空间，同时定义物理文件的存放路径和所占硬盘的大小。</p><p>　　①、物理文件缺省的存放路径在/oracle_home/dbs下，在命令行下用UNIX指令df -k 可查看硬盘资源分区的使用情况。如果oracle_home使用率达90‰以上，而且有一个或多个较为空闲的硬盘资源分区可以利用，我们最好把物理文件缺省的存放路径改到较为空闲的硬盘资源分区路径下。在此路径下我们可以这样规划资源物理文件的存储:</p><p>　　xxx表空间</p><p>　　xxx行业/ xxx公司/ xxx 部门/ xxx 服务.dbf</p><p>　　DEMO表空间</p><p>　　default_datafile_home1/col /elec/sys4/demo1.dbf</p><p>　　default_datafile_home1/col /elec/sys4/demo2.dbf</p><p>　　公司系统四部摹拟演示系统物理文件</p><p>　　HUMAN表空间</p><p>　　default_datafile_home1/col/elec/human/human.dbf</p><p>　　公司人事部人事管理系统物理文件</p><p>　　BOOK表空间</p><p>　　default_datafile_home1/col/elec/book/book.dbf</p><p>　　公司资料室图书管理系统物理文件</p><p>　　QUESTION表空间</p><p>　　default_datafile_home1/col/elec/client/question.dbf</p><p>　　公司客户服务部问题库系统物理文件</p><p>　　PC表空间</p><p>　　default_datafile_home1/col/chaoxun/client/pc.dbf</p><p>　　公司PC机售后服务系统物理文件</p><p>　　……表空间</p><p>　　default_datafile_home2/……………………………</p><p>　　等等</p><p>　　说明:其中default_datafile_home1指oracle_home/dbs;</p><p>　　default_datafile_home2指较为空闲的硬盘资源分区路径。</p><p>　　②、物理文件的大小根据应用系统的数据量、数据对象、程序包的多少来定。一般用于摹拟演示的小系统，表空间初始的物理文件为2M即能满足要求，如果信息量满，还可以增加物理文件，扩充表空间(每次扩充大小也可暂定为2M);一般实际运行的应用系统可适当增加表空间初始的物理文件大小，但也不要一次分配太大(因为不易回收空间，却易扩充空间)，这也需要根据具体情况具体分析:信息量大、需长时间保存的应用在条件允许情况下，表空间可以大到几百M甚至上G;信息量小、短期经常刷新的应用，表空间可以控制在2M以下。</p><p>　　③、表空间的名称应该采用同系统应用相似的英文字符或字符缩写，表空间所对应的一个或多个物理文件名也应有相关性。不同用户所处的缺省表空间不同，存储的信息就不能互相访问。这比把所有用户信息都储存在系统表空间，安全性大大提高了。如果用ORACLE WEB SERVER管理端口创建的用户，其缺省和临时表空间一定是系统表空间，DBA切记要改变用户的缺省表空间。临时表空间存放临时数据段，处理一些排序、合并等中间操作，根据实际应用的需求可以把它们放在专门创建的表空间里;如果系统表空间大，也可以把它们放在系统表空间。用户创建的数据索引最好和数据文件分开存放在不同表空间，以减少数据争用和提高响应速度。</p><p>　　·密码和用户名的规范</p><p>　　有相当数量的ORACLE用户名和密码一致，这是个很不安全的因素。我们建议ORACLE用户名和密码一定不要一样，密码最好在五，六位字符以上。不同用户间不应该使用相同的密码。用户名的定义可根据实际应用的英文名来设，而依据编程人员的姓名定义的用户名实际上不规范，可在日后的工作中结合上述有关存储结构规范的说明逐步改进。</p><p>　　(3)特殊要求用户的规范</p><p>　　在ORACLE数据库使用过程中，还会遇到一些有特殊要求的用户:非编程人员需要对某个表有查询、增加、删除、修改的权利。DBA应创建一个这样的用户，先确定用户名和密码，再规定相关应用所在缺省表空间(包含某个表)和临时表空间，最后TABLE属主给其授权:赋予CONNECT角色SELECT、INSERT、DELETE、UPDATE ON THE TABLE的对象级权限，这可根据实际需求自由取舍。</p><p>　　举例:●给新用户授于对象级权限(命令行方式):</p><p>　　假设新用户NEW2需要有查询、删除、修改DCD用户的表EMP。</p><p>　　%svrmgrl</p><p>　　SVRMGR&gt;connect internal; 以系统管理员登录</p><p>　　SVRMGR&gt;create user new2 identified by new2345 default tablespace app;</p><p>　　SVRMGR&gt;connect dcd/dcdpwd; 以dcd用户登录</p><p>　　SVRMGR&gt;grant connect to new2;</p><p>　　SVRMGR&gt;grant select on emp to new2;</p><p>　　SVRMGR&gt;grant delete on emp to new2;</p><p>　　SVRMGR&gt;grant update on emp to new2;</p><p>　　说了这么多关于用户的问题，那么接下来我们就详细得说一下关于密码文件的使用以及维护--在Oracle数据库系统中，用户如果要以特权用户身份(INTERNAL/SYSDBA/SYSOPER)登录Oracle数据库可以有两种身份验证的方法:即使用与操作系统集成的身份验证或使用Oracle数据库的密码文件进行身份验证。因此，管理好密码文件，对于控制授权用户从远端或本机登录Oracle数据库系统，执行数据库管理工作，具有重要的意义。</p><p>　　Oracle数据库的密码文件存放有超级用户INTERNAL/SYS的口令及其他特权用户的用户名/口令，它一般存放在ORACLE_HOME\DATABASE目录下。</p><p>　　·密码文件的创建:</p><p>　　在使用Oracle Instance Manager创建一数据库实例的时侯，在ORACLE_HOME\DATABASE目录下还自动创建了一个与之对应的密码文件，文件名为PWDSID.ORA，其中SID代表相应的Oracle数据库系统标识符。此密码文件是进行初始数据库管理工作的基础。在此之后，管理员也可以根据需要，使用工具ORAPWD.EXE手工创建密码文件，命令格式如下:</p><p>　　C:\ &gt;ORAPWD　FILE=&lt; FILENAME &gt;　PASSWORD =&lt; PASSWORD &gt; ENTRIES=&lt; MAX_USERS &gt;</p><p>　　各命令参数的含义为:</p><p>　　FILENAME:密码文件名;</p><p>　　PASSWORD:设置INTERNAL/SYS帐号的口令;</p><p>　　MAX_USERS:密码文件中可以存放的最大用户数，对应于允许以SYSDBA/SYSOPER权限登录数据库的最大用户数。由于在以后的维护中，若用户数超出了此限制，则需要重建密码文件，所以此参数可以根据需要设置得大一些。</p><p>　　有了密码文件之后，需要设置初始化参数REMOTE_LOGIN_PASSWORDFILE来控制密码文件的使用状态。</p><p>　　·设置初始化参数REMOTE_LOGIN_PASSWORDFILE:</p><p>　　在Oracle数据库实例的初始化参数文件中，此参数控制着密码文件的使用及其状态。它可以有以下几个选项:</p><p>　　NONE:指示Oracle系统不使用密码文件，特权用户的登录通过操作系统进行身份验证;</p><p>　　EXCLUSIVE:指示只有一个数据库实例可以使用此密码文件。只有在此设置下的密码文件可以包含有除INTERNAL/SYS以外的用户信息，即允许将系统权限SYSOPER/SYSDBA授予除INTERNAL/SYS以外的其他用户。</p><p>　　SHARED:指示可有多个数据库实例可以使用此密码文件。在此设置下只有INTERNAL/SYS帐号能被密码文件识别，即使文件中存有其他用户的信息，也不允许他们以SYSOPER/SYSDBA的权限登录。此设置为缺省值。</p><p>　　在REMOTE_LOGIN_PASSWORDFILE参数设置为EXCLUSIVE、SHARED情况下，Oracle系统搜索密码文件的次序为:在系统注册库中查找ORA_SID_PWFILE参数值(它为密码文件的全路径名);若未找到，则查找ORA_PWFILE参数值;若仍未找到，则使用缺省值ORACLE_HOME\DATABASE\PWDSID.ORA;其中的SID代表相应的Oracle数据库系统标识符。</p><p>　　·向密码文件中增加、删除用户:</p><p>　　当初始化参数REMOTE_LOGIN_PASSWORDFILE设置为EXCLUSIVE时，系统允许除INTERNAL/SYS以外的其他用户以管理员身份从远端或本机登录到Oracle数据库系统，执行数据库管理工作;这些用户名必须存在于密码文件中，系统才能识别他们。由于不管是在创建数据库实例时自动创建的密码文件，还是使用工具ORAPWD.EXE手工创建的密码文件，都只包含INTERNAL/SYS用户的信息;为此，在实际操作中，可能需要向密码文件添加或删除其他用户帐号。</p><p>　　由于仅被授予SYSOPER/SYSDBA系统权限的用户才存在于密码文件中，所以当向某一用户授予或收回SYSOPER/SYSDBA系统权限时，他们的帐号也将相应地被加入到密码文件或从密码文件中删除。由此，向密码文件中增加或删除某一用户，实际上也就是对某一用户授予或收回SYSOPER/SYSDBA系统权限。</p><p>　　要进行此项授权操作，需使用SYSDBA权限(或INTERNAL帐号)连入数据库，且初始化参数REMOTE_LOGIN_PASSWORDFILE的设置必须为EXCLUSIVE。具体操作步骤如下:</p><p>　　创建相应的密码文件;</p><p>　　设置初始化参数REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE;</p><p>　　使用SYSDBA权限登录: CONNECT　SYS/internal_user_passsword　AS　SYSDBA;</p><p>　　启动数据库实例并打开数据库;</p><p>　　创建相应用户帐号，对其授权(包括SYSOPER和SYSDBA): 授予权限:GRANT　SYSDBA　TO　user_name;</p><p>　　收回权限:REVOKE　SYSDBA　FROM　user_name;</p><p>　　现在这些用户可以以管理员身份登录数据库系统了;</p><p>　　·使用密码文件登录:</p><p>　　有了密码文件后，用户就可以使用密码文件以SYSOPER/SYSDBA权限登录Oracle数据库实例了，注意初始化参数REMOTE_LOGIN_PASSWORDFILE应设置为EXCLUSIVE或SHARED。任何用户以SYSOPER/SYSDBA的权限登录后，将位于SYS用户的Schema之下，以下为两个登录的例子:</p><p>　　1. 以管理员身份登录:</p><p>　　假设用户scott已被授予SYSDBA权限，则他可以使用以下命令登录:</p><p>　　CONNECT　scott/tiger　AS　SYSDBA</p><p>　　2. 以INTERNAL身份登录:</p><p>　　CONNECT　INTERNAL/INTERNAL_PASSWORD</p><p>　　·密码文件的维护:</p><p>　　1. 查看密码文件中的成员:</p><p>　　可以通过查询视图V$PWFILE_USERS来获取拥有SYSOPER/SYSDBA系统权限的用户的信息，表中SYSOPER/SYSDBA列的取值TRUE/FALSE表示此用户是否拥有相应的权限。这些用户也就是相应地存在于密码文件中的成员。</p><p>　　2. 扩展密码文件的用户数量:</p><p>　　当向密码文件添加的帐号数目超过创建密码文件时所定的限制(即ORAPWD.EXE工具的MAX_USERS参数)时，为扩展密码文件的用户数限制，需重建密码文件，具体步骤如下:</p><p>　　a) 查询视图V$PWFILE_USERS，记录下拥有SYSOPER/SYSDBA系统权限的用户信息;</p><p>　　关闭数据库;</p><p>　　c) 删除密码文件;</p><p>　　d) 用ORAPWD.EXE新建一密码文件;</p><p>　　e) 将步骤a中获取的用户添加到密码文件中。</p><p>　　3. 修改密码文件的状态:</p><p>　　密码文件的状态信息存放于此文件中，当它被创建时，它的缺省状态为SHARED。可以通过改变初始化参数REMOTE_LOGIN_PASSWORDFILE的设置改变密码文件的状态。当启动数据库事例时，Oracle系统从初始化参数文件中读取REMOTE_LOGIN_PASSWORDFILE参数的设置;当加载数据库时，系统将此参数与口令文件的状态进行比较，如果不同，则更新密码文件的状态。若计划允许从多台客户机上启动数据库实例，由于各客户机上必须有初始化参数文件，所以应确保各客户机上的初始化参数文件的一致性，以避免意外地改变了密码文件的状态，造成数据库登陆的失败。</p><p>　　4. 修改密码文件的存储位置:</p><p>　　密码文件的存放位置可以根据需要进行移动，但作此修改后，应相应修改系统注册库有关指向密码文件存放位置的参数或环境变量的设置。</p><p>　　5. 删除密码文件:</p><p>　　在删除密码文件前,应确保当前运行的各数据库实例的初始化参数REMOTE_LOGIN_PASSWORDFILE皆设置为NONE。在删除密码文件后，若想要以管理员身份连入数据库的话，则必须使用操作系统验证的方法进行登录。</p><p>　　但是管理员都觉得乏味，因为在管理员中流行一种很简单的加密办法--就是经常，很频繁地修改自己的密码。可是，每次修改都跟打一次仗似的--因为更新程序并不是每个人都愿意做的事情。</p><p>　　那么有没有什么简单点的办法呢?请往下看:</p><p>　　模型:Oracle7.3;开发工具:Develope2000。收费系统(在数据库中的名称是SFYY)，其Client端分散在市区的数个营业点，通过城域网与主机(小型 机)相连。</p><p>　　过程:</p><p>　　·在收费小型机Oracle系统的system用户(DBA)下，创建新用户test;</p><p>　　create user test</p><p>　　identified by carton</p><p>　　default tablespace dataspace1</p><p>　　quota 100K</p><p>　　·对test用户授以权限;</p><p>　　grant create session to test;</p><p>　　grant resource to test;</p><p>　　·在test用户下建立一个存储函数mmtranslate,它其实是一个加密程序。下面是一个简 单的例子。</p><p>　　function mmtranslate(m varchar2)</p><p>　　return varchar2</p><p>　　as</p><p>　　i number(2);</p><p>　　kk varchar2(10);</p><p>　　begin</p><p>　　kk:=′′;</p><p>　　i:=1;</p><p>　　loop</p><p>　　if i&lt;=length(m) then</p><p>　　if instr(′1234567890′,substr(m,i,1),1,1)&gt;0 then</p><p>　　kk:=kk||chr(100+to_number(substr(m,i,1)));</p><p>　　elseif instr(‘wxyz‘,substr(m,i,1),1,1)&gt;0 then</p><p>　　kk:=kk||chr(-8+ascii(substr(m,i,1)));</p><p>　　else</p><p>　　kk:=kk||chr(4+ascii(substr(m,i,1)));</p><p>　　end if;</p><p>　　else</p><p>　　exit;</p><p>　　end if;</p><p>　　i:=i+1;</p><p>　　end loop;</p><p>　　return kk;</p><p>　　exception</p><p>　　when others then</p><p>　　return ′-1′;</p><p>　　end;</p><p>　　·在test用户下建表mmtest并插入记录:</p><p>　　create table mmtest</p><p>　　(usnamevarchar2(6),------用户名称</p><p>　　mimavarchar2(6)------加密前的密码);</p><p>　　insert into mmtest values( ‘sfyy‘,‘eds2‘);</p><p>　　commit;</p><p>　　·执行以下语句</p><p>　　SQL&gt;select mmtranslate(‘eds2‘) from dual;</p><p>　　MMTRANSLATE(‘EDS2‘)</p><p>　　----------------------------------------</p><p>　　ihwf</p><p>　　利用DBA权限更改sfyy的密码为上面语句的执行结果:</p><p>　　alter user sffy</p><p>　　identified by ihwf; ;</p><p>　　·修改应用程序，对于开发环境是Develope2000的程序来说，主要是修改主程序的on-lo gon触发器:</p><p>　　declare</p><p>　　mm varchar2(6);</p><p>　　begin</p><p>　　logon(‘test‘,‘carton‘);</p><p>　　select mima into mm from mmtest where usname=‘sfyy‘;</p><p>　　mm:=mmtranslate(mm);</p><p>　　logout;</p><p>　　logon(‘sfyy‘,mm);</p><p>　　end;</p><p>　　然后再利用触发器WHEN-NEW-FROM-INSTANCE执行Callfrom或Newform等 命令，进入业务处理程序。这个主程序应当仅仅由管理员来掌握,编译之后将执行文件下发 到各收费点的Clien端。</p><p>　　·在System用户下，利用Oracle提供的pupbld.sql,建立表Productuserprofile,执行下面这样的命令，限制在非开发状态Sql命令的使用,例如</p><p>　　insert into productuserprofile</p><p>　　(product,userid,attribute,charvalue) values</p><p>　　(‘SQL*Plus‘,‘TEST‘,‘CONNECT‘,‘DISABLED‘);</p><p>　　insert into productuserprofile</p><p>　　(product,userid,attribute,charvalue) values</p><p>　　(‘SQL*Plus‘,‘SFYY‘,‘DELETE‘,‘DISABLED‘);这样，在SQL状态下，根本无法连接到TEST用户，而在 sfyy用户下，delete命令将不能执行。当然，DBA可以改变这些设置。</p><p>　　当然了，这个仅仅是属于一种“应用技巧”，但是足可以把那些每天忙于更新系统的管理员舒服好几天了。但是另一方面，还要加强对源程序的管理，在Client端只存放执行程序。加强审计，发现异常现象，及时处理。这样才可以做到更高一层的“安全”。</p><p>　　在下面，我主要是向大家介绍一个REM对GHXXB制立数据库触发子,密码的加密程序。</p><p>　　REM 对GHXXB制立数据库触发子(当INSERT OR UPDATE GHXXB时触发)</p><p>　　drop trigger scjmmm;</p><p>　　create or replace trigger scjmmm</p><p>　　before insert or update of mm On ghxxb For each Row</p><p>　　Begin</p><p>　　:new.mm:=ENCRYPT(:new.mm,:NEW.GH,TO_CHAR(SYSDATE,‘SS‘));</p><p>　　End;</p><p>　　/</p><p>　　---------------------------密码的加密程序ENCRYPT----------------------</p><p>　　Create or Replace</p><p>　　Function ENCRYPT (Inpass In Varchar2,IN_GH In Varchar2,IN_SS In Varchar2)</p><p>　　Return Varchar2 Is</p><p>　　bcs varchar2(20);</p><p>　　bcs1 number;</p><p>　　cs number;</p><p>　　jg number;</p><p>　　m_gh VARCHAR2(4);</p><p>　　m_mm VARCHAR2(20);</p><p>　　Begin</p><p>　　m_gh:=IN_GH;</p><p>　　m_mm:=INPASS;</p><p>　　cs:=TO_NUMBER(IN_SS);</p><p>　　If cs&lt;=1 then cs:=77 ;end if;</p><p>　　bcs:=substr(to_char(ascii(substr(m_gh,1,1))),1,2);</p><p>　　If bcs&lt;‘1‘ then bcs:=‘7‘ ;end if;</p><p>　　m_gh:=substr(m_gh,2);</p><p>　　Loop EXIT WHEN nvl(length(m_gh),0)=0 ;</p><p>　　bcs:=bcs||substr(to_char(ascii(substr(m_gh,1,1))),-1,1);</p><p>　　m_gh:=substr(m_gh,2);</p><p>　　End loop;</p><p>　　Loop EXIT WHEN nvl(length(m_mm),0)=0 ;</p><p>　　bcs:=bcs||substr(to_char(ascii(substr(m_mm,1,1))),-1,1);</p><p>　　m_mm:=substr(m_mm,2);</p><p>　　End loop;</p><p>　　bcs1:=to_number(bcs);</p><p>　　jg:=cs*bcs1;</p><p>　　Loop EXIT WHEN length(to_char(jg))&gt;13;</p><p>　　jg:=jg*cs ;</p><p>　　End loop;</p><p>　　RETURN(IN_SS||substr(to_char(jg),1,14));</p><p>　　End;</p><p>　　/</p><p>　　总结上面的东西，我们仅仅是从自身做起，知道了怎么维护Oracle数据库安全这个话题的“皮毛”。可是，对于这个似乎永远也说不完的话题，我们光知道怎么从内部“防御”就够了吗?不要忘了，在外面，还有一群虎视耽耽的“hacker”在盯着你的数据库--因为这里面有他们想要的东西。</p><p>　　所以，请大家关注好下一个话题:</p><p>　　§2.不被“hacker”入侵的几个建议</p><p>　　我们的目标是:没有蛀牙!(开个玩笑~!呵呵)其实应该是:它应尽可能地堵住潜在的各种漏洞，防止非法用户利用它们侵入数据库系统。对于数据库数据的安全问题，数据库管理员可以参考有关系统双机热备份功能以及数据库的备份和恢复的资料。</p><p>　　以下就数据库系统不被非法用户侵入这个问题作进一步的阐述。</p><p>　　·组和安全性:在操作系统下建立用户组也是保证数据库安全性的一种有效方法。Oracle程序为了安全性目的一般分为两类:一类所有的用户都可执行，另一类只DBA可执行。在Unix环境下组设置的配置文件是/etc/group，关于这个文件如何配置，请参阅Unix的有关手册，以下是保证安全性的几种方法:</p><p>　　(1)在安装Oracle Server前，创建数据库管理员组(DBA)而且分配root和Oracle软件拥有者的用户ID给这个组。DBA能执行的程序只有710权限。在安装过程中SQL*DBA系统权限命令被自动分配给DBA组。</p><p>　　(2)允许一部分Unix用户有限制地访问Oracle<a class="bluekey" href="http://www.yesky.com/key/2575/167575.html" target="_blank">服务器系统</a>，增加一个由授权用户组的Oracle组，确保给Oracle服务器实用例程Oracle组ID，公用的可执行程序，比如SQL*Plus，SQL*forms等，应该可被这组执行，然后该这个实用例程的权限为710，它将允许同组的用户执行，而其他用户不能。</p><p>　　(3)改那些不会影响数据库安全性的程序的权限为711。(注:在我们的系统中为了安装和调试的方便，Oracle数据库中的两个具有DBA权限的用户Sys和System的缺省密码是manager。为了您数据库系统的安全，我们强烈建议您该掉这两个用户的密码，具体操作如下:</p><p>　　在SQL*DBA下键入:</p><p>　　alter user sys indentified by password;</p><p>　　alter user system indentified by password;</p><p>　　其中password为您为用户设置的密码。</p><p>　　·Oracle服务器实用例程的安全性:</p><p>　　以下是保护Oracle服务器不被非法用户使用的几条建议:</p><p>　　(1) 确保$ORACLE_HOME/bin目录下的所有程序的拥有权归Oracle软件拥有者所有;</p><p>　　(2) 给所有用户实用便程(sqiplus,sqiforms,e<a class="bluekey" href="http://www.yesky.com/key/1970/166970.html" target="_blank">xp,</a>imp等)711权限，使服务器上所有的用户都可访问Oracle服务器;</p><p>　　(3) 给所有的DBA实用例程(比如SQL*DBA)700权限。Oracle服务器和Unix组当访问本地的服务时，您可以通过在操作系统下把Oracle服务器的角色映射到Unix的组的方式来使用Unix管理服务器的安全性，这种方法适应于本地访问。</p><p>　　在Unix中指定Oracle服务器角色的格式如下:</p><p>　　ora_sid_role[_dla]</p><p>　　其中 sid 是您Oracle数据库的oracle_sid;</p><p>　　role 是Oracle服务器中角色的名字;</p><p>　　d (可选)表示这个角色是缺省值;a (可选)表示这个角色带有WITH ADMIN选项，您只可以把这个角色授予其他角色，不能是其他用户。</p><p>　　以下是在/etc/group文件中设置的例子:</p><p>　　ora_test_osoper_d:NONE:1:jim,narry,scott</p><p>　　ora_test_osdba_a:NONE:3:pat</p><p>　　ora_test_role1:NONE:4:bob,jane,tom,mary,jim</p><p>　　bin: NONE:5:root,oracle,dba</p><p>　　root:NONE:7:root</p><p>　　词组“ora_test_osoper_d”表示组的名字;词组“NONE”表示这个组的密码;数字1表示这个组的ID;接下来的是这个组的成员。前两行是Oracle服务器角色的例子，使用test作为sid，osoper和osdba作为Oracle服务器角色的名字。osoper是分配给用户的缺省角色，osdba带有WITH ADMIN选项。为了使这些数据库角色起作用，您必须shutdown您的数据库系统，设置Oracle数据库参数文件initORACLE_SID.ora中os_roles参数为True，然后重新启动您的数据库。如果您想让这些角色有connect internal权限，运行orapwd为这些角色设置密码。当您尝试connect internal时，您键入的密码表示了角色所对应的权限。</p><p>　　·SQL*DBA命令的安全性:</p><p>　　如果您没有SQL*PLUS应用程序，您也可以使用SQL*DBA作SQL查权限相关的命令只能分配给Oracle软件拥有者和DBA组的用户，因为这些命令被授予了特殊的系统权限。</p><p>　　(1) startup</p><p>　　(2) shutdown</p><p>　　(3) connect internal</p><p>　　·数据库文件的安全性:</p><p>　　Oracle软件的拥有者应该这些数据库文件($ORACLE_HOME/dbs/*.dbf)设置这些文件的使用权限为0600:文件的拥有者可读可写，同组的和其他组的用户没有写的权限。</p><p>　　Oracle软件的拥有者应该拥有包含数据库文件的目录，为了增加安全性，建议收回同组和其他组用户对这些文件的可读权限。</p><p>　　·网络安全性:</p><p>　　当处理网络安全性时，以下是额外要考虑的几个问题。</p><p>　　(1) 在网络上使用密码在网上的远端用户可以通过加密或不加密方式键入密码，当您用不加密方式键入密码时，您的密码很有可能被非法用户截获，导致破坏了系统的安全性。</p><p>　　(2) 网络上的DBA权限控制您可以通过下列两种方式对网络上的DBA权限进行控制:</p><p>　　A 设置成拒绝远程DBA访问;</p><p>　　B 通过orapwd给DBA设置特殊的密码。</p><p>　　·建立安全性策略:</p><p>　　系统安全性策略</p><p>　　(1)管理数据库用户:数据库用户是访问Oracle数据库信息的途径，因此，应该很好地维护管理数据库用户的安全性。按照数据库系统的大小和管理数据库用户所需的工作量，数据库安全性管理者可能只是拥有create，alter，或drop数据库用户的一个特殊用户，或者是拥有这些权限的一组用户，应注意的是，只有那些值得信任的个人才应该有管理数据库用户的权限。</p><p>　　(2) 用户身份确认:数据库用户可以通过操作系统，网络服务，或数据库进行身份确认，通过主机操作系统进行用户身份认证的优点有:</p><p>　　A 用户能更快，更方便地联入数据库;</p><p>　　B 通过操作系统对用户身份确认进行集中控制:如果操作系统与数据库用户信息一致，Oracle无须存储和管理用户名以及密码;</p><p>　　C 用户进入数据库和操作系统审计信息一致。</p><p>　　(3) 操作系统安全性</p><p>　　A 数据库管理员必须有create和delete文件的操作系统权限;</p><p>　　B 一般数据库用户不应该有create或delete与数据库相关文件的操作系统权限;</p><p>　　C 如果操作系统能为数据库用户分配角色，那么安全性管理者必须有修改操作系统帐户安全性区域的操作系统权限。</p><p>　　·数据的安全性策略:</p><p>　　数据的生考虑应基于数据的重要性。如果数据不是很重要，那么数据的安全性策略可以稍稍放松一些。然而，如果数据很重要，那么应该有一谨慎的安全性策略，用它来维护对数据对象访问的有效控制。</p><p>　　·用户安全性策略:</p><p>　　(1) 一般用户的安全性:</p><p>　　A 密码的安全性:如果用户是通过数据库进行用户身份的确认，那么建议使用密码加密的方式与数据库进行连接。这种方式的设置方法如下:</p><p>　　在客户端的oracle.ini文件中设置ora_encrypt_login数为true;</p><p>　　在服务器端的initORACLE_SID.ora文件中设置dbling_encypt_login参数为true。</p><p>　　B 权限管理:对于那些用户很多，应用程序和数据对象很丰富的数据库，应充分利用“角色”这个机制所带的方便性对权限进行有效管理。对于复杂的系统环境，“角色”能大大地简化权限的理。</p><p>　　(2) 终端用户的安全性:</p><p>　　您必须针对终端用户制定安全性策略。例如，对于一个有很多用户的大规模数据库，安全性管理者可以决定用户组分类为这些用户组创建用户角色，把所需的权限和应用程序角色授予每一个用户角色，以及为用户分配相应的用户角色。当处理特殊的应用要求时，安全性管理者也必须明确地把一些特定的权限要求授予给用户。您可以使用“角色”对终端用户进行权限管理。</p><p>　　·数据库管理者安全性策略:</p><p>　　(1) 保护作为sys和system用户的连接:</p><p>　　当数据库创建好以后，立即更改有管理权限的sys和system用户的密码，防止非法用户访问数据库。当作为sys和system用户连入数据库后，用户有强大的权限用各种方式对数据库进行改动。</p><p>　　(2) 保护管理者与数据库的连接:</p><p>　　应该只有数据库管理者能用管理权限连入数据库，当以sysdba或startup，shutdown，和recover或数据库对象(例如create,drop，和delete等)进行没有任何限制的操作。</p><p>　　(3) 使用角色对管理者权限进行管理</p><p>　　·应用程序开发者的安全性策略:</p><p>　　(1) 应用程序开发者和他们的权限数据库应用程序开发者是唯一一类需要特殊权限组完成自己工作的数据库用户。开发者需要诸如create table,create，procedure等系统权限，然而，为了限制开发者对数据库的操作，只应该把一些特定的系统权限授予开发者。</p><p>　　(2) 应用程序开发者的环境:</p><p>　　A 程序开发者不应与终端用户竞争数据库资源;</p><p>　　B 用程序开发者不能损害数据库其他应用产品。</p><p>　　(3) free和controlled应用程序开发应用程序开发者有一下两种权限:</p><p>　　A free development</p><p>　　应用程序开发者允许创建新的模式对象，包括table,index,procedure,package等，它允许应用程序开发者开发独立于其他对象的应用程序。</p><p>　　B controlled development</p><p>　　应用程序开发者不允许创建新的模式对象。所有需要table,indes procedure等都由数据库管理者创建，它保证了数据库管理者能完全控制数据空间的使用以及访问数据库信息的途径。但有时应用程序开发者也需这两种权限的混和。</p><p>　　(4) 应用程序开发者的角色和权限数据库安全性管理者能创建角色来管理典型的应用程序开发者的权限要求。</p><p>　　A create系统权限常常授予给应用程序开发者，以至于他们能创建他的数据对象。</p><p>　　B 数据对象角色几乎不会授予给应用程序开发者使用的角色。</p><p>　　(5) 加强应用程序开发者的空间限制作为数据库安全性管理者，您应该特别地为每个应用程序开发者设置以下的一些限制:</p><p>　　A 开发者可以创建table或index的表空间;</p><p>　　B 在每一个表空间中，开发者所拥有的空间份额。应用程序管理者的安全在有许多数据库应用程序的数据库系统中，您可能需要一应用程序管理者，应用程序管理者应负责起以下的任务:</p><p>　　a)为每一个应用程序创建角色以及管理每一个应用程序的角色;</p><p>　　b)创建和管理数据库应用程序使用的数据对象;</p><p>　　c)需要的话，维护和更新应用程序代码和Oracle的存储过程和程序包。</p><p>　　我相信有了以上的这些建议，作为一个Oracle的管理者绝对可以做好他本职的工作了。可是，我们再怎么努力，都始终得面对这样一个现实，那就是Oracle毕竟是其他人开发的，而我们却在使用。所以，Oracle到底有多少漏洞--我想这个不是你和我所能解决的。不过既然作为一篇讨论Oracle数据安全的文章，我认为有必要把漏洞这一块也写进去，毕竟这也是“安全”必不可少的一部分。呵呵!</p><p>　　所以……</p><p>　　【Oracle漏洞举例】:</p><p>　　·Oracle9iAS Web Cache远程拒绝服务攻击漏洞(2002-10-28)</p><p>　　·Oracle 8.1.6的oidldapd中的漏洞</p><p>　　·Oracle 9iAS OracleJSP 泄漏JSP文件信息漏洞</p><p>　　·Linux ORACLE 8.1.5漏洞</p><p>　　想必我没有理由再往下举了，因为读者肯定已经从其他有效的途径得到了关于Oracle漏洞的最新情报。我这里就不再赘述了。</p><p>　　总而言之一句话--“Oracle数据安全是一个博大而又精深的话题;如果你没有耐心，就永远不会得到它的精髓之所在。”</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/30644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-14 17:32 <a href="http://www.blogjava.net/TrampEagle/articles/30644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sybase和Oracle数据库导出文件的互相导入</title><link>http://www.blogjava.net/TrampEagle/articles/30643.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 14 Feb 2006 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30643.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30643.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30643.html</trackback:ping><description><![CDATA[原文引自：<a href="http://searchdatabase.techtarget.com.cn/askexperts/386/2059386.shtml?ticket=ST-1482-pwEqGyyn28IesFO8rs19">http://searchdatabase.techtarget.com.cn/askexperts/386/2059386.shtml?ticket=ST-1482-pwEqGyyn28IesFO8rs19</a><br /><br /><a class="f1">  
<div class="guanggao"><span id="contentAdv"></span></div><p>　　<strong>问:我现在有sybase<a class="bluekey" href="http://www.yesky.com/key/421/25421.html" target="_blank">数据库开发</a>的软件,想把<a class="bluekey" href="http://www.yesky.com/key/4310/34310.html" target="_blank">sybase数据库</a>中的数据导入到利用oracle数据库开发的软件中?如果可以,是不是在开发oracle数据库(现在基于oracle的数据库还没有开发)的时候有什么特别要求?</strong></p><p>　　答:1、简单的办法，是将<a class="bluekey" href="http://www.yesky.com/key/2187/102187.html" target="_blank">sybase</a>中的数据导成SQL <a class="bluekey" href="http://www.yesky.com/key/955/45955.html" target="_blank">语句</a>，然后针对可能不同的<a class="bluekey" href="http://www.yesky.com/key/4712/59712.html" target="_blank">数据类型</a>做一些修改。或者将数据导成文本，使用分隔符隔离，然后使用ORACLE的sqlldr导入。</p><p>　　    2、或者使用一些现成的工具，有些可以试用，你可以看看。 <br /><a href="http://www.swissql.com/products/sybase-to-oracle/sybase-to-oracledownloadform.html">http://www.swissql.com/products/sybase-to-oracle/sybase-to-oracledownloadform.html</a></p></a><img src ="http://www.blogjava.net/TrampEagle/aggbug/30643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-14 17:28 <a href="http://www.blogjava.net/TrampEagle/articles/30643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL到Oracle程序迁移的注意事项</title><link>http://www.blogjava.net/TrampEagle/articles/30642.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 14 Feb 2006 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/30642.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/30642.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/30642.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/30642.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/30642.html</trackback:ping><description><![CDATA[原文引自：<a href="http://www.techtarget.com.cn/434/1952434.shtml">http://www.techtarget.com.cn/434/1952434.shtml</a><br /><br />很多应用项目, 刚起步的时候用MY<a class="bluekey" href="http://www.yesky.com/key/2644/102644.html" target="_blank">SQL数据库</a>基本上能实现各种功能需求，随着应用用户的增多，数据量的增加，MYSQL渐渐地出现不堪重负的情况:连接很慢甚至宕机，于是就有把数据从MYSQL迁到ORACLE的需求，应用程序也要相应做一些修改。本人总结出以下几点注意事项，希望对大家有所帮助。 
<p>　　1. 自动增长的数据类型处理</p><p>　　MYSQL有自动增长的数据类型，插入记录时不用操作此字段，会自动获得数据值。ORACLE没有自动增长的数据类型，需要建立一个自动增长的序列号，插入记录时要把序列号的下一个值赋于此字段。</p><p>　　CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1 <a class="bluekey" href="http://www.yesky.com/key/2535/102535.html" target="_blank">START</a><a class="bluekey" href="http://www.yesky.com/key/1588/96588.html" target="_blank">WITH</a> 1 MAXVALUE 99999 CYCLE NOCACHE;</p><p>　　其中最大的值按字段的长度来定, 如果定义的自动增长的序列号 NUMBER(6) , 最大值为999999</p><p>　　INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL</p><p>　　2. 单引号的处理</p><p>　　MYSQL里可以用双引号包起字符串，ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。</p><p>　　3. 翻页的SQL语句的处理</p><p>　　MYSQL处理翻页的SQL语句比较简单，用LIMIT 开始位置, 记录个数;PHP里还可以用SEEK定位到结果集的位置。ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM&lt;100, 不能用ROWNUM&gt;80。</p><p>　　以下是经过分析后较好的两种ORACLE翻页SQL语句( ID是唯一关键字的字段名 ):</p><p>　　语句一:</p><p>　　SELECT ID, [FIELD_NAME,...] FROM TABLE_NAME <a class="bluekey" href="http://www.yesky.com/key/3271/98271.html" target="_blank">WHERE</a> ID IN ( SELECT ID FROM (SELECT ROWNUM AS NUMROW, ID FROM TABLE_NAME WHERE 条件1 ORDER BY 条件2) WHERE NUMROW &gt; 80 AND NUMROW &lt; 100 ) ORDER BY 条件3;</p><p>　　语句二:</p><p>　　SELECT * FROM (( SELECT ROWNUM AS NUMROW, c.* from (select [FIELD_NAME,...] FROM TABLE_NAME WHERE 条件1 ORDER BY 条件2) c) WHERE NUMROW &gt; 80 AND NUMROW &lt; 100 ) ORDER BY 条件3;</p><p>　　4. 长字符串的处理</p><p>　　长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型，方法借用ORACLE里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断，不能为空的字段值和超出长度字段值都应该提出警告,返回上次操作。</p><p>　　5. 日期字段的处理</p><p>　　MYSQL日期字段分DATE和TIME两种，ORACLE日期字段只有DATE，包含年月日时分秒信息，用当前数据库的系统时间为SYSDATE, 精确到秒，或者用<a class="bluekey" href="http://www.yesky.com/key/2319/42319.html" target="_blank">字符串转换</a>成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)年-月-日 24小时:分钟:秒 的格式YYYY-MM-DD HH24:MI:SS TO_DATE()还有很多种日期格式, 可以参看ORACLE DOC.日期型字段转换成字符串函数TO_CHAR(‘2001-08-01’,’YYYY-MM-DD HH24:MI:SS’)</p><p>　　日期字段的数学运算公式有很大的不同。MYSQL找到离当前时间7天用 DATE_FIELD_NAME &gt; SUBDATE(NOW()，INTERVAL 7 DAY)ORACLE找到离当前时间7天用 DATE_FIELD_NAME &gt;SYSDATE - 7;</p><p>　　6. 空字符的处理</p><p>　　MYSQL的非空字段也有空的内容，ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOT NULL来定义ORACLE表结构, 导数据的时候会产生错误。因此导数据时要对空字符进行判断，如果为NULL或空字符，需要把它改成一个空格的字符串。</p><p>　　7. 字符串的模糊比较</p><p>　　MYSQL里用 字段名 like '%字符串%',ORACLE里也可以用 字段名 like '%字符串%' 但这种方法不能使用索引, 速度不快，用字符串比较函数 instr(字段名,'字符串')&gt;0 会得到更精确的查找结果。</p><p>　　8. 程序和函数里，操作数据库的工作完成后请注意结果集和指针的释放。</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/30642.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-02-14 17:26 <a href="http://www.blogjava.net/TrampEagle/articles/30642.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle 10g SQL 优化再学习</title><link>http://www.blogjava.net/TrampEagle/articles/27899.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Fri, 13 Jan 2006 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27899.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27899.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27899.html</trackback:ping><description><![CDATA[引自：<a href="/calvin/archive/2005/11/11/19276.html">http://www.blogjava.net/calvin/archive/2005/11/11/19276.html</a><br /><br />从8i到10g，Oracle不断进化自己的SQL Tuning智能，一些秘籍级的优化口诀已经失效。<br />   但我喜欢失效，不用记口诀，操个<a href="http://www.quest.com/toad/"><font color="#366900">Toad for Oracle Xpert</font></a> ，按照大方向舒舒服服的调优才是爱做的事情。<br /><br /><strong>1.Excution Plan<br /></strong>     Excution Plan是最基本的调优概念，不管你的调优吹得如何天花乱堕，结果还是要由Excution plan来显示Oracle 最终用什么索引、按什么顺序连接各表，Full Table Scan还是Access by Rowid Index，瓶颈在什么地方。如果没有它的指导，一切调优都是蒙的。<br /><br /><br /><strong>2.Toad for Oracle Xpert</strong><br />    用它来调优在真的好舒服。<a href="http://www.quest.com/"><font color="#366900">Quest </font></a>吞并了Lecco后，将它整合到了Toad 的SQL Tunning里面：最清晰的执行计划显示，自动生成N条等价SQL、给出优化建议，不同SQL执行计划的对比，还有实际执行的逻辑读、物理读数据等等一目了然。<br /><br /><br /><strong>3.索引<br /></strong>   大部分的性能问题其实都是索引应用的问题，Where子句、Order By、Group By 都要用到索引。<br />   一般开发人员认为将索引建全了就可以下班回家了，实则还有颇多的思量和陷阱。<br /><br /><strong>3.1 索引列上不要进行计算</strong><br />      这是最最普遍的失效陷阱，比如where trunc(order_date)=trunc(sysdate), i+2&gt;4。索引失效的原因也简单，索引是针对原值建的二叉树，你将列值*3/4+2折腾一番后，原来的二叉树当然就用不上了。解决的方法:<br />　 1.　换成等价语法，比如trunc(order_date) 换成 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">where order_date</span><span style="COLOR: #808080">&gt;</span><span style="COLOR: #000000">trunc(sysdate)</span><span style="COLOR: #808080">-</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #808080">and</span><span style="COLOR: #000000"> order_date</span><span style="COLOR: #808080">&lt;</span><span style="COLOR: #000000">trunc(sysdate)</span><span style="COLOR: #808080">+</span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span></div><p>　 2.    特别为计算建立函数索引</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">create</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">index</span><span style="COLOR: #000000"> Ｉ_XXXX </span><span style="COLOR: #0000ff">on</span><span style="COLOR: #000000"> shop_order(trunc(order_date))</span></div><p>    3.    将计算从等号左边移到右边<br />　这是针对某些无心之失的纠正，把a*2&gt;4　改为a&gt;4/2；把TO_CHAR(zip) = '94002' 改为zip = TO_NUMBER('94002');<br /><br /><strong>3.2 CBO与索引选择性<br /></strong>     建了索引也不一定会被Oracle用的，就像个挑食的孩子。基于成本的优化器(CBO, Cost-Based Optimizer)，会先看看表的大小，还有索引的重复度，再决定用还是不用。表中有100 条记录而其中有80 个不重复的索引键值. 这个索引的选择性就是80/100 = 0.8，留意Toad里显示索引的Selective和Cardinailty。实在不听话时，就要用hints来调教。<br />     另外，where语句存在多条索引可用时，只会选择其中一条。所以索引也不是越多越好：）<br /><br /><strong>3.3 索引重建</strong><br />     传说中数据更新频繁导致有20%的碎片时，Oracle就会放弃这个索引。宁可信其有之下，应该时常alter index &lt;INDEXNAME&gt; rebuild一下。<br /><br /><strong>3.4 其他要注意的地方<br /></strong>      不要使用Not，如goods_no != 2，要改为</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">where</span><span style="COLOR: #000000"> goods_no</span><span style="COLOR: #808080">&gt;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span><span style="COLOR: #000000"> </span><span style="COLOR: #808080">and</span><span style="COLOR: #000000"> goods_no</span><span style="COLOR: #808080">&lt;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">2</span></div><p>      不要使用is null , 如WHERE DEPT_CODE IS NOT NULL 要改为</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">WHERE</span><span style="COLOR: #000000"> DEPT_CODE </span><span style="COLOR: #808080">&gt;=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">0</span><span style="COLOR: #000000">;</span></div><p><strong>3.5 select 的列如果全是索引列时<br /></strong>   又如果没有where 条件，或者where条件全部是索引列时，Oracle 将直接从索引里获取数据而不去读真实的数据表，这样子理论上会快很多，比如</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">select</span><span style="COLOR: #000000"> order_no,order_time </span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000"> shop_order </span><span style="COLOR: #0000ff">where</span><span style="COLOR: #000000"> shop_no</span><span style="COLOR: #808080">=</span><span style="FONT-WEIGHT: bold; COLOR: #800000">4</span></div><p>当order_no,order_time,shop_no 这三列全为索引列时，你将看到一个和平时完全不同的执行计划。<br /><br /><strong>3.6 位图索引<br /></strong>     传说中当数据值较少，比如某些表示分类、状态的列，应该建位图索引而不是普通的二叉树索引，否则效率低下。不过看执行计划，这些位图索引鲜有被Oracle临幸的。<br />  <br /></p><p><strong>4.减少查询往返和查询的表</strong><br />这也是很简单的大道理，程序与Oracle交互的成本极高，所以一个查询能完成的不要分开两次查，如果一个循环执行１万条查询的，怎么都快不到哪里去了。<br /><br /><strong>4.1 封装PL/SQL存储过程<br /></strong>　 最高级的做法是把循环的操作封装到PL/SQL写的存储过程里，因为存储过程都在服务端执行，所以没有数据往返的消耗。<br /></p><p><strong>4.2 封装PL/SQL内部函数<br /></strong>  有机会，将一些查询封装到函数里，而在普通SQL里使用这些函数，同样是很有效的优化。<br /><br /><strong>4.3 Decode/Case<br /></strong>　 但存储过程也麻烦，所以有case/decode把几条条件基本相同的重复查询合并为一条的用法：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">SELECT</span><span style="COLOR: #000000"><br /> </span><span style="COLOR: #ff00ff">COUNT</span><span style="COLOR: #000000">(</span><span style="COLOR: #ff00ff">CASE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">WHEN</span><span style="COLOR: #000000"> price </span><span style="COLOR: #808080">&lt;</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">13</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">THEN</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ELSE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">END</span><span style="COLOR: #000000">) low,<br /> </span><span style="COLOR: #ff00ff">COUNT</span><span style="COLOR: #000000">(</span><span style="COLOR: #ff00ff">CASE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">WHEN</span><span style="COLOR: #000000"> price </span><span style="COLOR: #808080">BETWEEN</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">13</span><span style="COLOR: #000000"> </span><span style="COLOR: #808080">AND</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">15</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">THEN</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ELSE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">END</span><span style="COLOR: #000000">) med,<br /> </span><span style="COLOR: #ff00ff">COUNT</span><span style="COLOR: #000000">(</span><span style="COLOR: #ff00ff">CASE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">WHEN</span><span style="COLOR: #000000"> price </span><span style="COLOR: #808080">&gt;</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">15</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">THEN</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ELSE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">END</span><span style="COLOR: #000000">) high<br /></span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> products;</span></div><p><strong>4.4 一种Where/Update语法</strong></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">SELECT</span><span style="COLOR: #000000"> TAB_NAME　</span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> TABLES<br /></span><span style="COLOR: #0000ff">WHERE</span><span style="COLOR: #000000"> (TAB_NAME,DB_VER) </span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"> （( </span><span style="COLOR: #0000ff">SELECT</span><span style="COLOR: #000000"> TAB_NAME,DB_VER)<br /></span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> TAB_COLUMNS </span><span style="COLOR: #0000ff">WHERE</span><span style="COLOR: #000000"> VERSION </span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #800000">604</span><span style="COLOR: #000000">)</span></div><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">UPDATE</span><span style="COLOR: #000000"> EMP<br /></span><span style="COLOR: #0000ff">SET</span><span style="COLOR: #000000"> (EMP_CAT, SAL_RANGE)<br /></span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">SELECT</span><span style="COLOR: #000000"> </span><span style="COLOR: #ff00ff">MAX</span><span style="COLOR: #000000">(CATEGORY)</span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> EMP_CATEGORIES)</span></div><p><strong><br />5.其他优化</strong><br /><strong>5.1RowID和ROWNUM</strong><br />     连Hibernate 新版也支持ROWID了，证明它非常有用。比如号称删除重复数据的最快写法：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">DELETE</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> EMP E<br /></span><span style="COLOR: #0000ff">WHERE</span><span style="COLOR: #000000"> E.ROWID </span><span style="COLOR: #808080">&gt;</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">SELECT</span><span style="COLOR: #000000"> </span><span style="COLOR: #ff00ff">MIN</span><span style="COLOR: #000000">(X.ROWID)<br /></span><span style="COLOR: #0000ff">FROM</span><span style="COLOR: #000000"> EMP X<br /></span><span style="COLOR: #0000ff">WHERE</span><span style="COLOR: #000000"> X.EMP_NO </span><span style="COLOR: #808080">=</span><span style="COLOR: #000000"> E.EMP_NO);</span></div><p> </p><p><strong>6.终极秘技 - </strong>Hints<br />   这是Oracle DBA的玩具，也是终极武器，比如Oracle在CBO,RBO中所做的选择总不合自己心水时，可以用它来强力调教一下Oracle，结果经常让人喜出望外。<br />   如果开发人员没那么多时间来专门学习它，可以依靠Toad SQL opmitzer 来自动生成这些提示，然后对比一下各种提示的实际效果。不过随着10g智能的进化，hints的惊喜少了。<br /><br /><strong>7. 找出要优化的Top SQL<br /></strong>    磨了这么久的枪，如果找不到敌人是件郁闷的事情。<br />    幸亏10g这方面做得非常好。进入Web管理界面，就能看到当前或者任意一天的SQL列表，按性能排序。<br />    有了它，SQL Trace和TKPROF都可以不用了。</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/27899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-13 12:44 <a href="http://www.blogjava.net/TrampEagle/articles/27899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Think in java(第14章: 创建窗口与Applet)</title><link>http://www.blogjava.net/TrampEagle/articles/27784.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 12 Jan 2006 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27784.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27784.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27784.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 14: 创建窗口与Applet设计的宗旨是"能轻松完成简单的任务，有办法完成复杂的任务"。[74]最初设计Java 1.0的GUI类库时，Sun的目标是，要让程序员能在所有平台下都能做出非常漂亮的界面。但是这个目标没能实现。相反用Java 1.0的Abstract Window Toolkit(AWT) 作出来的GUI，在所有平台上都显得那么平庸。而且它的功能也非常有限；只能用四种字体，不能访...&nbsp;&nbsp;<a href='http://www.blogjava.net/TrampEagle/articles/27784.html'>阅读全文</a><img src ="http://www.blogjava.net/TrampEagle/aggbug/27784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-12 16:51 <a href="http://www.blogjava.net/TrampEagle/articles/27784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle 游标使用大全</title><link>http://www.blogjava.net/TrampEagle/articles/27729.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Thu, 12 Jan 2006 04:50:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27729.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27729.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27729.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27729.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27729.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">引自：<A href="http://www.souzz.net/html/database/ORACLE/9467.html">http://www.souzz.net/html/database/ORACLE/9467.html</A><BR>发现这篇文章不全，待补充！<BR><BR><BR>查询</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>SELECT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句用于从<A href="http://www.souzz.net/html/database/" target=_blank>数据库</A>中查询数据，当在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句时，要与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">子句一起使用，查询的返回值被赋予</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">子句中的变量，变量的声明是在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DELCARE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语法如下：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SELECT [DISTICT|ALL]{*|column[,column,...]}<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>INTO (variable[,variable,...] |record)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>FROM {table|(sub-query)}[alias]<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>WHERE............<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句只返回一行数据。如果超过一行数据，那么就要使用显式游标（对游标的讨论我们将在后面进行），</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">子句中要有与</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">子句中相同列数量的变量。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">子句中也可以是记录变量。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman">%TYPE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">属性</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中可以将变量和常量声明为内建或用户定义的数据类型，以引用一个列名，同时继承他的数据类型和大小。这种动态赋值方法是非常有用的，比如变量引用的列的数据类型和大小改变了，如果使用了</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">%TYPE,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么用户就不必修改代码，否则就必须修改代码。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>v_empno SCOTT.EMP.EMPNO%TYPE;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>v_salary EMP.SALARY%TYPE;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">　不但列名可以使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">%TYPE,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">而且变量、游标、记录，或声明的常量都可以使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">%TYPE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这对于定义相同数据类型的变量非常有用。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>DELCARE<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>V_A NUMBER(5):=10;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>V_B V_A%TYPE:=15;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>V_C V_A%TYPE;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>BEGIN<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>DBMS_OUTPUT.PUT_LINE<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>('V_A='||V_A||'V_B='||V_B||'V_C='||V_C);<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>END<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman" color=#000000 size=2>&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>SQL&gt;/<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>V_A=10 V_B=15 V_C=<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>PL/SQL procedure successfully completed.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SQL&gt;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;</SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其他</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其它操作数据的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">:INSERT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">UPDATE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DELETE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">LOCK TABLE,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这些语句在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的语法与在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的语法相同。我们在前面已经讨论过</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句的使用这里就不再重复了。在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句中可以使用任何在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DECLARE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">部分声明的变量，如果是嵌套块，那么要注意变量的作用范围。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">　</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">AS<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>v_ename EMP.ENAME%TYPE;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>BEGIN<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">　</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT ename INTO v_ename<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>FROM emp<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>WHERE empno=p_empno;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>INSERT INTO FORMER_EMP(EMPNO,ENAME)<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>VALUES (p_empno,v_ename);<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>DELETE FROM emp<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>WHERE empno=p_empno;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>UPDATE former_emp<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SET date_deleted=SYSDATE<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>WHERE empno=p_empno;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman" color=#000000 size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>EXCEPTION<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>WHEN NO_DATA_FOUND THEN<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>DBMS_OUTPUT.PUT_LINE('Employee Number Not Found!');<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>END<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句的结果</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当执行一条</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句后，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句的结果保存在四个游标属性中，这些属性用于控制程序流程或者了解程序的状态。当运行</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句时，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开一个内建游标并处理结果，游标是维护查询结果的内存中的一个区域，游标在运行</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句时打开，完成后关闭。隐式游标只使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三个属性</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">.SQL%FOUND,SQL%NOTFOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是布尔值，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%ROWCOUNT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是整数值。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman">SQL%FOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%NOTFOUND<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在执行任何</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句前</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%FOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%NOTFOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值都是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">NULL,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在执行</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句后，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%FOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的属性值将是：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000>. TRUE :INSERT<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman">. TRUE :DELETE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">UPDATE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，至少有一行被</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DELETE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">UPDATE.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman">. TRUE :SELECT INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">至少返回一行</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%FOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">TRUE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">,SQL%NOTFOUND</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FALSE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000>SQL%ROWCOUNT<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在执行任何</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句之前，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%ROWCOUNT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值都是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">NULL,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>INTO</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句，如果执行成功，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%ROWCOUNT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">1,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有成功，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%ROWCOUNT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">0</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，同时产生一个异常</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">NO_DATA_FOUND.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000>SQL%ISOPEN<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp; </SPAN>SQL%ISOPEN</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个布尔值，如果游标打开，则为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">TRUE, </FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果游标关闭，则为</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FALSE.</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于隐式游标而言</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SQL%ISOPEN</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">总是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FALSE</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，这是因为隐式游标在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句执行时打开，结束时就立即关闭。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">事务控制语句</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">事务是一个工作的逻辑单元可以包括一个或多个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句，事物控制帮助用户保证数据的一致性。如果事务控制逻辑单元中的任何一个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">DML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句失败，那么整个事务都将回滚，在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中用户可以明确地使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">COMMIT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ROLLBACK</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SAVEPOINT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SET TRANSACTION</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>COMMIT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句终止事务，永久保存数据库的变化，同时释放所有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">LOCK,ROLLBACK</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">终止现行事务释放所有</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">LOCK</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，但不保存数据库的任何变化</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">,SAVEPOINT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于设置中间点，当事务调用过多的数据库操作时，中间点是非常有用的，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SET TRANSACTION</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于设置事务属性，比如</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">read-write</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和隔离级等。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显式游标</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当查询返回结果超过一行时，就需要一个显式游标，此时用户不能使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">select into</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">管理隐式游标，当查询开始时隐式游标打开，查询结束时隐式游标自动关闭。显式游标在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">块的声明部分声明，在执行部分或异常处理部分打开，取数据</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">,</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关闭。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用游标</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里要做一个声明，我们所说的游标通常是指显式游标，因此从现在起没有特别指明的情况，我们所说的游标都是指显式游标。要在程序中使用游标，必须首先声明游标。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">声明游标</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语法：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>CURSOR cursor_name IS select_statement;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">PL/SQL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中游标名是一个未声明变量，不能给游标名赋值或用于表达式中。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT color=#000000 size=2>&nbsp; </FONT>
<P><FONT color=#000000 size=2></FONT></P></FONT></SPAN>
<P><FONT color=#000000></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P><FONT color=#000000 size=2></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例：</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>DELCARE<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>CURSOR C_EMP IS SELECT empno,ename,salary<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>FROM emp<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>WHERE salary&gt;2000<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>ORDER BY ename;<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>........<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT face="Times New Roman"><FONT size=2><FONT color=#000000><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>BEGIN<SPAN style="mso-spacerun: yes">&nbsp; </SPAN></FONT></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><FONT color=#000000><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp;&nbsp;&nbsp; </FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在游标定义中</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">SELECT</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语句中不一定非要表可以是视图，也可以从多个表或视图中选择的列，甚至可以使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">*</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来选择所有的列</SPAN><FONT face="Times New Roman"> </FONT><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US><SPAN style="mso-spacerun: yes"><FONT face="Times New Roman">&nbsp; </FONT></SPAN></SPAN></FONT></FONT></P><img src ="http://www.blogjava.net/TrampEagle/aggbug/27729.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-12 12:50 <a href="http://www.blogjava.net/TrampEagle/articles/27729.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样Oracle中导入文本数据</title><link>http://www.blogjava.net/TrampEagle/articles/27637.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Wed, 11 Jan 2006 12:37:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27637.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27637.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27637.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27637.html</trackback:ping><description><![CDATA[引自：<a href="http://searchdatabase.techtarget.com.cn/askexperts/42/2190042.shtml?ticket=ST-89991-j5GGcHLOXTwhnPuSbYpa">http://searchdatabase.techtarget.com.cn/askexperts/42/2190042.shtml?ticket=ST-89991-j5GGcHLOXTwhnPuSbYpa</a><br /><br />具体的技术实现 
<p>　　<strong>一、Dos 环境下加载</strong></p><p>　　1、首先，服务器端的侦听服务必须已经开启。</p><p>　　测试方法:Dos 下输入</p><p>　　C:\&gt;<a class="bluekey" href="http://www.yesky.com/key/2682/102682.html" target="_blank">sqlplus</a> username/password@serviceName</p><p>　　2、然后使用 Oracle 的 sqlldr 命令进行数据的导入前期条件</p><p>　　1) Oracle 数据库端必须已经建好了需要导入的数据表的结构</p><p>　　2) 一个数据源文件 下面例子中为制表符分隔的文本文件 <a class="bluekey" href="http://www.yesky.com/key/2888/112888.html" target="_blank">model</a>.txt ,为Excel 表中导出的</p><p>　　3) 手工编辑一个<a class="bluekey" href="http://www.yesky.com/key/192/95192.html" target="_blank">XXX</a>.CTL 的控制文件</p><p>　　4) 命令行加载数据</p><p>　　如下实例:</p><p>　　以下文件缺省放到C:\ 下，如果不是，就需要指明全路径</p><p>　　1. 命令控制文件 input.ctl 内容</p><p>　　命令</p><p>　　说明</p><p>　　load data</p><p>　　1、控制文件标识</p><p>　　infile 'model.txt'</p><p>　　2、要输入的数据文件名为test.txt</p><p>　　append into table system.塔位属性表</p><p>　　3、向表test中追加记录</p><p>　　fields terminated by X'09'</p><p>　　4、指定分隔符，字段终止于X'09'，是一个制表符(TAB)</p><p>　　(编号,名称,大小)</p><p>　　5、定义列对应表中顺序</p><p>　　控制文件中指定插入数据的方式关键字</p><p>　　l insert，为缺省方式，在数据装载开始时要求表为空</p><p>　　l append，在表中追加新记录</p><p>　　l <a class="bluekey" href="http://www.yesky.com/key/186/105186.html" target="_blank">replace</a>，删除旧记录，替换成新装载的记录</p><p>　　l truncate，同上</p><p>　　在 Dos 窗口下使用 SQl*Loader 命令实现数据的导入</p><p>　　C:\&gt;sqlldr userid=system/manager@ serviceName <a class="bluekey" href="http://www.yesky.com/key/478/125478.html" target="_blank">control</a>=input.ctl</p><p>　　默认日志文件名为:input.log</p><p>　　默认坏记录文件为:input.bad</p><p>　　<strong>二、使用其它数据库转移工具</strong></p><p>　　以下以SQL Server 导入导出向导为例</p><p>　　1、在数据的导入导出向导中设置数据源服务器，实例中选择数据源选择SQL Server</p><p>　　2、然后指定要导入的Oracle 数据源</p><p>　　3、需要配置Oracle 的属性信息</p><p>　　需要注意的是，登录数据库的用户信息即为数据导入之后的方案名，即导入之后的SQL Server 中的表在Oracle 中标志名为 username.表名</p><p>　　以下按照提示即可，可以完全导入SQl Server 中的数据表和视图，也可以使用查询语句返回你要选择的列或者行。</p><p>　　<strong>三、Oracle 企业管理器中的数据加载功能</strong></p><p>　　登录Oracle 的控制台界面，针对单独的数据表可以使用数据加载工具</p><p>　　中间需要指定控制文件等，同Dos 加载一致，不再重复</p><img src ="http://www.blogjava.net/TrampEagle/aggbug/27637.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-11 20:37 <a href="http://www.blogjava.net/TrampEagle/articles/27637.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix SQL函数的详细用法</title><link>http://www.blogjava.net/TrampEagle/articles/27370.html</link><dc:creator>TrampEagle</dc:creator><author>TrampEagle</author><pubDate>Tue, 10 Jan 2006 05:23:00 GMT</pubDate><guid>http://www.blogjava.net/TrampEagle/articles/27370.html</guid><wfw:comment>http://www.blogjava.net/TrampEagle/comments/27370.html</wfw:comment><comments>http://www.blogjava.net/TrampEagle/articles/27370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/TrampEagle/comments/commentRss/27370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/TrampEagle/services/trackbacks/27370.html</trackback:ping><description><![CDATA[引自：<A href="http://blog.csdn.net/hxcfindjob/archive/2005/01/20/261679.aspx">http://blog.csdn.net/hxcfindjob/archive/2005/01/20/261679.aspx</A><BR><BR>
<P>Informix SQL函数的详细用法</P>
<P>一、内部函数 <BR>　 1、内部合计函数 <BR>　　　 1）COUNT（*）　　　　　　　　　　返回行数 <BR>　　　 2）COUNT（DISTINCT COLNAME）　　 返回指定列中唯一值的个数 <BR>　　　 3）SUM（COLNAME/EXPRESSION）　　 返回指定列或表达式的数值和； <BR>　　　 4）SUM（DISTINCT COLNAME）　　　 返回指定列中唯一值的和 <BR>　　　 5）AVG（COLNAME/EXPRESSION）　　 返回指定列或表达式中的数值平均值 <BR>　　　 6）AVG（DISTINCT COLNAME）　　　 返回指定列中唯一值的平均值 <BR>　　　 7）MIN（COLNAME/EXPRESSION）　　 返回指定列或表达式中的数值最小值 <BR>　　　 8）MAX（COLNAME/EXPRESSION）　　 返回指定列或表达式中的数值最大值 <BR>　 2、日期与时间函数 <BR>　　　 1）DAY（DATE/DATETIME EXPRESSION）　　　返回指定表达式中的当月几号 <BR>　　　 2）MONTH（DATE/DATETIME EXPRESSION）　　返回指定表达式中的月份 <BR>　　　 3）YEAR（DATE/DATETIME EXPRESSION）　　 返回指定表达式中的年份 <BR>　　　 4）WEEKDAY（DATE/DATETIME EXPRESSION）　返回指定表达式中的当周星期几 <BR>　　　 5）DATE（NOT DATE EXPRESSION）　　　　　返回指定表达式代表的日期值 <BR>　　　 6）TODAY　　　　　　　　　　　　　　　　返回当前日期的日期值 <BR>　　　 7）CURRENT[first to last]　　　　　　　 返回当前日期的日期时间值 <BR>　　　 8）COLNAME/EXPRESSION UNITS PRECISION　 返回指定精度的指定单位数 <BR>　　　 9）MDY（MONTH，DAY，YEAR）　　　　　　　返回标识指定年、月、日的日期值 <BR>　　　 10）DATETIME（DATE/DATETIME EXPRESSION）FIRST TO LAST 返回表达式代表的日期时间值 <BR>　　　 11）INTERVAL（DATE/DATETIME EXPRESSION）FIRST TO LAST 返回表达式代表的时间间隔值 <BR>　　　 12）EXTEND（DATE/DATETIME EXPRESSION，[first to last]）返回经过调整的日期或日期时间</P>
<P>值 </P>
<P>　　　 例子1、和UNITS合用，指定日期或时间单位(year,month,day,hour,minute,seond,fraction)： <BR>　　　　　　　let tmp_date = today + 3 UNITS day <BR>　　　 例子2、let tmp_date = MDY(10,30,2002)　　-- 2002-10-30 <BR>　　　 例子3、let tmp_date = today + interval(7) day to day　--当前时间加上7天； <BR>　　　　　　　注：该功能与1相似； <BR>　　　 例子4、EXTEND转换日期或日期时间值 <BR>　　　　　　　let tmp_inthour = extend(datetime1,hour to hour) </P>
<P>　 3、代数函数 <BR>　　　1）ABS(COLNAME/EXPRESSION)：　　　　　　 取绝对值 <BR>　　　2）MOD（COLNAME/EXPRESSION，DIVISOR）　　返回除以除数后的模（余数） <BR>　　　3）POW（COLNAME/EXPRESSION，EXPONENT）　 返回一个值的指数冥 <BR>　　　　 例子：let tmp_float = pow(2,3)　--8.00000000 </P>
<P>　　　4）ROOT（COLNAME/EXPRESSION，[index]）　 返回指定列或表达式的根值 </P>
<P>　　　5）SQRT（COLNAME/EXPRESSION）　　　　　　返回指定列或表达式的平方根值 </P>
<P>　　　6）ROUND（COLNAME/EXPRESSION，[factor]） 返回指定列或表达式的圆整化值 <BR>　　　7）TRUNC（COLNAME/EXPRESSION，[factor]） 返回指定列或表达式的截尾值 <BR>　　　　 说明：上两者中FACTOR指定小数位数，若不指定，则为0；若为负数，则整化到小数点左边； <BR>　　　　 注：ROUND是在指定位上进行4舍5入；TRUNC是在指定位上直接截断； <BR>　　　　　let tmp_float = round(4.555,2) --4.56 <BR>　　　　　let tmp_float = trunc(4.555,2) --4.55 </P>
<P>　 4、指数与对数函数 <BR>　　　1）EXP（COLNAME/EXPRESSION）　　　　返回指定列或表达式的指数值 <BR>　　　2）LOGN（COLNAME/EXPRESSION）　　　 返回指定列或表达式的自然对数值 <BR>　　　3）LOG10（COLNAME/EXPRESSION）　　　返回指定列或表达式的底数位10的对数值 </P>
<P>　 5、三角函数 <BR>　　　1）COS（RADIAN EXPRESSION）　　　　　返回指定弧度表达式的余弦值 <BR>　　　2）SIN（RADIAN EXPRESSION）　　　　　正弦 <BR>　　　3）TAN（RADIAN EXPRESSION）　　　　　正切 <BR>　　　4）ACOS（RADIAN EXPRESSION）　　　　 反余弦 <BR>　　　5）ASIN（RADIAN EXPRESSION）　　　　 反正弦 <BR>　　　6）ATAN（RADIAN EXPRESSION）　　　　 反正切 <BR>　　　7）ATAN2（X，Y）　　　　　　　　　　 返回坐标（X，Y）的极坐标角度组件 </P>
<P>　 6、统计函数 <BR>　　　1）RANGE（COLNAME）　　　 返回指定列的最大值与最小值之差 = MAX（COLNAME）-MIN</P>
<P>（COLNAME） <BR>　　　2）VARIANCE（COLNAME）　　返回指定列的样本方差； <BR>　　　3）STDEV（COLNAME）　　　 返回指定列的标准偏差； </P>
<P>　 7、其他函数 <BR>　　　1）USER　　　　　　　　　　　　　　返回当前用户名 <BR>　　　2）HEX（COLNAME/EXPRESSION）　　　 返回指定列或表达式的十六进制值 <BR>　　　3）LENGTH（COLNAME/EXPRESSION）　　返回指定字符列或表达式的长度 <BR>　　　4）TRIM（COLNAME/EXPRESSION）　　　删除指定列或表达式前后的字符 <BR>　　　5）COLNAME/EXPRESSION || COLNAME/EXPRESSION　返回并在一起的字符； </P>
<P>二、IDS内部函数 <BR>　 1、DBSERVERNAME　　　返回数据库服务器名　let tmp_char=DBSERVERNAME <BR>　 2、SITENAME　　　　　返回数据库服务器名　let tmp_char=SITENAME <BR>　　　说明：两者功能相同； </P>
<P>　 3、DBINFO（‘SPECIAL_KEYWORD')　　　返回只关键字值 <BR>　　　例子1：返回数据中每个表的DBSPACE名称 <BR>　　　　 select dbinfo('dbspace',partnum),tabname from systables <BR>　　　　　where tabid&gt;99 and tabtype='T'　(OK) <BR>　　　例子2：返回任何表中插入的最后一个SERIAL值 <BR>　　　　　select dbinfo('sqlca.sqlerrd1') from systables where tabid = 1 <BR>　　　例子3：返回最后一个SELECT，INSERT，UPDATE，DELETE或EXECUTE PROCEDURE语句处理的行数； <BR>　　　　　select dbinfo('sqlca.sqlerrd2') from systables where tabid=1; </P><img src ="http://www.blogjava.net/TrampEagle/aggbug/27370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/TrampEagle/" target="_blank">TrampEagle</a> 2006-01-10 13:23 <a href="http://www.blogjava.net/TrampEagle/articles/27370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>