考核
\1. 常用drools的属性有哪些?(介绍5种 并说明作用)
一、属性no-loop 默认值:false 类型:Boolean 属性说明:防止死循环,当规则通过update之类的函数修改了Fact对象时,可能使规则再次被激活,从而导致死循环。将no-loop设置为true的目的是避免当前规则then部分被修改后的事实对象再次被激活,从而防止死循环的发生。 二、属性ruleflow-group 默认值:N/A 类型:String 属性说明:ruleflow-group分为rule、flow和group3个部分,分别代表规则、流程、分组,即常说的规则流。 三、属性lock-on-active 默认值:false 类型:Boolean 属性说明:lock-on-active是指”锁定活跃”。既然它是规则体的属性,那一定是锁定规则的,而且是锁定活跃的规则。简单地说,当规则体设置该属性为true时,则当前只会被触发一次。当ruleflow-group或agenda-group再次被激活时,即使在规则体中设置lock-on-active为true,该规则体也不能再次被激活,即无论如何更新规则事实对象,当前规则也只能被触发一次。这是no-loop的升级版,一个更强大的解决死循环的属性。 四、属性salience 默认值:0 类型:integer 属性说明:规则体被执行的顺序,每一个规则都有一个默认的执行顺序,如果不设置salience属性,规则体的执行顺序为由上到下。salience值可以是一个整数,但也可以是一个负数,其值越大,执行顺序越高,排名越靠前。Drools还支持动态配置优先级。 五、属性enabled 默认值:true 类型:Boolean 属性说明:指规则是否可以被执行,若规则体设置为enabled false,则规则体将视为永久不被激活。 六、属性dialect 可能值:Java或Mvel。 类型:String。 属性说明:用来定义规则中要使用的语言类型,支持Mvel和Java两种类型语言,默认情况下由包指定的。Java语言在特殊情况下会用到,如Ac-cumulate、引用Java中的语法等。 七、属性date-effective 默认值:N/A 类型:String、日期、时间。 属性说明:只有当前系统时间大于等于设置的时间或日期,规则才会被激活。在没有设置该属性的情况下,规则体不受时间限制。date-effective的值是一个日期型的字符串,默认情况下,date-effective可接受的日期格式为”dd-MM-yyyy”。 八、属性date-expires 默认值:N/A 类型:String、日期、时间。 属性说明:date-expires属性与date-effective属性是相反的,即只有当前系统时间小于设置的时间或日期,规则才会被激活。在没有设置该属性的情况下,规则体不受时间限制。date-expires的值为一个日期型的字符串,默认情况下,date-expires可接受的日期格式为”dd-MMM-yyyy”。 九、属性duration 默认值:无。 类型:long。 属性说明:表示定时器,如果当前规则LHS部分为true,那么规则继续执行;如果该属性已经被弃用,那么通过新的属性timer来控制。 十、属性activation-group 默认值:N/A。 类型:String。 属性说明:activation-group是指激活分组,通过字符串定义分组名称,具有相同组名称的规则体有且只有一个规则被激活,其他规则体的LHS部分仍然为true也不会被执行。该属性受salience属性影响,如当前规则文件中的其他规则未设计该属性,则视为规则处于被激活状态,并不受该属性的影响。 十一、属性agenda-group 默认值:无,需要通过Java设置。 类型:String。 属性说明:agenda-group是议程分组,属于另一种可控的规则执行方式,是指用户可以通过配置agenda-group的参数来控制规则的执行,而且只有获取焦点的规则才会被激活。 十二、属性auto-focus 默认值:false。 类型:Boolean。 属性说明:auto-focus属性为自动获取焦点,即当前规则是否被激活。如果一个规则被执行,那么认为auto-focus为true;如果单独设置,一般结合agenda-group,当一个议程组未获取焦点时,可以设置auto-focus来控制。 十三、属性timer 默认值:无。 类型:与Java定时器参数类型相似。 属性说明:timer属性是一个定时器,用来控制规则的执行时间。
\2. 简述drools API开发步骤
获取KieServices 获取KieContainer 获取KieSession 插入事实对象(Insert fact) 执行规则引攀 关闭KieSessionCSDN
\3. 简述RHS中extends的作用
extends关键字进行规则条件部分的继承
\4. 简述SpringBoot整合drools步骤
springboot整合drools初步实战 1.导入maven依赖 <properties> <drools.version>7.14.0.final</drools.version> </properties> <!-- drools --> <dependency> <groupid>org.drools</groupid> <artifactid>drools-compiler</artifactid> <version>${drools.version}</version> </dependency> 2.编写配置类 package com.springcloud.blog.admin.config; import org.kie.api.kiebase; import org.kie.api.kieservices; import org.kie.api.builder.*; import org.kie.api.runtime.kiecontainer; import org.kie.api.runtime.kiesession; import org.kie.internal.io.resourcefactory; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.core.io.resource; import org.springframework.core.io.support.pathmatchingresourcepatternresolver; import org.springframework.core.io.support.resourcepatternresolver; import java.io.ioexception; @configuration public class kiasessionconfig { private static final string rules_path = "rules/"; @bean public kiefilesystem kiefilesystem() throws ioexception { kiefilesystem kiefilesystem = getkieservices().newkiefilesystem(); for (resource file : getrulefiles()) { kiefilesystem.write(resourcefactory.newclasspathresource(rules_path + file.getfilename(), "utf-8")); } return kiefilesystem; } private resource[] getrulefiles() throws ioexception { resourcepatternresolver resourcepatternresolver = new pathmatchingresourcepatternresolver(); final resource[] resources = resourcepatternresolver.getresources("classpath*:" + rules_path + "**/*.*"); return resources; } @bean public kiecontainer kiecontainer() throws ioexception { final kierepository kierepository = getkieservices().getrepository(); kierepository.addkiemodule(new kiemodule() { public releaseid getreleaseid() { return kierepository.getdefaultreleaseid(); } }); kiebuilder kiebuilder = getkieservices().newkiebuilder(kiefilesystem()); kiebuilder.buildall(); return getkieservices().newkiecontainer(kierepository.getdefaultreleaseid()); } private kieservices getkieservices() { return kieservices.factory.get(); } @bean public kiebase kiebase() throws ioexception { return kiecontainer().getkiebase(); } @bean public kiesession kiesession() throws ioexception { return kiecontainer().newkiesession(); } } 3.resources目录新建rules目录 4.新建实体 package com.springcloud.blog.admin.drools; public class people { private int sex; private string name; private string drltype; public int getsex() { return sex; } public void setsex(int sex) { this.sex = sex; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getdrltype() { return drltype; } public void setdrltype(string drltype) { this.drltype = drltype; } } 5.编写规则文件 package com.springcloud.blog.admin.drools import com.springcloud.blog.admin.drools.people dialect "java" rule "man" when $p : people(sex == 1 && drltype == "people") then system.out.println($p.getname() + "是男孩"); end 6.单元测试(只要正常输出,表示整合是ok的,接下来就可以任意应用了) package com.springcloud.blog.base.controller.test.task; import com.springcloud.blog.admin.blogadminapplication; import com.springcloud.blog.admin.drools.people; import org.junit.test; import org.junit.runner.runwith; import org.kie.api.kiebase; import org.kie.api.runtime.kiesession; import org.springframework.beans.factory.annotation.autowired; import org.springframework.boot.test.context.springboottest; import org.springframework.test.context.junit4.springrunner; @runwith(springrunner.class) @springboottest(classes = blogadminapplication.class, webenvironment = springboottest.webenvironment.random_port) public class droolsjunittest { @autowired private kiesession session; @test public void people() { people people = new people(); people.setname("yc"); people.setsex(1); people.setdrltype("people"); session.insert(people);//插入 session.fireallrules();//执行规则 } } 7.输出结果
\5. 商场为了增加商品的销量 开展如下活动,请根据活动的内容编写drl文件
1) 满减
用户订单每满100元减10元
用户订单每满500元减60元
用户订单每满1000元减150元
2) 指定分类商品打折
1) 大家电类商品、小家电类商品 打7折
2) 休闲食品类、干性杂货类商品打9折
以上两项活动同时有效
package order import com.kgc.mydrool.pojo.Orders rule "用户订单每满100元减10元" salience 10 activation-group "order_discount" when $o:Orders(money>=100&&money<500) then $o.setDiscount(($o.getMoney()/100)*10); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end rule "用户订单每满500元减60元" salience 10 activation-group "order_discount" when $o:Orders(money>=500&&money<600) then $o.setDiscount(60); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end rule "用户订单每满500元减60元1" salience 10 activation-group "order_discount" when $o:Orders(money>=600&&money<1000) then $o.setDiscount(60+(($o.getMoney()-500)/100)*10); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end rule "用户订单每满1000元减150元1" salience 10 activation-group "order_discount" when $o:Orders((money%1000)<100) then $o.setDiscount(($o.getMoney()/1000)*150); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end rule "用户订单每满1000元减150元2" salience 10 activation-group "order_discount" when $o:Orders((money%1000)>=100&&(money%1000)<500) then Integer restMoney=$o.getMoney()%1000; $o.setDiscount(($o.getMoney()/1000)*150+(restMoney/100)*10); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end rule "用户订单每满1000元减150元3" salience 10 activation-group "order_discount" when $o:Orders((money%1000)>=500) then Integer restMoney=$o.getMoney()%1000-500; $o.setDiscount(($o.getMoney()/1000)*150+(restMoney/100)*10+60); $o.setFinalmoney($o.getMoney()-$o.getDiscount()); end 2)指定分类商品打折 1)大家电类商品、小家电类商品 打7折 2)休闲食品类、干性杂货类商品打9折 package goods import com.kgc.mydrool.pojo.Goods rule "大家电类商品、小家电类商品 打7折" salience 10 activation-group "goods_discount" when $g:Goods(type==1||type==2) then $g.setRebate(0.7); end rule "2) 休闲食品类、干性杂货类商品打9折" salience 10 activation-group "goods_discount" when $g:Goods(type==3||type==4) then $g.setRebate(0.9); end
\6. 请简述spring工作原理和spring中使用的设计模式(最少3种)及使用在什么地方
1、Spring的原理和组成 Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现,Spring为简化我们的开发工作,封装了一系列的开箱即用的组件功能模块,包括:Spring JDBC 、Spring MVC 、Spring Security、 Spring AOP 、Spring ORM 、Spring Test等。 #设计模式 工厂方法模式(FactoryMethod)、抽象工厂模式(AbstractFactory)、 建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton) 结构型 适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、 装饰器模式(Decorator)、门面模式(Facade)、享元模式(Flyweight)、 代理模式(Proxy) 行为型 解释器模式(Interpreter)、模板方法模式(TemplateMethod)、 责任链模式(ChainofResponsibility)、命令模式(Command)、 迭代器模式(Iterator)、调解者模式(Mediator)、备忘录模式(Memento)、 观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、 访问者模式(Visitor)
\7. 请简述springmvc工作原理 绘制工作流程图
1、用户发送请求到前端控制器(DispatcherServlet)。 2、前端控制器请求处理器映射器(HandlerMapping)去查找处理器(Handler)。 3、找到以后处理器映射器(HandlerMappering)向前端控制器返回执行链(HandlerExecutionChain)。 4、前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)。 5、处理器适配器去执行Handler。 6、处理器执行完给处理器适配器返回ModelAndView。 7、处理器适配器向前端控制器返回ModelAndView。 8、前端控制器请求视图解析器(ViewResolver)去进行视图解析。 9、视图解析器向前端控制器返回View。 10、前端控制器对视图进行渲染。 11、前端控制器向用户响应结果。
\8. 请问什么是OOM,如果处理
OOM, 全称 “Out Of Memory”, 意思是 “内存用完了”。 程序计数器: 当前线程执行的字节码的行号指示器, 线程私有 JAVA 虚拟机栈: Java 方法执行的内存模型, 每个 Java 方法的执行对应着一个栈帧的进栈和出栈的操作。 本地方法栈: 类似 “JAVA 虚拟机栈”, 但是为 native 方法的运行提供内存环境。 JAVA 堆: 对象内存分配的地方, 内存垃圾回收的主要区域, 所有线程共享。可分为新生代, 老生代。 方法区: 用于存储已经被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。Hotspot 中的 “永久代”。 运行时常量池: 方法区的一部分, 存储常量信息, 如各种字面量、符号引用等。 直接内存: 并不是 JVM 运行时数据区的一部分, 可直接访问的内存, 比如 NIO 会用到这部分。 java.lang.OutOfMemoryError: Java heap space ------>java 堆内存溢出, 此种情况最常见, 一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露, 需要通过内存监控软件查找程序中的泄露代码, 而堆大小可以通过虚拟机参数 - Xms,-Xmx 等修改。 java.lang.OutOfMemoryError: PermGen space ------>java 永久代溢出, 即方法区溢出了, 一般出现于大量 Class 或者 jsp 页面, 或者采用 cglib 等反射机制的情况, 因为上述情况会产生大量的 Class 信息存储于方法区。当出现此种情况时可以通过更改方法区的大小来解决, 使用类似 - XX:PermSize=64m -XX:MaxPermSize=256m 的形式修改。注意, 过多的常量尤其是字符串也会导致方法区溢出。 java.lang.StackOverflowError ------> 不会抛 OOM error, 但也是比较常见的 Java 内存溢出。JAVA 虚拟机栈溢出, 一般是由于程序中存在死循环或者深度递归调用造成的, 栈大小设置太小也会出现此种溢出。可以通过虚拟机参数 - Xss 来设置栈的大小。
\9. Oracle中树状查询 请写一个简单例子
SELECT 。。。START WITH condition CONNECT BY condition;
\10. 请绘制出Oracle体系结构
ORACLE体系结构主要分为:内存结构、进程结构、存储结构。内存结构主要由SGA和PGA构成;进程结构主要由用户进程和ORACLE进程组成;存储结构主要由逻辑存储和物理存储构成。
二、ORACLE内存结构 1、SGA系统全局区是Oracle Instance的基本组成部分,在实例启动时分配。是一组包含一个Oracle实例的数据和控制信息的共享内存结构。主要是用于存储数据库信息的内存区,该信息为数据库进程所共享(PGA不能共享的)。它包含Oracle 服务器的数据和控制信息,它是在Oracle服务器所驻留的计算机的实际内存中得以分配,如果实际内存不够再往虚拟内存中写。 2、PGA是一块包含一个服务进程的数据和控制信息的内存区域。你每启动一个数据库进程就会在内存中创建一个pga,它是独有的,非共享。 三、SGA概述 系统全局区是数据服务中实例的必要组成部分,由很多小内存区共同构成,各个小内存区存放不同的信息,系统全局区用于暂存可以被所有进程( 服务进程和后台进程 )共享的信息,对系统的运行性能有好处,SGA在实例启动的时候自动分配 ,实例关闭时自动释放。SGA暂存系统的大量共享数据,对系统性能影响很大,所以需要为SGA选择适当的管理方式。 1、共享池(Shared Pool) (1)数据字典缓存区(Data Dictionary Cache) 用于存放SQL语句相关的数据文件、表、索引、列、用户、其他的数据对象的定义和权限信息等。 (2)库缓存区(Librabry Cache) 该区域存放共享SQL和PL/SQL代码。服务器进程在执行语句时,首先会匹配库缓存,如果存在相同语句则无需编译直接使用已编译的执行计划。绑定变量不是在编译阶段赋值的,而是在运行阶段赋值的,因此含有绑定变量的SQL语句可以不用重新编译。 (3)SQL和PL/SQL结果缓存 2、大池(Large Pool) 大池是个可选的内存区域,可提供一个大的缓冲区供数据库的备份与恢复操作过程使用。数据库的备份恢复、执行具有大量排序操作的SQL语句、并行化的数据库操作时可能需要用到大池。 3、Java池(Java Pool) JAVA池在数据库中支持JAVA 的运行,存放JAVA代码和JAVA语句的语法分析表 4、流池(Stream Pool) 用于缓存流进程在数据库间移动/复制数据时使用的队列消息。一般从重做日志中提取变更记录的进程和应用变更记录的进程会用到流池。 5、数据库缓存区(Database Buffer Cache) 用于缓存当前或最近使用的从磁盘读取的数据块的拷贝,来优化数据库的I/O减少物理读/写。Oralce依据LRU算法对该内存区域进行block-level的更新.LRU算法(简单理解就是最近最小使用的数据调出内存)。 (1)脏缓存快(Dirty buffers) 数据被修改过并且已经commit但是还未写入磁盘的数据缓存块,脏缓存块最终被DBWn进程写入到磁盘的数据文件中永久保存。 (2)命中缓存块(Pinned buffers) 最近正在被访问的缓存块,始终被保留在数据高速缓存中,不会被写入数据文件。 (3)空闲缓存块(Free buffers) 该缓存块中没有数据,等待被写入数据。oracle从数据文件中读取数据后,寻找空闲缓存块,以便写入其中。 6、日志缓冲区(Redo Log Buffer) 日志缓冲区是一块比较小的内存区域,它是用来短期存储将写入到磁盘中的重做日志信息。日志缓冲区也是为了减少磁盘IO,减少用户的等待时间。 四、PGA PGA是指单个服务器进程或者单个后台进程所需的数据和控制信息。PGA是在用户进程连接到数据库并创建一个会话时自动分配。该区域内保留每个与oracle数据库连接的用户进程所需的内存,当一个用户会话结束,PAG就会释放。排序区 1、排序区 当用户需要对数据进行排序时,系统会将需要排序的数据保存到PGA中的排序区内,然后在这个排序区内对这些数据进行排序。如果发现用户的很多操作都需要用到排序,那么为用户设置比较大的排序区,可以提高用户访问数据的效率。 2、会话区 会话区保存了会话所具有的权限、角色、性能统计等信息,通常都是由数据库系统自我维护。 3、 堆栈区 保存着绑定变量、会话变量、SQL语句运行时的内存结构等重要的信息,通常都是由数据库系统自我维护 4、游标区 游标区是一个动态的区域,当用户执行游标语句打开游标时,系统会在PGA中创建游标区,当关闭游标时,这个区域就会被释放。创建与释放需要占用一定的系统资源,花费一定的时间,如果频繁的打开和关闭游标,就会降低语句的执行性能。 五、进程结构 1、SMON 系统监视器进程,负责打开数据库时候的恢复、整理数据库表(段)空间的碎片等。它通过验证所有数据文件和联机重做日志文件来打开数据库。数据库状态置为open之后,SMON的主要工作内容就放在各种内部任务上,如合并空闲空间,处理表(段)空间碎片。 2、PMON 进程监视器进程,负责监视所有服务器进程,并且检查连接会话中的问题。如果会话异常中止,PMON会及时销毁对应的服务器进程,将PGA内存返回给系统空闲内存池,并回滚所有未提交的事务。 3、DBWn 数据库写进程,它主要负责将Database Buffer Cache中的脏缓冲区写入数据文件,做持久化。这里需要再次声明,数据库写进程DBWn是不受我们commit影响的,我们commit影响的是日志写进程LGWR。DBWn选择要写入的脏缓冲区的原则是:最近最少使用。也就是说,DBWn将最近最少使用的脏缓冲区写入数据文件。 以下四种情况,DBWn将执行写操作: (1)没有可用的缓冲区 当数据被读取到Database Buffer Cache时,需要先查找空闲的缓冲区,也就是说既不脏也没被占用的缓冲区。如果长时间找不到空闲缓冲区,那么DBWn就会将某些脏缓冲区写入磁盘。完成之后,就有可用的空闲缓冲区了。 (2)脏缓冲区过多 第二种情况是脏缓冲区过多,这个多是由Oracle一个内部值决定的。 (3)每三秒钟(三秒钟超时) 第三种情况,三秒钟超时。DBWn每三秒钟会对一些缓冲区进行写操作。前面两种情况是强制写,而三秒钟超时意味着即使没有脏缓冲区,也要DBWn也要执行一次清理。 (4)遇到检查点 前面三种情况是部分写入(称为增量检查点或提高增量检查点位置),最后这种情况是全部写入,把所有的脏缓冲区全部写入数据文件。前三种情况是在Oracle运行过程中自动执行的,不会给系统的I/O造成比较大的压力。但是在执行检查点的情况下,可能同时有非常大量的脏缓冲区需要写入磁盘,所以当时的磁盘I/O会到达顶峰,CPU使用率很可能会爆高到100%。因此,一般在不得已的时候才使用检查点: 4、LGWR 日志写进程,负责将日志缓冲区Log Buffer中的内容写入到磁盘的联机(重做)日志文件中,这个写入的过程称为“日志缓冲区转储”。当我们对数据做任何更改时(包括增删改),这个更改会写入到两个缓冲区,一个是Database Buffer Cache ,用于写入到数据文件;另一个是Redo Log Buffer,用于写入联机重做日志文件。为了防止丢失更改,LGWR进程几乎实时地将Redo Log Buffer写入到联机重做日志文件中。当我们commit时,会话挂起,LGWR执行写入操作,写入完成,事务标记为不可callback的已提交返回给会话,会话重新可用。 (1)会话发出commit 保证了已提交commit的事务中的所有变更都可以在联机重做日志中记录,这是数据库数据不丢失的保证。如果数据库损坏,可以在还原上一次备份的基础上,利用自上次备份以来的(归档)联机重做日志进行事务重做。当然,commit的事务会重新写入数据文件,未提交的事务不会持久化存储。 (2)日志缓冲区1/3满 日志缓冲区三分之一满的时候,也会使LGWR执行写操作。一般来说日志缓冲区只有MB级大小,应用程序(比如JAVA程序)会在不到一秒的时间生成足以充满1/3的重做内容(更改),所以说,LGWR会几乎实时地执行写操作。此后,在会话发出commit命令的时候,由于没有太多要一次性写入到日志中的内容,所以commit也几乎是实时完成的。 (3)DBWn要写入数据文件 为了防止瞬间断电等突发情况的发生而导致数据的不一致,DBWn在写入数据文件之前要执行日志写操作,因为日志写操作能提供数据在没有写入数据文件情况下的数据可恢复性。另外由于DBWn的写操作是有三秒钟超时的,而日志写操作必须要在DBWn之前执行一次,所以LGWR也就有了三秒钟超时的触发条件。 5、CKPT 执行CKPT进程会使得DBWn进行写操作。CKPT不再必须执行完全检查点,但是它必须跟踪重做日志中的增量检查点位置。在必要的时候,CKPT会执行增量检查点,以使得增量检查点的位置前移。增量检查点位置是发生故障时,重做开始的位置。CKPT使用当前检查点位置去刷新控制文件。 6、MMON 可管理性监视器进程,以前也叫Memory Monitor,内存监视器进程用于支持Oracle数据库的自我管理和自我调整的进程,简单地理解为“监视器的监视器”。 7、MMAN MMAN,Memory Manager,内存管理进程,支持内存分配的自动管理。有了这个进程,我们DBA只需要去设置总的内存大小,SGA以及PGA等,MMAN会在DBA设置的总体大小范围内进行自动分配。 8、LREG 侦听器注册进程,它注册了有关数据库实例和Oracle网络监听调度程序的信息。这样,用户就可以通过侦听器连接到数据库。同时LREG还能根据工作负载与性能信息更新侦听器,这在多实例环境下是比较智能的。之前这个功能是由PMON来实现的。 9、ARCn 它将联机重做日志文件的内容写入到归档日志文件中。由于联机重做日志文件只有那么几组,每组几个文件,每个文件就几兆,它们会频繁地被刷新,不可能保留长期且完整的重做条目,所以,为了保证可恢复性,必须在联机重做日志文件被刷新前将其归档。如果启用了归档模式,ARCn将会启动,一旦ARCn异常,数据库实例将会挂起。ARCn最多有30个,命名为ARC1~ARC30。 10、RECO RECO,Recoverer,恢复进程。它是在分布式架构下,解决分布式事务失败问题的进程。
\11. 请编写一个最简单的存储过程
什么是存储过程 存储过程是存储在Oracle数据库中的一段plsql程序块,我们可以使用存储过程来完成一定的操作数据库的逻辑。它类似于编程中的方法(只是类似哦!),可以有输入参数、输出参数、输入输出参数。 存储过程最大的优点是速度很快,因为其存储在数据库中,且已经编译过了,所以调用时速度很快。
CREATE OR REPLACE PROCEDURE INSERT_DEPT_PROCEDURE( deptNo IN NUMBER,--输入型参数 deptName IN VARCHAR2 DEFAULT '新建部门',--输入参数的默认值 deptLoc IN VARCHAR2, deptInfo OUT VARCHAR2,--输出型参数 returnInfo IN OUT BOOLEAN--输入输出型参数 ) IS BEGIN INSERT INTO dept VALUES(deptNo,deptName,deptLoc); COMMIT; dbms_output.put_line('插入数据成功'); SELECT dt.deptno||dt.dname||dt.loc INTO deptInfo FROM dept dt;--给输出型参数赋值 IF returnInfo THEN returnInfo :=FALSE; ELSE returnInfo := TRUE; END IF; --这里可以有异常处理的代码 END INSERT_DEPT_PROCEDURE;删除存储过程
DROP PROCEDURE INSERT_DEPT_PROCEDURE; EXECUTE INSERT_DEPT_PROCEDURE;--无参数调用 execute INSERT_DEPT_PROCEDURE(88,'软件部','重庆');--有参数调用(按位置) --参数调用时,有按位置传递和按名称传递两种,按名称传递一般不使用,这里不介绍
\12. 有表学员成绩表(stuscores)如下,请编写SQL语句找出每个班级的成绩前3的学员
Id(编号) | Stuname(学员编号) | Classid(班级编号) | Score(考试成绩) |
---|---|---|---|
1 | 张三 | 1 | 90 |
2 | 李四 | 2 | 77 |
3 | 王五 | 1 | 69 |
4 | 赵柳 | 1 | 78 |
5 | 宋茜 | 1 | 99 |
6 | 王斌 | 2 | 70 |
#分区⼦句(partition-by-clause):按照分区列的值对数据⾏进⾏分组。所有分区列的值相同的数据⾏被组合为⼀个数据分区。
#排序⼦句(order-by-clause):通过⼀列或⼀个表达式的值来对数据分区中的⾏进⾏排序。在分区⼦句中按照分区列的值来进⾏排序,在数
据分区内的数据⾏按照排序列的值进⾏排序。使⽤NULLS FIRST或NULLS LAST⼦句可以把空值放到数据分区的最上⾯或最下⾯。#开窗⼦句(partition-by):⽤来指定不同的分区边界,⽽order-by⼦句可以改变分区内的排序顺序。
select * from (select id,stuname,classid,score,row_number() over(partition by classid order by score desc) rank from stuscores) a where a.rank<=3;