|
2010年7月17日
1、http://www.jar114.com/site.html
该网站可以提供我们项目中经常需要的jar包,如果缺少包,就可以在这里查找。
流程定义文件*.jpdl.xml中如果有中文乱码,肯定是task中有中文。
需要在eclipse安装软件下,即E:\eclipse\eclipse.ini增加
-Dfile.encoding=UTF-8
然后重启eclipse即可解决。
配置jbpm4工程的运行环境:
1、添加依赖库。
E:\JBPM\jbpm-4.3\jbpm.jar
E:\JBPM\jbpm-4.3\lib下的jar包。
2、添加配置文件。
E:\JBPM\jbpm-4.3\examples\src下的配置文件拷贝到自己java工程的src下。
---------------------------------------------------------------
管理流程定义:发布流程定义、查看流程定义、删除流程定义。
RepositoryService repositoryService = processEngine.getRepositoryService();
String deploymentId = repositoryService.createDeployment().addResourceFromClasspath
("helloworld.jpdl.xml").deploy();
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
repositoryService.deleteDeploymentCascade(deploymentId);
---------------------------------------------------------------
管理流程实例:发起新流程、执行等待的流程、查看流程实例、终止流程实例、删除流程实例。
ExecutionService executionService = processEngine.getExecutionService();
ProcessInstance pi = executionService.startProcessInstanceByKey("helloworld");
ProcessInstance pi = executionService.signalExecutionById(pi.getId()); //执行等待的流程.
List<ProcessInstance> list = executionService.createProcessInstanceQuery().list();
executionService.endProcessInstance(pi.getId(), "cancel");
executionService.deleteProcessInstanceCascade(pi.getId());
TaskService taskService = processEngine.getTaskService();
taskService.completeTask(taskId, map);
控制流程的活动:Start、End、Decision、Fork、Join、Sub-process、State、task.
原子活动:java、script、sql、hql、email。
配置开发环境:
1、jbpm4:http://sourceforge.net/projects/jbpm/files/ 下选择jbpm-4.3.zip 137.9M
2、eclipse3.5版本以上 : http://www.eclipse.org/downloads/ 下选择 Eclipse IDE for Java EE 190M
3、GPD (Graphical Process Designer)插件,路径:E:\jbpm-4.3\install\src\gpd\jbpm-gpd-site.zip。
通过Eclipse-->help-->Install New Software-->Add-->Archive到插件所在路径。
java.lang.NullPointerException
at jxl.read.biff.File.<init>(File.java:77)
at jxl.Workbook.getWorkbook(Workbook.java:250)
at jxl.Workbook.getWorkbook(Workbook.java:235)
at org.drools.decisiontable.parser.xls.ExcelParser.parseFile(ExcelParser.java:76)
at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:89)
at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:68)
at com.sample.DecisionTableTest.readDecisionTable(DecisionTableTest.java:59)
at com.sample.DecisionTableTest.main(DecisionTableTest.java:36)
Drools调用readDecisionTable()方法里面一处为:
InputStream is = DecisionTableTest.class.getResourceAsStream("rules\\Sample.xls");
final String drl = converter.compile( is, InputType.XLS );
需改为如下,取的class即错误解决。
InputStream is = DecisionTableTest.class.getClassLoader().getResourceAsStream("rules\\Sample.xls");
final String drl = converter.compile( is, InputType.XLS );
org.mvel.CompileException: can not resolve identifier: 'declr'
at org.mvel.ASTNode.getReducedValue(ASTNode.java:315)
at org.mvel.ast.PropertyASTNode.getReducedValue(PropertyASTNode.java:29)
at org.mvel.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:103)
at org.mvel.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:51)
at org.mvel.TemplateInterpreter.execute(TemplateInterpreter.java:428)
at org.mvel.TemplateInterpreter.parse(TemplateInterpreter.java:320)
at org.drools.rule.builder.dialect.java.AbstractJavaBuilder.generatTemplates(AbstractJavaBuilder.java:113)
at org.drools.rule.builder.dialect.java.JavaConsequenceBuilder.build(JavaConsequenceBuilder.java:95)
at org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:67)
at org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:446)
at org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:304)
at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:167)
at com.sample.DecisionTableTest.readDecisionTable(DecisionTableTest.java:63)
at com.sample.DecisionTableTest.main(DecisionTableTest.java:36)
替换mvel.jar为mvel14-1.2.10.jar后不再报错,好像是jar包的问题。
看了下jar包里面的org.mvel.ASTNode.getReducedValue方法已经注释掉了。
WARNING: Wasn't able to correctly close stream for decision table. nulljava.lang.NullPointerException
at jxl.read.biff.File.<init>(File.java:77)
at jxl.Workbook.getWorkbook(Workbook.java:250)
at jxl.Workbook.getWorkbook(Workbook.java:235)
at org.drools.decisiontable.parser.xls.ExcelParser.parseFile(ExcelParser.java:76)
at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:89)
at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:68)
at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:110)
at com.sample.DecisionTableTest.readDecisionTable(DecisionTableTest.java:57)
at com.sample.DecisionTableTest.main(DecisionTableTest.java:35)
在web项目中的原先的写法为:
final String drl = converter.compile( "rules\\Sample.xls", InputType.XLS );
参考了下别人的写法,改为下面的方式进行处理:
InputStream is = DecisionTableTest.class.getClassLoader().getResourceAsStream("rules\\Sample.xls");
final String drl = converter.compile( is, InputType.XLS );
由于drools有新版本了,所以与MyEclipse整合进行了解下。
整合步骤如下:
1、下载MyEclipse 8.5;
2、在http://www.jboss.org/drools/downloads.html下载Drools Eclipse 3.5 Workbench 5.1 插件;
3、在E:\MyEclipse8.5下新建2个文件:links、myplugins。
E:\MyEclipse 8.5\links:放drools.link配置文件,内容为path=E:\\MyEclipse 8.5\\myplugins\\drools\\
E:\MyEclipse 8.5\myplugins:放drools文件,该E:\MyEclipse 8.5\myplugins\drools\eclipse下放置从网上下载的drools插件的features和plugins。
4、重启MyEclipse 8.5即可看见drools图标。
5、安装Jboss:下载jboss-5.0.0.GA,解压即可。
打开MyEclipse->window->Preference->MyEclipse->Servers->JBoss->JBoss 5.x进行jre及相关配置。
在命令行下运行java程序,出现如上异常Exception in thread "main" java.lang.UnsupportedClassVersionError。
主要是jdk的版本被oracle给换成低版本了。
可以在命令行下输入:javac -version 查看版本,最后把%JAVA_HOME%\bin;添加到Oracle之前,再重开启电脑,编译,运行即可。
可以查考:http://hi.baidu.com/tianxingacer/blog/item/e628b947ffc54f016a63e5ac.html/cmtid/1fe1e9ae1dc5b9f6faed50d9
我的机器以前装的是offices2003自带的js调试工具,昨天按照上IE8后,js调试工具有时候是ie8的调试界面,有时是ie6的调试界面,经网上查找已找到原因。
主要是我把IE8的‘脚本’下的“启动调试”给关了,所以最后只出现ie6的调试界面。
解决方法:打开IE8后,点击"工具"->"开发人员工具",或者快捷键F12,会打开页面调试窗口。
今天用反编译工具查看java源代码,发现反编译的java文件有错误,在网上了解了下,是原先开发人员对代码做了一下加密处理。下面介绍一下java的混淆器Proguard。
ProGuard 是一个免费的 Java类文件的压缩,优化,混肴器。它删除没有用的类,字段,方法与属性。使字节码最大程度地优化,使用简短且无意义的名字来重命名类、字段和方法 。eclipse已经把Proguard集成在一起了。
其他地方也有介绍,如下:http://blog.csdn.net/alex197963/archive/2008/07/07/2620603.aspx
1、当处理多个访问相同数据的用户时,通常可能出现三种问题:
脏读
当应用程序使用了被另一个应用程序修改过的数据,而这个数据处于未提交状态时,就会发生脏读。第二个应用程序随后会请求回滚被其修改的数据。第一个事务使用的数据就会被损坏,或者“变脏”。
不可重复的读
当一个事务获得了数据,而该数据随后被一个单独的事务所更改时,若第一个事务再次读取更改后的数据,就会发生不可重复的读。这样,第一个事务进行了一个不可重复的读。
虚读
当事务通过某种查询获取了数据,另一个事务修改了部分该数据,原来的事务第二次获取该数据时,就会发生虚读。第一个事务现在会有不同的结果集,它可能包含虚读。
2、Java.sql.Connection接口定义的隔离级别
TRANSACTION_NONE 说明不支持事务
TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化。这样脏读、不可重复的读和虚读都是允许的。
TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生。
TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、不可重复的读和虚读。
3、事务的隔离级别
在J2EE中,通过java.sql.Connection接口设置事务隔离级别,这一接口为连接的隔离级别提供了getter()和setter()
Int getTransactionIsolation() throws SQLException
void setTransactionIsolation() throws SQLException
Connection对象负责事务,一旦收到事务请求,事务将自动提交,因为Connection对象已定义为自动提交方式,可通过setAutoCommit(false)禁用自动提交模式
另外java.sql.DatabaseMetaData接口为数据存储提供支持的隔离级别查找方法:getTransactionIsolation(),supportsTransactionIsolationLevel()
对多个库操作的分布式事务必须在所有库中执行同一个隔离级别,否则会出现意想不到的结果
4、事务提交和回滚
为了完成提交事务和回滚事务,JDBC API包括了两个方法作为 Connection 接口的一部分。若将 Connection 对象名称指定为 con,通过调用 con.commit(); 可以保存程序状态;
通过调用 con.rollback(); 可以返回到以前保存的状态。如果数据库实际运行操作时有错误发生,这两个方法都会抛出 SQLExceptions,所以您需要在 try ... catch 块中包装它们。
5、批处理和事务
缺省情况下,JDBC 驱动程序运行在被称为自动提交的模式下,可禁用自动提交模式
con.setAutoCommit(false);
批处理操作中通过在一次单独的操作(或批处理)中执行多个数据库更新操作
{con.setAutoCommit(false) ;
Statement stmt = connection.createStatement() ; stmt.addBatch("INSERT INTO people VALUES('Joe Jackson', 0.325, 25, 105) ; stmt.addBatch("INSERT INTO people
VALUES('Jim Jackson', 0.349, 18, 99) ; stmt.addBatch("INSERT INTO people VALUES('Jack Jackson', 0.295, 15, 84) ;
int[] updateCounts = stmt.executeBatch() ; con.commit() ;
Initial Capacity:池的连接数量,在启动时创建
Maximun Capacity:这是池可以打开的连接的最大数量
Capacity Increment:成组地打开增量连接
Login Delay Seconds:池驱动程序在启动时打开每一个新的连接需要等待的时间
Refresh Period(刷新周期)
Supports Local Transaction:只用于XA连接池
Allow Shrinking and Shrink Period(允许收缩和收缩期):如果池的数量太大,超过了初始,且如果任何一个连接在收缩期内空闲,那么空闲的连接将在收缩期末关闭
监控JDBC连接池:
Waiters Hight字段指明了最多有多少客户等待数据库连接
Waiters字段告诉你当前有多少客户正在等待连接
Connections Hight字段给出最大的并发连接数。
Wait Seconds Hight字段显示了客户等待数据库连接的最长时间
1、连接:
直接连接(direct connection)
池连接(pooled connection)
连接复用 ,避免了数据库连接频繁建立、关闭的开销 ;
对JDBC中的原始连接进行了封装 ,隔离了应用的本身的处理逻辑和具体数据库访问逻辑 。
2、什么是连接池?
连接池是在Weblogic启动时候预先建立的数据库连接,由Weblogic在运行时负责维护。
可以减少程序每次数据库请求都要新创建数据库物理连接的时间及资源。
对数据库属性的更改只需通过控制台进行,不需改动客户端代码
MultiPool
可以使用MultiPool为高用户访问量提供数据库负载均衡,它使用简单的循环算法将连接请求平衡分配MultiPool中的每一个池。
多池的作用:为防数据库连接失败提供冗余,备份或高有效池;为高用户访问量提供数据库负载均衡,负载均衡池。
备份池:一个备份池由一个有顺序的连接池列表组成。
负载均衡池:使用简单的循环算法将连接请求平衡地分到在列表中的每一个池。
3、DataSource
数据源对应一个数据库连接池。客户程序可以通过数据源绑定的JNDI名字得到该数据源的引用,并通过数据源对象得到数据库连接。
JDBC的API:
java.sql.DriverManager
java.sql.Connection
java.sql.ResultSet
Javax.sql.RowSet:
javax.sql.Statement
java.sql.PreparedStatement:用于执行预编译的SQL语句
java.sql.CallableStatement:用于执行在数据库中定义的存储过程
Javax.sql.DataSource是java.sql.Connectioin对象的工厂并使用一个JNDI服务注册它.
1、Type 1类型驱动,JDBC-ODBC桥
通常运行Windows平台,需要在客户端安装ODBC驱动,早期Java访问数据库的主要方式,效率较低。
适用于快速的原型系统,没有提供JDBC驱动的数据库如Access ,由于包含多个驱动程序层,其性能一般不适合生产系统
Java-->JDBC-ODBC Bridge---->JDBC-ODBC Library--->ODBC Driver-->Database
驱动程序的类名称是 sun.jdbc.odbc.JdbcOdbcDriver
JDBC URL 的形式为 jdbc:odbc:dsn(dsn 是使用 ODBC 管理员注册数据库的数据源名称)
不是100%JAVA程序,与ODBC之间的接口采用非JAVA方式调用,因此不能在APPLET中使用
{
String url = "jdbc:odbc:jdbc" ;
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url, "java", "sun");
}
2、Type 2类型驱动,需要在客户端安装数据库的本地驱动,JDBC请求会转换为对数据库本地API的调用。
利用开发商提供的本地库来直接与数据库通信。
Java-->JDBC-Driver-->DB Client Library-->Database
绕过了ODBC层,性能优于Type1
也称为部分 Java 驱动程序,因为它们直接将 JDBC API 翻译成具体数据库的API
使用第二种模型将开发者限制在数据库厂商的客户机库支持的客户机平台和操作系统
Oracle的OCI驱动就属于Type2
3、Type 3类型驱动,DBC请求通过网络服务器层实现,在网络服务器层可以实现负载均衡,连接池管理等。
第三种驱动程序是纯 Java 驱动程序,它将 JDBC API 转换成独立于数据库的协议。JDBC 驱动程序并没有直接和数据库进行通讯;它和一个中间件服务器通讯,然后这个中间件服务器和数据库进行通讯。这种额外的中间层次提供了灵活性:可以用相同的代码访问不同的数据库,因为中间件服务器隐藏了 Java 应用程序的细节。要转到不同的数据库,您只需在中间件服务器上改变参数。(有一点需要注意:中间件服务器必须支持您访问的数据库格式。)
第三种驱动程序的缺点是,额外的中间层次可能有损整体系统性能。另一方面,如果应用程序需要和不同的数据库格式进行交互,第三种驱动程序是个有效的方法,因为不管底层的数据库是什么,都使用同样的 JDBC 驱动程序。另外,因为中间件服务器可以安装在专门的硬件平台上,可以利用总的结果进行一些优化。
Java--->Jdbc Driver(Type3 jdbc driver)----->java middleware--->JDBC Driver---->Database
Weblogic的Pool驱动程序就是一个Type3的JDBC驱动程序。
4、Type 4类型驱动,为纯Java实现,不需要任何客户端设置。
OCI驱动程序利用Java本地化接口(JNI),通过Oracle客户端软件与数据库进行通讯。Thin驱动程序是纯Java驱动程序,它直接与数据库进行通讯。
JDBC应用的两种架构
两层架构:客户程序直接对数据库发起JDBC请求,Type1、2、4支持两层架构。
多层架构:客户程序将JDBC请求发送到中间层,中间层再将请求发送到数据库。
通常应用系统会根据用户数、并发数、用户的行为等等来确定具体的性能目标,如果确定应用程序不能满足性能目标,那么就需要优化、重构程序并调整JVM、应用服务器、数据库、OS 或者改变硬件配置等等。
影响Java 性能的主要因素:
硬件,如CPU、内存、体系结构等等
操作系统
数据库系统
JVM
应用服务器
数据库服务器
网络环境
应用架构及程序编写水平
性能调整的步骤:
1、 使用工具测试系统是否满足性能目标
2、 发现性能瓶颈
3、 假设瓶颈的原因
4、 测试你的假设
5、 如果假设成立,更改这一部分
6、 测试确定更改是否可以提高性能,衡量性能提高的程度
7、重复以上步骤,直到获得可以接受的性能。
J2EE性能不好时的现象,主要表现在对客户端的请求响应很慢:
一向很慢:应用的响应总是很慢,改变环境(如应用负载、数据库的连接池数量等等),对响应时间的影响不大。
越来越慢:在相同的负载情况下,随着系统运行的时间的增长,系统越来越慢,这可能是系统已到达极限或是系统死锁和错误引起的。
低于负载时会越来越慢(Slower and slower under load):.
偶尔的挂起或异常错误(Sporadic hangs or aberrant errors):有时这可能是由于负载的变化或其他情况引起的可以预测的死锁(Foreseeable lock ups): 挂起或最初只有少量错误,但随着时间的推移整个系统都锁上了,典型地这可能是为的适应"management by restarts.“
突发性的混乱(Sudden chaos): 系统已运行了一段时间(如一个小时或可能是三、四天),性能稳定并可以接受, 突然没有任何理由,开始出错或死锁了。
监控工具:
WebLogic Server的控制台
cpu
内存
JDBC
辅助的工具
Jprobe
Optimizit
Vtune
TowerJ Performance
WebLogic Server 10的下载地址:
http://www.oracle.com/technology/software/products/ias/htdocs/wls_main.html
1、域(Domains)
域是管理的单元或边界;
作为一个单元来管理的,并相互关联的一组Weblogic 服务器资源被称为域;
域由单一的管理服务器来管理。
2、机器(Machines)
可以对应到服务器所在的物理硬件;
可以是Unix或non-Unix类型;
可以用来远程管理和监控;
3、服务器(Servers)
服务器是执行在单一Java虚拟机 (JVM)中weblogic.Server类的实例。
服务器:最多和一个WLS机器关联;占用一定数量的RAM ;是多线程的。
4、管理服务器(Administration server)
对整个域的集中控制
XML配置存储库的保存者
日志信息的集中保存
5、被管理服务器(Managed Server)
WebLogicServer的一个实例;
从管理服务器远程加载配置信息‘;
可以是也可以不是集群的一部分。
6、集群 (Clustering)
WebLogic集群技术指通过一组服务器共同 工作,在多台机器间复制应用表示层和应用逻辑层的能力,实现关键业务系统的负载分布,消除个别故障点;集群用来实现负载均衡和容错。
1、J2EE应用开发的核心组件。
Servlet: 处理HTTP请求,产生响应。
JSP:Java Server Pages ,同Servlet。其中包含了HTML和JSP标签、Java代码和其他信息。
EJB:EJB服务端组件模型简化了具有交互性、扩展性和移植性中间组件的开发。EJB一般用于实现系统的业务逻辑。
2、J2EE的相关技术
核心:Servlet 、JSP、EJB
数据库:JDBC
命名和目录服务:JNDI
消息服务:JMS( Java Message Service )
Email:Java Mail
分布式计算:RMI、RMI-IIOP
事务:JTA(Java Transaction API)
数据格式化:XML、HTML、XSL
协议:TCP/IP、HTTP(S)、IIOP、SSL
安全:JAAS
3、J2EE的4层结构
客户层(浏览器)
Web层(HTML、Servlet、JSP)
业务层(EJB)
EIS层(关系数据库)
4、J2EE的Application Server:
Tomcat
BEA Weblogic
IBM Websphere
Oracle Application Server
Sun Java System
Jboss
Borland AppServer
Sybase Application Server
HP Application Server
Apusic
5、集成开发工具:
Borland:JBuilder
Oracle :JDeveloper
Bea :WebLogic Workshop
IBM:Websphere Studio
Sun:NetBeans
MyEclipse
在小型的应用系统或者有特殊需要的系统中,可以使用一个免费的Web服务器Tomcat,该服务器支持全部JSP以及Servlet规范,但是目前还不支持EJB。
在Java相关的开发领域中,常用的是3种数据库:Oracle、DB2和MySQL。有时候也使用微软公司的SQL Server数据库服务器 。
DateUtils.compareYear(regDate, base.getTInsrncBgnTm()) // 新旧车标志【保险起期 - 初登年月】 单位:年
//显示输入框录入的字符位数。 ztf 10.07.19
function displayLength(obj) {
var lenSpan = document.getElementById("lenSpan");
if (lenSpan == null) {
lenSpan = document.createElement("SPAN");
lenSpan.id = "lenSpan";
obj.parentNode.appendChild(lenSpan);
}
lenSpan.innerText = "已输入" + obj.value.length + "位";
}
onkeyup="displayLength(this)"进行js调用。
--情况1:多个参数的传递,由于多个文件编码不一致,可能出现乱码。
window.open(base+"/policy/universal/pop/flat_vhl_inf_query.jsp?
cLcnNo="+objPlateNo.value+"&cEngNo="+objEngNo.value+"&cVhlFrm="+objFrmNo.value+"&cPlateTy
p="+objPlateTyp+"&cProdNo="+objCProdNo+"&cDptCde="+objCDptCde+"&cNewMrk="+objNewMrk.value
+"&cEcdemicMrk="+objEcdemicMrk.value,"","scrollbars=yes,left=100,top=150,Toolbar=no,Locat
ion=no,Direction=no,Resizeable=no,Width="+800+" ,Height="+400);
--相应的jsp获得参数
<%
String CProdNo = request.getParameter("prodNo");
String CDptCde = request.getParameter("dptCde");
String CPlateNo = request.getParameter("plateNo");
String CFrmNo = request.getParameter("frmNo");
if("".equals(CPlateNo)&&"".equals(CFrmNo)){
return;
}
String dwName = "policy.pub.flat_vhl_inf_DW";
%>
--情况2:解决乱码的问题。
function tool_uploadFile(clmNo,billType,maxFileNum,fileType,singleLimit,totalLimit) {//解决乱码的问题,增加变量paramObj。ztf 10.06.01
var paramObj = {
"clmNo" : clmNo,
"billType" : billType,
"maxFileNum" : maxFileNum,
"fileType" : fileType,
"singleLimit" : singleLimit,
"totalLimit" : totalLimit
};
var r = window.showModalDialog(global.WEB_APP_NAME+"/core/jsp/common/uploadFile.jsp",paramObj,"dialogHeight:610px;dialogWidth:530px;center:1;help: 0; status: 0;");
return r;
}
--在相应的jsp页面通过js获得参数:
<html>
<head>
<title>文件上传</title>
</head>
<script type="text/javascript" src="<%=webApp%>/core/js/core/Tool.js"></script>
<body bgcolor="#85b7ec">
<script>
var paramObj = window.dialogArguments;
var clmNo = paramObj.clmNo;
var billType = paramObj.billType;
var maxFileNum = paramObj.maxFileNum;
var fileType = paramObj.fileType;
var singleLimit = paramObj.singleLimit;
var totalLimit = paramObj.totalLimit;
tool.loadApplet('<%=agentIp%>','<%=agentPort%>','<%=orgId%>',clmNo,billType,maxFileNum,fileType,singleLimit,totalLimit);
</script>
</body>
</html>
vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])
1、具体业务中用到的sql,这个是查找最近标志为1,且有多条记录的数据。 (这个sql查找错误比较有用。)
select a.c_ply_no ,count(1) from web_ply_base a
where a.c_latest_mrk='1'
group by a.c_ply_no
having count(1)>1
背景count(*) count(1) 两者比较,主要还是要count(1)所相对应的数据字段:
如果你的数据表没有主键,那么count(1)比count(*)快
如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快
如果你的表只有一个字段的话那count(*)就是最快的啦
如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。
因为count(*),自动会优化指定到那一个字段。所以没必要去count(?),用count(*),sql会帮你完成优化的.
其他语句:select * from 表名 where 条件 order by 字段名 asc\desc // asc 升序 desc 降序
2、C_Nme_En匹配多个 like 查询。
select distinct C_Spec_No
from WEB_Prd_Fix_Spec
WHERE C_Spec_No in (SELECT C_Spec_No
FROM web_Prd_Prod_Spec_Rel
WHERE C_Prod_No = '0326'
and C_Spec_No like '89%')
and (C_Nme_En like '%000000%' or C_Nme_En like '%030006%' or
C_Nme_En like '%030061%')
--递归,树状结构的存储与展示
drop table article;
create table article
(
id number primary key,
count varchar2(4000),
pid number,
isleaf number(1), --0 代表非叶子节点,1代表叶子节点
alevel number(2)
);
insert into article values(1,'蚂蚁大战大象',0,0,0);
insert into article values(2,'大象被打趴下',1,0,1);
insert into article values(3,'蚂蚁也不好过',2,1,2);
insert into article values(4,'瞎说',2,0,2);
insert into article values(5,'没有瞎说',4,1,3);
insert into article values(6,'怎么可能',1,0,1);
insert into article values(7,'怎么没有可能',6,1,2);
insert into article values(8,'可能性是很大的',6,1,2);
insert into article values(9,'大象进医院了',2,0,2);
insert into article values(10,'护士是蚂蚁',9,1,3);
commit;
蚂蚁大战大象
大象被打趴下了
蚂蚁也不好过
瞎说
没有瞎说
大象进医院了
护士是蚂蚁
怎么可能
怎么没有可能
可能性是很大的
--用存储过程展现树状结构。
create or replace procedure p(v_pid article.pid%type,v_level binary_integer) is
cursor c is select * from article where pid = v_pid;
v_preStr varchar2(1024) := '';
begin
for i in 0..v_level loop
v_preStr := v_preStr || '****';
end loop;
for v_article in c loop
dbms_output.put_line(v_preStr ||v_article.cont);
if(v_article.isleaf=0) then
p(v_artile.id,v_levle +1);
end if;
end loop;
end;
--触发器
create table emp2_log
(
uname varchar2(20);
action varchar2(10);
atime date
);
create or replace trigger trig
after insert or delete or update on emp2 for each row
begin
if inserting then
insert into emp2_log values (USER,'insert',sysdate); --USER关键字,用户。
elsif updating then
insert into emp2_log values (USER,'update',sysdate);
elsif deleting then
insert into emp2_log values (USER,'delete',sysdate);
end if;
end;
update emp2 set sal = sal*2 where deptno = 30;
select * from emp2_log;
drop trigger trig;
--直接执行时,出现违反完整约束条件,已找到子记录。
update dept set deptno = 99 where deptno = 10;
--使用下面的,把子表一起更新。
create or replace trigger trig
after update on dept for each row
begin
update emp set deptno =:NEW.deptno where deptno =:OLD.deptno;
end;
update dept set deptno = 99 where deptno = 10;
select * from emp;
rollback;
--函数
create or replace function sal_tax
(v_sal number)
return number
is
begin
if(v_sal < 2000) then
return 0.10;
elsif(v_sal < 2750) then
return 0.15;
else
return 0.20;
end if;
end;
数据库定义的函数money_to_chinese ,把数字转换正中文输出。
create or replace function money_to_chinese(money in VARCHAR2)
return varchar2 is
c_money VARCHAR2(12);
m_string VARCHAR2(60) := '分角圆拾佰仟万拾佰仟亿';
n_string VARCHAR2(40) := '壹贰叁肆伍陆柒捌玖';
b_string VARCHAR2(80);
n CHAR;
len NUMBER(3);
i NUMBER(3);
tmp NUMBER(12);
is_zero BOOLEAN;
z_count NUMBER(3);
l_money NUMBER;
l_sign VARCHAR2(10);
BEGIN
l_money := abs(money);
IF money < 0 THEN
l_sign := '负' ;
ELSE
l_sign := '';
END IF;
tmp := round(l_money, 2) * 100;
c_money := rtrim(ltrim(to_char(tmp, '999999999999')));
len := length(c_money);
is_zero := TRUE;
z_count := 0;
i := 0;
WHILE i < len LOOP
i := i + 1;
n := substr(c_money, i, 1);
IF n = '0' THEN
IF len - i = 6 OR len - i = 2 OR len = i THEN
IF is_zero THEN
b_string := substr(b_string, 1, length(b_string) - 1);
is_zero := FALSE;
END IF;
IF len - i = 6 THEN
b_string := b_string || '万';
END IF;
IF len - i = 2 THEN
b_string := b_string || '圆';
END IF;
IF len = i THEN
IF (len = 1) THEN
b_string := '零圆整';
ELSE
b_string := b_string || '整';
END IF;
END IF;
z_count := 0;
ELSE
IF z_count = 0 THEN
b_string := b_string || '零';
is_zero := TRUE;
END IF;
z_count := z_count + 1;
END IF;
ELSE
b_string := b_string || substr(n_string, to_number(n), 1) ||
substr(m_string, len - i + 1, 1);
z_count := 0;
is_zero := FALSE;
END IF;
END LOOP;
b_string := l_sign || b_string ;
RETURN b_string;
exception
--异常处理
WHEN OTHERS THEN
RETURN(SQLERRM);
END;
--创建存储过程:
create or replace procedure p
is
cursor c is
select * from emp2 for update;
begin
for v_temp in c loop
if(v_temp.deptno = 10) then
update emp2 set sal = sal+10 where current of c;
elsif(v_temp.deptno = 20) then
update emp2 set sal = sal+20 where current of c;
else
update emp2 set sal = sal+50 where current of c;
end if;
end loop;
commit;
end;
--执行:
exec p;
begin
p;
end;
--带参数的存储过程,in传入参数,默认为传入,out传出。
create or replace procedure p
(v_a in number,v_b number,v_ret out number,v_temp in out number)
is
begin
if(v_a >v_b) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp :=v_temp +1;
end;
declare
v_a number := 3;
v_b number := 4;
v_ret number;
v_temp number := 5;
begin
p(v_a,v_b,v_ret,v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
--游标
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
exit when(c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
declare
cursor c is
select * from emp;
v_emp emp%rowtype;
begin
open c;
fetch c into v_emp;
while(c%found) loop
dbms_output.put_line(v_emp.ename);
fetch c into v_emp;
--fetch c into v_emp; 导致第一条没有打印,最后一条打印2遍。
--dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
declare
cursor c is
select * from emp;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
--带参数的游标
declare
cursor c(v_deptno emp.deptno%type,v_job emp.job%type)
is
select ename,sal from emp where deptno =v_deptno and job= v_job;
--v_temp c%rowtype;
begin
for v_temp in c(30,'CLERK') loop --for自动打开游标。
dbms_output.put_line(v_temp.ename);
end loop;
end;
--可更新的游标
declare
cursor c
is
select * from emp2 for update;
--v_temp c%rowtype;
begin
for v_temp in c loop
if(v_temp.sal <2000) then
update emp2 set sal = sal*2 where current of c;
elsif(v_temp.sal = 5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
PLSql是SQL的补充,PL过程语言procedure language,SQL:Structured Query Language。
PLSql 带有分支、循环的语言,SQL没有分支、循环的语言。
set serveroutput on;
-- 简单的PL/SQL语句块
declare
v_name varchar2(20);
begin
v_name :='myname';
dbms_output.put_line(v_name);
end;
/
--语句块的组成
declare
v_num number := 0 ;
begin
v_num := 2/v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line('error');
end;
/
--变量声明的规则
1、变量名不能够使用保留字,如from、select等
2、第一个字符必须是字母
3、变量名最多包含30个字符
4、不要与数据库的表或者列同名
5、每一行只能声明一个变量
--常用变量类型
1、binary_integer:整数,主要用来计数而不是用来表示字段类型
2、number:数字类型
3、char:定长字符串
4、varchar2:变长字符串
5、date:日期
6、long:长字符串,最长2GB
7、boolean:布尔类型,可以取值true、false和null值
--变量声明
declare
v_temp number(1);
v_count binary_integer :=0;
v_sal number(7,2):= 4000.00;
v_date date:= sysdate;
v_pi constant number(3,2) := 3.14; --constant相当java的final常量
v_valid boolean := false;
v_name varchar2(20) not null :='MyName';
begin
dbms_output.put_line('v_temp value:'|| v_temp);
end;
--变量声明,使用%type属性
declare
v_empno number(4);
v_empno2 emp.empno%type;
v_empno3 v_empno2%type;
begin
dbms_output.put_line('Test');
end;
--简单变量赋值
declare
v_name varchar2(20);
v_sal number(7,2);
v_sal2 number(7,2);
v_valid boolean :=false;
v_date date;
begin
va_name :='MyName';
v_sal :=23.77;
v_sal2 :=23.77;
v_valid:=(v_sal = v_sal2);
v_date:=to_date('1999-08-12 12:23:38','YYYY-MM-DD HH24:MI:SS');
end;
--Table变量类型,定义一种新的类型,是数组。
declare
type type_table_emp_empno is table of emp.empno%type index by binary_integer;
v_empno type_table_emp_empno;
begin
v_empnos(0) := 7369;
v_empnos(2) := 7839;
v_empnos(-1) := 9999;
dbms_output.put_line(v_empnos(-1));
end;
--Record变量类型,类似java的类的概念。
declare
type type_record_dept is record
(
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
);
v_tmp type_record_dept;
begin
v_tmp.deptno := 50;
v_tmp.dname := 'aaaa';
v_tmp.loc := 'bj';
dbms_output.put_line(v_temp.deptno||''||v_temp.dname);
end;
--使用%rowtype声明Record变量
declare
v_temp dept%rowtype;
begin
v_tmp.deptno := 50;
v_tmp.dname := 'aaaa';
v_tmp.loc := 'bj';
dbms_output.put_line(v_temp.deptno||''||v_temp.dname);
end;
--SQL语句的运用,返回数据有且只有一条记录。
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno = 7369;
dbms_output.put_line(v_ename||''||v_sal);
end;
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = 7369;
dbms_output.put_line(v_emp.ename);
end;
declare
v_deptno dept.deptno%type := 50;
v_dname dept.dname%type := 'aaaa';
v_loc dept.loc%type := 'bj';
begin
insert into dept2 values (v_deptno,v_dname,v_loc);
commit;
end;
declare
v_deptno emp2.deptno%type := 10;
v_count number ;
begin
--update emp2 set sal = sal/2 where deptno = v_deptno;
--select deptno into v_deptno from emp2 where empno = 7369;
select count(*) into v_count from emp2;
dbms_output.put_line(sql%rowcount||'条记录被影响');
commit;
end;
DDL语句:
begin
execute immediate 'create table T(nnn varchar2(20) default ''aaa'')';
end;
--if语句:取出7369的薪水,如果<1200,则输出'low',如果<2000则输出'middle',否则'high'
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 7369;
if(v_sal < 1200) then
dbms_output.put_line('low');
elsif(v_sal < 2000) then
dbms_output.put_line('middle');
else
dbms_output.put_line('high');
end if;
end;
--循环
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i+ 1;
exit when (i >= 11);
end loop;
end;
declare
j binary_integer := 1;
begin
while j< 11 loop
dbms_output.put_line(j);
j := j+ 1;
end loop;
end;
begin
for k in 1..10 loop
dbms_output.put_line(k);
end loop;
for k in reverse 1..10 loop
dbms_output.put_line(k);
end loop;
end;
--错误处理
declare
v_temp number(4);
begin
select empno into v_temp from emp where deptno = 10;
exception
when too_many_rows then
dbms_output.put_line('太多记录了');
when others then
dbms_output.put_line('error');
end;
declare
v_temp number(4);
begin
select empno into v_temp from emp where empno = 2222;
exception
when no_data_found then
dbms_output.put_line('没数据');
end;
create table errorlog
(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
);
create sequence seq_errorlog_id start with 1 increment by 1;
declare
v_deptno dept.deptno%type := 10;
v_errmsg varchar2(1024);
begin
delete from dept where deptno = v_deptno;
commit;
exception
when others then
rollback;
v_errcode := SQLCODE; --关键字,代表出错的代码。
v_errmsg := SQLERRM;
insert into errorlog values (seq_errorlog_id.nextval,v_errcode,v_errmsg,sysdate);
commit;
end;
构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。关系数据库中的关系必须满足一定的要求,即满足不同的范式。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF)和第六范式(6NF)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。
第一范式(1NF):无重复的列。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。
数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
第二范式(2NF):属性完全依赖于主键[消除部分子函数依赖]。
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。例如员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是属性完全依赖于主键。
第三范式(3NF):属性不依赖于其它非主属性[消除传递依赖]。
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。
所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。
序列:sequence,产生一个独一无二的序列,是oracle特有的。
create table article
(
id number,
title varchar2(1024),
cont long
);
insert into article values(seq.nextval,'a','b');
select * from user_sequences; --查询序列
create sequence seq; --创建序列seq对象
select seq.nextval from dual;
drop sequence seq;
视图:一个虚表,也是一个子查询,是存储在数据字典里的一条select语句。
视图:基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改,视图基于的表称为基表。
视图的优点:
1、对数据库的访问,可以有选择性的选取数据库里的一部分信息,整张表的信息不对外开放。2.用户通过简单的查询可以从复杂查询中得到结果。
视图的缺点:
如果一个表的结构改了,相应的视图如果用到了该表的字段,也要进行修改,增加维护工作量。
简单视图:只从单表里获取数据,不包含函数和数据组,可以实现DML操作。
复杂视图:从多表获取数据,包含函数和数据组,不可以DML操作。
视图的创建:
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name
[(alias[, alias]...)]
AS subquery
[WITH CHECK OPTION [CONSTRAINT constraint]]
[WITH READ ONLY]
其中:
OR REPLACE:若所创建的试图已经存在,ORACLE自动重建该视图;
FORCE:不管基表是否存在ORACLE都会自动创建该视图;
NOFORCE:只有基表都存在ORACLE才会创建该视图:
alias:为视图产生的列定义的别名;
subquery:一条完整的SELECT语句,可以在该语句中定义别名;
WITH CHECK OPTION :插入或修改的数据行必须满足视图定义的约束;
WITH READ ONLY :该视图上不能进行任何DML操作。
例如:
CREATE OR REPLACE VIEW dept_sum_vw
(name,minsal,maxsal,avgsal)
AS SELECT d.dname,min(e.sal),max(e.sal),avg(e.sal)
FROM emp e,dept d
WHERE e.deptno=d.deptno
GROUP BY d.dname;
查询视图:select * from user_views;
修改视图:通过OR REPLACE 重新创建同名视图即可。
删除视图:DROP VIEW VIEW_NAME;
视图的定义原则:
1.视图的查询可以使用复杂的SELECT语法,包括连接/分组查询和子查询;
2.在没有WITH CHECK OPTION和 READ ONLY 的情况下,查询中不能使用ORDER BY 子句;
3.如果没有为CHECK OPTION约束命名,系统会自动为之命名,形式为SYS_Cn;
4.OR REPLACE选项可以不删除原视图便可更改其定义并重建,或重新授予对象权限。
视图上的DML操作,应遵循的原则:
1.简单视图可以执行DML操作;
2.在视图包含GROUP 函数,GROUP BY子句,DISTINCT关键字时不能删除数据行;
3.在视图不出现下列情况时可通过视图修改基表数据或插入数据:
a.视图中包含GROUP 函数,GROUP BY子句,DISTINCT关键字;
b.使用表达式定义的列;
c .ROWNUM伪列。
d.基表中未在视图中选择的其他列定义为非空且无默认值。
WITH CHECK OPTION 子句限定:
通过视图执行的INSERTS和UPDATES操作不能创建该视图检索不到的数据行,因为它会对插入或修改的数据行执行完整性约束和数据有效性检查。
例如:
CREATE OR REPLACE VIEW vw_emp20
AS SELECT * FROM emp
WHERE deptno=20
WITH CHECK OPTION constraint vw_emp20_ck;
视图 已建立。
查询结果:
SELECT empno,ename,job FROM vw_emp20;
EMPNO ENAME JOB
--------------------- -------------- -------------
7369 SMITH CLERK
7566 JONES MANAGER
7902 FORD ANALYST
修改:
UPDATE vw_emp20
SET deptno=20
WHERE empno=7902;
将产生错误:
UPDATE vw_emp20
*
ERROR 位于第一行:
ORA-01402:视图WITH CHECK OPTION 违反WHERE 子句
索引:--像字典里面的索引。
表建立索引后在插入数据时,一要把数据写入表里,二要把该数据记入索引里面,因此查询效率高、但插入效率低。
create index idx_stu_email on stu(email,class); --组合索引,查询效率高。
drop index idx_stu_email;
select * from user_indexes; -- 查询索引
Oracle的数据库对象分为五种:表,视图,序列,索引和同义词。
select * from user_tables -- 当前用户下有多少张表
select * from user_views -- 当前用户下有多少张视图
select * from user_sequences; --查询序列
select * from user_indexes; -- 查询索引
select * from user_constraints -- 当前用户下有多少约束
select * from dictionary --数据字典表的表
DDL(data definition language):DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。
数据类型:VARCHAR2(50)最大4K(4096字节)、CHAR(1)最大2k、NUMBER(10,6)、NUMBER(6)、DATE、
LONG 变长字符串,最大长度达2G。
约束条件有5个:非空、唯一、主键、外键、check。
create table stu
(
id number(6), --primary key
name varchar2(20) constraint stu_name_nn not null, --stu_name_nn别名
sex number(1),
age number(3),
sdate date,
grade number(2) default 1,
class number(4), --references class(id)
email varchar2(50),
--email varchar2(50) unique --字段级约束,不能有重复值
constraint stu_name_email_uni unique(name,email), --表级约束
constraint stu_id_pk primary key(id), --表级约束
constraint stu_class_fk foreign key(class) references class(id) --被参考字段必须是主键
);
create table class
(
id number(4) primary key,
name varchar2(20) not null
)
alter table stu add(addr varchar2(100)); --对已存在的表新增字段
alter table stu modify(addr varchar2(150)); --对字段修改
alter table stu drop (addr); --删除一个字段
alter table stu drop constraint stu_class_fk;
delete from class;
drop table class;
|