oracle左,右,全连接

Oracle 外连接

  • 左外连接 (左边的表不加限制)
  • 右外连接(右边的表不加限制)
  • 全外连接(左右两表都不加限制)

外连接(Outer Join)

outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。外连接分为三种: 左外连接,右外连接,全外连接。 对应SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常我们省略outer 这个关键字。 写成:LEFT/RIGHT/FULL JOIN。

在左外连接和右外连接时都会以一张表为基表,该表的内容会全部显示,然后加上两张表匹配的内容。 如果基表的数据在另一张表没有记录。 那么在相关联的结果集行中列显示为空值(NULL)。

对于外连接, 也可以使用“(+) ”来表示。 关于使用(+)的一些注意事项:


  • (+)操作符只能出现在where子句中,并且不能与outer join语法同时使用。
  • 当使用(+)操作符执行外连接时,如果在where子句中包含有多个条件,则必须在所有条件中都包含(+)操作符
    -(+)操作符只适用于列,而不能用在表达式上。
  • (+)操作符不能与or和in操作符一起使用。
  • (+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。

在做实验之前,我们先将dave表和bl里加一些不同的数据。 以方便测试。

SQL> select * from bl;

    ID NAME

     1 dave

     2 bl

     3 big bird

     4 exc

     9 怀宁

SQL> select * from dave;

    ID NAME

     8 安庆

     1 dave

     2 bl

     1 bl

     2 dave

     3 dba

     4 sf-express

     5 dmm

左外连接(Left outer join/ left join)

left join是以左表的记录为基础的,示例中Dave可以看成左表,BL可以看成右表,它的结果集是Dave表中的数据,在加上Dave表和BL表匹配的数据。换句话说,左表(Dave)的记录将会全部表示出来,而右表(BL)只会显示符合搜索条件的记录。BL表记录不足的地方均为NULL.

示例:

SQL> select * from dave a left join bl b on a.id = b.id;

   ID NAME               ID NAME

    1 bl                  1 dave

    1 dave                1 dave

    2 dave                2 bl

    2 bl                  2 bl

    3 dba                 3 big bird

    4 sf-express          4 exc

    5 dmm                             -- 此处B表为null,因为没有匹配到

    8 安庆                             -- 此处B表为null,因为没有匹配到

SQL> select * from dave a left outer join bl b on a.id = b.id;

    ID NAME               ID NAME

     1 bl                  1 dave

     1 dave                1 dave

     2 dave                2 bl

     2 bl                  2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

     5 dmm

     8 安庆

用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在右表,左表就是全部显示,故是左连接。

SQL> Select * from dave a,bl b where a.id=b.id(+);    -- 注意: 用(+) 就要用关键字where

    ID NAME               ID NAME

     1 bl                  1 dave

     1 dave                1 dave

     2 dave                2 bl

     2 bl                  2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

     5 dmm

     8 安庆

右外连接(right outer join/ right join)

和left join的结果刚好相反,是以右表(BL)为基础的, 显示BL表的所以记录,在加上Dave和BL 匹配的结果。 Dave表不足的地方用NULL填充.

示例:

SQL> select * from dave a right join bl b on a.id = b.id;

    ID NAME               ID NAME

     1 dave                1 dave

     2 bl                  2 bl

     1 bl                  1 dave

     2 dave                2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

                           9 怀宁    --此处左表不足用Null 填充

SQL> select * from dave a right outer join bl b on a.id = b.id;

    ID NAME               ID NAME

     1 dave                1 dave

     2 bl                  2 bl

     1 bl                  1 dave

     2 dave                2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

                           9 怀宁  --此处左表不足用Null 填充

用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在左表,右表就是全部显示,故是右连接。

SQL> Select * from dave a,bl b where a.id(+)=b.id;

    ID NAME               ID NAME

     1 dave                1 dave

     2 bl                  2 bl

     1 bl                  1 dave

     2 dave                2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

                           9 怀宁

全外连接(full outer join/ full join)

左表和右表都不做限制,所有的记录都显示,两表不足的地方用null 填充。 全外连接不支持(+)这种写法。

示例:

SQL> select * from dave a full join bl b on a.id = b.id;

    ID NAME               ID NAME

     8 安庆

     1 dave                1 dave

     2 bl                  2 bl

     1 bl                  1 dave

     2 dave                2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

     5 dmm

                           9 怀宁

SQL> select * from dave a full outer join bl b on a.id = b.id;

    ID NAME               ID NAME

     8 安庆

     1 dave                1 dave

     2 bl                  2 bl

     1 bl                  1 dave

     2 dave                2 bl

     3 dba                 3 big bird

     4 sf-express          4 exc

     5 dmm      

抽象类和接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别。

抽象类

我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的。如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类。比如new Animal(),我们都知道这个是产生一个动物Animal对象,但是这个Animal具体长成什么样子我们并不知道,它没有一个具体动物的概念,所以他就是一个抽象类,需要一个具体的动物,如狗、猫来对它进行特定的描述,我们才知道它长成啥样。在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。同时,抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象的方法,至于这组抽象方法的具体表现形式有派生类来实现。同时抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的,同时在一个以抽象类为节点的继承关系等级链中,叶子节点一定是具体的实现类。(不知这样理解是否有错!!!高手指点….)

在使用抽象类时需要注意几点:

  • 抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
  • 抽象方法必须由子类来进行重写。
  • 只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
  • 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
  • 子类中的抽象方法不能与父类的抽象方法同名。
  • abstract不能与final并列修饰同一个类。
  • abstract 不能与private、static、final或native并列修饰同一个方法。

实例
定义一个抽象动物类Animal,提供抽象方法叫cry(),猫、狗都是动物类的子类,由于cry()为抽象方法,所以Cat、Dog必须要实现cry()方法。如下:

public abstract class Animal {  
public abstract void cry();  
}  
  
public class Cat extends Animal{  
  
@Override  
public void cry() {  
    System.out.println("猫叫:喵喵...");  
}  
}  
  
public class Dog extends Animal{  
  
@Override  
public void cry() {  
    System.out.println("狗叫:汪汪...");  
}  

}  
  
public class Test {  
  
public static void main(String[] args) {  
    Animal a1 = new Cat();  
    Animal a2 = new Dog();  
      
    a1.cry();  
    a2.cry();  
}  
 

--------------------------------------------------------------------  
Output:  
猫叫:喵喵...  
狗叫:汪汪...  

创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样使用他们.抽象类还是有用的重构器,因为它们使我们可以很容易地将公共方法沿着继承层次结构向上移动。

接口

接口是一种比抽象类更加抽象的“类”。这里给“类”加引号是我找不到更好的词来表示,但是我们要明确一点就是,接口本身就不是类,从我们不能实例化一个接口就可以看出。如new Runnable();肯定是错误的,我们只能new它的实现类。接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。同时实现该接口的实现类必须要实现该接口的所有方法,通过使用implements关键字,他表示该类在遵循某个或某组特定的接口,同时也表示着“interface只是它的外貌,但是现在需要声明它是如何工作的”。接口是抽象类的延伸,java了保证数据安全是不能多重继承的,也就是说继承只能存在一个父类,但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多重继承的缺陷,但是推荐继承和接口共同使用,因为这样既可以保证数据安全性又可以实现多重继承。

在使用接口过程中需要注意如下几个问题:

  • Interface的方所有法访问权限自动被声明为public。确切的说只能为public,当然你可以显示的声明为protected、private,但是编译会出错!
  • 接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。可以通过类命名直接访问:ImplementClass.name。
  • 接口中不存在实现的方法
  • 实现接口的非抽象类必须要实现该接口的所有方法。抽象类可以不用实现
  • 不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用(refer to)一个实现该接口的类的对象。可以使用 instanceof 检查一个对象是否实现了某个特定的接口。例如:if(anObject instanceof Comparable){}
  • 在实现多接口的时候一定要避免方法名的重复

抽象类与接口的区别

尽管抽象类和接口之间存在较大的相同点,甚至有时候还可以互换,但这样并不能弥补他们之间的差异之处。下面将从语法层次和设计层次两个方面对抽象类和接口进行阐述。

语法层次

在语法层次,java语言对于抽象类和接口分别给出了不同的定义。下面已Demo类来说明他们之间的不同之处。

使用抽象类来实现:

public abstract class Demo {  
abstract void method1();  
  
  
void method2(){  
    //实现  
}  
}  

使用接口来实现:

interface Demo {  
    void method1();  
    void method2();  
}  

抽象类方式中,抽象类可以拥有任意范围的成员数据,同时也可以拥有自己的非抽象方法,但是接口方式中,它仅能够有静态、不能修改的成员数据(但是我们一般是不会在接口中使用成员数据),同时它所有的方法都必须是抽象的。在某种程度上来说,接口是抽象类的特殊化。

对子类而言,它只能继承一个抽象类(这是java为了数据安全而考虑的),但是却可以实现多个接口。

设计层次

上面只是从语法层次和编程角度来区分它们之间的关系,这些都是低层次的,要真正使用好抽象类和接口,我们就必须要从较高层次来区分了。只有从设计理念的角度才能看出它们的本质所在。一般来说他们存在如下三个不同点:

抽象层次不同

抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。

跨域不同

抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。我们知道抽象类是从子类中发现公共部分,然后泛化成抽象类,子类继承该父类即可,但是接口不同。实现它的子类可以不存在任何关系,共同之处。例如猫、狗可以抽象成一个动物类抽象类,具备叫的方法。鸟、飞机可以实现飞Fly接口,具备飞的行为,这里我们总不能将鸟、飞机共用一个父类吧!所以说抽象类所体现的是一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在”is-a” 关系,即父类和派生类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已。

设计层次不同

对于抽象类而言,它是自下而上来设计的,我们要先知道子类才能抽象出父类,而接口则不同,它根本就不需要知道子类的存在,只需要定义一个规则即可,至于什么子类、什么时候怎么实现它一概不知。比如我们只有一个猫类在这里,如果你这是就抽象成一个动物类,是不是设计有点儿过度?我们起码要有两个动物类,猫、狗在这里,我们在抽象他们的共同点形成动物抽象类吧!所以说抽象类往往都是通过重构而来的!但是接口就不同,比如说飞,我们根本就不知道会有什么东西来实现这个飞接口,怎么实现也不得而知,我们要做的就是事前定义好飞的行为接口。所以说抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。

总结

  1. 抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。
  2. 在抽象类中可以拥有自己的成员变量和非抽象类方法,但是接口中只能存在静态的不可变的成员数据(不过一般都不在接口中定义成员数据),而且它的所有方法都是抽象的。
  3. 抽象类和接口所反映的设计理念是不同的,抽象类所代表的是“is-a”的关系,而接口所代表的是“like-a”的关系。

抽象类和接口是java语言中两种不同的抽象概念,他们的存在对多态提供了非常好的支持,虽然他们之间存在很大的相似性。但是对于他们的选择往往反应了您对问题域的理解。只有对问题域的本质有良好的理解,才能做出正确、合理的设计。

linux(centos)上git的安装

我是在centos的环境下以源码的形式装的

先去下源码包

下载源码

git在这去下源码包 git-2.7.0.tar.gz

下好之后上传到linux服务器上,

解压,配置安装

[root@drayy git-2.7.0]# cd git-2.7.0
[root@drayy git-2.7.0]# ./configure
[root@drayy git-2.7.0]# make
[root@drayy git-2.7.0]# make install

但在执行make操作时报错:缺少gcc,yum安装gcc

[root@drayy git-2.7.0]# yum -y install gcc

重新执行make操作,还报错,缺少zlib.h。我们可以查看是否存在zlib.h

[root@drayy git-2.7.0]# whereis zlib

如果存在则会输出zlib路径。不存在则输出空白,以下是安装详情:

  • 下载zlib下载zlib最新版:zlib-1.2.8.tar.gz

    [root@drayy git-2.7.0]# tar -zxvf zlib-1.2.8.tar.gz
    [root@drayy git-2.7.0]# cd zlib-1.2.8
    [root@drayy git-2.7.0]# ./configure
    [root@drayy git-2.7.0]# make
    [root@drayy git-2.7.0]# make install

    再执行
    [root@drayy git-2.7.0]# git –version
    git version 2.7.0

安装成功

struts2返回结果类型

Result Types

Chain Result

用来处理Action链,被跳转的action中仍能获取上个页面的值

配置文件
<package name="public" extends="struts-default">
    <!-- Chain creatAccount to login, using the default parameter -->
    <action name="createAccount" class="com.dream.struts.ResultAction" method="createAccount">
        <result type="chain">login</result>
    </action>

    <action name="login" class="com.dream.struts.ResultAction" method="login">
        <!-- Chain to another namespace -->
        <result type="chain">
            <param name="actionName">dashboard</param>
            <param name="namespace">/secure</param>
        </result>
    </action>
</package>

<package name="secure" extends="struts-default" namespace="/secure">
    <action name="dashboard" class="com.dream.struts.ResultAction" method="dashboard">
        <result>/dashboard.jsp</result>
    </action>
</package>

ResultAction.java
public class ResultAction {
public String createAccount(){
    System.out.println("ceate account");
    return "success";
}

public String login(){
    System.out.println("login");
    return "success";
}
public String dashboard(){
    System.out.println("dashboard");
    return "success";
}
}

Dispatcher Result

缺省值,如果没有配置类型默认就是dispatcher,包括或转发到一个视图(通常是一个jsp)。在后台Struts2将使用一个RequestDispatcher,目标servlet/JSP接收相同的request/response对象作为原始的servlet或JSP。 因此,可以使用request.setAttribute()传递数据- - - Struts的action是可用的。如果请求action会找不到资源。

<result name="success" type="dispatcher">
  <param name="location">/foo.jsp</param>
</result>

Redirect Result

重定向到一个资源,唯一的传参方法是通过会话或用OGNL表达式,url参数(url ?名称=值)。

  • parse: true by default. If set to false, the location param will not be parsed for Ognl expressions.

    <-- Pass parameters (reportType, width and height) --> generateReport.jsp pie 100 100 false summary

Redirect Action Result

HttpHeader Result

Stream Result

Velocity Result

XSL Result

PlainText Result

Tiles 2 Plugin

Tiles 3 Result

Postback Result

FreeMarker Result

返回一个视图使用FreeMarker模板引擎。

<result name="success" type="freemarker">foo.ftl</result>

开发笔记

将用户信息保存到Session中

ServletActionContext.getRequest().getSession().setAttribute(Constant.USER, user);

清除session中的保存信息

ServletActionContext.getRequest().getSession().removeAttribute(Constant.USER);

登录过滤器

public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    // TODO Auto-generated method stub
    HttpServletResponse rep= (HttpServletResponse) response;
    HttpServletRequest req=  (HttpServletRequest) request;
    String uri=req.getRequestURI();
    //判断当前请求地址是否是登录的请求地址
    if(!uri.contains("sys/login_")){
        //非登录请求
        if(req.getSession().getAttribute(Constant.USER) != null){
            //说明已经登录过,放行
            chain.doFilter(req, rep);
        }else {
            //没有登录过,跳转到登录界面
            rep.sendRedirect(req.getContextPath()+"/sys/login_toLoginUI.action");
        }
    }else {
        //登录请求,直接放行
        chain.doFilter(req, rep);
    }
}
@Override
public void destroy() {}
}

web.xml
    <!-- 登录过滤器,配置在struts2的前面  -->
  <filter>
    <filter-name>loginFilter</filter-name>
    <filter-class>com.dream.core.filter.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>loginFilter</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>

获取spring中的bean

WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext());
                PermissionCheck pc=(PermissionCheck) webApplicationContext.getBean("permissionCheck");
                

解决子框架嵌套的问题

if(window != window.parent){
    window.parent.location.reload(true);
} 

struts2 指定日期格式标签

<s:date name="createTime" format="yyyy-MM-dd HH:mm"/>

struts2 if标签,jq替换标签内容

//异步发布信息,信息的id及将要改成的信息状态
  	function doPublic(infoId, state){
  		//1、更新信息状态
  		$.ajax({
  			url:"${basePath}nsfw/info_publicInfo.action",
  			data:{"info.infoId":infoId, "info.state":state},
  			type:"post",
  			success: function(msg){
  				//2、更新状态栏、操作栏的显示值
  				if("更新状态成功" == msg){
  					if(state == 1){//说明信息状态已经被改成 发布,状态栏显示 发布,操作栏显示 停用
  						$("#show_"+infoId).html("发布");
  						$("#oper_"+infoId).html('<a href="javascript:doPublic(\''+infoId+'\',0)">停用</a>');
  					} else {
  						$("#show_"+infoId).html("停用");
  						$("#oper_"+infoId).html('<a href="javascript:doPublic(\''+infoId+'\',1)">发布</a>');
  					}
  				} else {alert("更新信息状态失败!");}
  			},
  			error: function(){
  				alert("更新信息状态失败!");
  			}
  		});
  	}

<td id="show_<s:property value='infoId'/>" align="center"><s:property 	value="state==1?'发布':'停用'"/></td>
<td align="center">
    <span  id="oper_<s:property value='infoId'/>">
        <s:if test="state==1">
            <a href="javascript:doPublic('<s:property value='infoId'/>',0)">停用</a>
        </s:if><s:else>
            <a href="javascript:doPublic('<s:property value='infoId'/>',1)">发布</a>
         </s:else>
    </span>
         <a href="javascript:doEdit('<s:property value='infoId'/>')">编辑</a>
        <a href="javascript:doDelete('<s:property value='infoId'/>')">删除</a>
 </td>

框架整合:在web.xml中注册spring监听器,启动spring容器:

先整合  struts 和spring
然后    spring 和hibernate
最后		struts spring hibernate 

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

final关键字修饰一个变量时

final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的

写struts2的核心过滤器的时候可以这样写

去引入jar包驱动下依次找到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter类

  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>

可以在项目struts总文件中包含 struts子文件

<include file="com/dream/nsfw/complain/conf/complain-struts.xml"></include> 

Spring配置文件

配置 Spring 核心监听器

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
监听器默认会加载 /WEB-INF/applicationContext.xml 配置文件 通常不会放在这个地主所以还需配置路径

如果不是配置在src根目录下,则需要这么写
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/classes/com/dream/nsfw/user/conf/user-spring.xml</param-value>
</context-param>

如果是配置在src根目录下,则需要这么写 
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/classes/user-spring.xml</param-value>
</context-param>
 
的确是简单了不少,但这样写还是麻烦所以有了如下写法
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:user-spring.xml</param-value>
</context-param>
这样看起来爽多了

3/16/2016 项目笔记

onchange事件触发条件需满足:

1、输入框的值发生改变;2 、输入框失去焦点。事件触发发生在2,而不是1的过程中。

设计工具

引言

最近一直在搞概要设计,需要画界面原型,经朋友推荐,知道了一个非常好用的工具,这里也推荐给大家,希望对你有所帮助。

工具:Balsamiq Mockups_2.2.5
地址:

这个工具用的还是比较顺手的

拖入,双击,全选,都是非常方便的, Very Good

界面如下

pd生成sql语句带引号

最近在用Powerdesigner生成oracle数据库sql语句时,发现表和字段名中都带有引号。例如:

create table "authorISBN"  (
"authorID"           INTEGER        not null,
"tit_isbn"           VARCHAR2(20),
"aut_authorID"       INTEGER,
"isbn"               VARCHAR2(20),
constraint PK_AUTHORISBN primary key ("authorID")
);

如果这样生成表的话,那么你查询或者插入数据都会显示table or view does not exist(表或视图不存在),然后让你郁闷的事情来了,这些表中oracle数据库中是存在的(我是建立在scott用户中的),但是你去删除这些表(drop table 表名,或者drop table “表名”)都是无法删除的,经过自己查找资料和研究发现,说明scott用户的权限不够。解决的方法是:你先连接到system用户下,使用命令 grant select any table to scott;(这句命令的意思是,授权给scott用户选择任何的表),这样你在连接到scott用户下,发现可以查询出这张表(select * from “表名”) 但是表名上要加引号。删除这张表(drop table “表名”) 表名上同样要加引号。

那么为什么用PowerDesigner生成的oracle数据库sql语句的表名和字段名上会出现引号呢?
因为,Oracle创建表的一条规则为:在命名表的时候可以使用大写或小写字母。只要表名或字段名没有用双引号括住,Oracle 对大小写就不敏感。Oracle 支持使用双引号的语法。但是,最好不要直接使用双引号。

那么怎么让这些引号不出现呢?
在PowerDesiger中,在physical data model 中找到菜单中的Database下的Edit current DBMS中,选择Script->Sql->Format,有一项CaseSensitivityUsingQuote,它的comment为“Determines if the case sensitivity for identifiers is managed using double quotes”,表示是否适用双引号来规定标识符的大小写,可以看到右边的values默认值为“YES”,改为“No”,点击【应用】按钮。
这样再生成sql语句时,表和字段名上是没有引号了。

oracle常用命令

解锁 scott用户

Cmd 命令下输入 sqlplus / as sysdba  进入 特权模式,然后更改 用户权限
alter user scott account unlock;

解锁scott用户时设置密码
alter user SCOTT account unlock identified by 123456;

创建用户,授权

创建用户tom 密码为13456

create user tom identified by 123456

授权tom登录权限

grant connect to tom

授权resource建表权限

 grant  resource to tom;

授权用户DBA权限

grant dba to testuser ;

授权创建视图权限

grant create any view to test;

给一个用户赋权限使用命令grant,回收权限使用命令 revoke

删除用户tom

drop user tom

删除带数据的tom

drop user tom cascade

查询scott 下的表

select  *  from  tab;

删除表

select 'drop table '||table_name||';' 
from cat 
where table_type='TABLE'

EXP数据库导出命令

exp 用户名/密码@localhost:1521/orcl file=E:/test.dmp full=y

DMP文件导入命令

imp 用户名/密码@localhost:1521/orcl file=E:/test.dmp full=y

删除数据为空的表数据

delete from cs_jsjd where cjdw is null; 

聚合函数的使用

聚合函数包含如下函数

avg count dense_rank rank first last max min sum grouping

group by 用于对查询结果分组统计
having子句用于限制分组显示结果

如何显示每个部门的平均工资和最高工资

SQL> select deptno,avg(sal),max(sal) from emp group by deptno;

显示每个部门的每种岗位的平均工资和最低工资

SQL> select deptno,job,avg(sal),max(sal) from emp group by deptno,job;

显示平均工资in低于2000的部门号和它的平均工资

SQL> select deptno,avg(sal),max(sal) from emp group by deptno having avg(sal)>2000;

对数据分组的总结

  • 分组函数只能出现在选择列表、having、order by 子句中
  • 如果在select语句中同时包含group by,having,order by 那么它们的顺序是group by , having ,order by

在选择列中如果有列,表达式和分组函数,那么这些列和表达式必须有一个出现在group by 子句中,否则就会出错

select deptno,avg(sal),max(sal) from emp group by deptno having avg(sal)<2000; 这里deptno就一定要出现在group by中

用decode 加统计行

表结构如下
CREATE TABLE "USER_CSCS"."CS_JKRB" 
(	"JKRB_ID" VARCHAR2(32 BYTE) DEFAULT sys_guid(), 
"KMDM" VARCHAR2(32 BYTE), 
"KMMC" VARCHAR2(32 BYTE), 
"BRFSE" VARCHAR2(32 BYTE), 
"BSZQ" VARCHAR2(32 BYTE), 
"ZJR" VARCHAR2(32 BYTE), 
"ZJSJ" VARCHAR2(32 BYTE) DEFAULT to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'), 
"XGR" VARCHAR2(32 BYTE), 
"XGSJ" VARCHAR2(32 BYTE)
)

with aa as
(
select kmdm,kmmc from cs_jkrb
)
select decode (grouping(t.kmdm),1,'合计',t.kmdm) kmdm,
decode (grouping(t.kmdm),1,' ',max(r.kmmc)) kmmc,
sum(t.brfse) 
from cs_jkrb t left join aa r on t.kmdm=r.kmdm
group by rollup(t.kmdm) 
order by t.kmdm;


select  decode (grouping(kmdm),1,'合计',kmdm) kmdm,kmmc,sum(brfse) from cs_jkrb group by rollup(kmdm,kmmc);

select  decode (grouping(kmdm),1,'合计',kmdm) kmdm,sum(brfse) from cs_jkrb group by rollup(kmdm);


with ds as
(select nsrsbh,rkrq,shuie from cs_drkxx),--地税
gs as (select nsrsbh,rkrq,shuie from cs_grkxx)--国税
select ds.nsrsbh,ds.rkrq,ds.shuie,gs.rkrq,gs.shuie from ds,gs
where ds.nsrsbh=gs.nsrsbh;

oracle合并查询

有时在实际应用中,为了合并多个select语句的结果可以使用集合操作符号 union,union all,intersect,minus

  • union 该操作符用于取得两个结果集的并集,使用该操作符时,会自动去掉结果集中重复行

    select ename,sal,job from emp where sal>2500 union select ename,sal,job from emp where job=’manager’

  • union all 该操作符与union相似,但不会取消重复行,而且不会排序

    select ename ,sal,job from emp where sal>2500 union all select ename,sal,job from where job=’manager’

  • intersect 使用该运算符取得两个结果集的交集

    select ename,sal,job from emp where sal>2500 intersect select ename,sal,job form emp where job=’manager’

  • minus 使用该操作符用于取得两个结果集的差集,它只会显示存在第一个集合中,而不存在第二个集合中的数据

    select ename,sal,job from emp where sal>2500 minus select ename,sal,job form emp where job=’manager’

复杂查询,子查询

如何显示高于自己部门的平均工资的员工的信息

第一步
1.	先求各个部门的平均工资和部门号
select deptno ,avg(sal) mysql from emp group by deptno;
2.	把上面的子查询看作一张子表
select a2.ename,a2.deptno,a2.sal,a1.mysql from emp a2 ,(select deptno,avg(sal) mysql from emp by deptno) a1 where a1.deptno=a2.deptno and a2.sal>a1.mysal;

查询与smith的部门和岗位完全相同的所有雇员

select  * from emp where (deptno,job)=(select deptno,job from emp where ename='SMITH');

在多行子查询中使用all操作符
如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

select ename,job,sal from emp where sal>all(select sal from emp where deptno=30);
或是
select ename,job,sal from emp where sal>(select max(sal) from emp where deptno =30)
后者效率更高

在多行子查询中使用any操作符

如何显示工资比部门30的任意一个员工的工资高的员工的姓名、工资和部门号

select ename,sal,job from emp where sal>any(select sal from emp where deptno=30);
或者
select ename,job,sal from emp where sal> (select min(sal) from emp where deptno=30);

with as用法

Oracle数据库中,使用with语句可以实现子查询,提高语句执行的效率,当查询中多次用到某一部分时,可以用Oracle with语句创建一个公共临时表。因为子查询在内存临时表中,避免了重复解析,所以执行效率会提高不少。临时表在一次查询结束自动清除。

例子1
with 
q1 as (select 3+5 S from dual),
q2 as (select 3*5 M from dual),
q3 as (select S,M,S+M,S*M from q2,q1)
select * from q3;

例子2
with tt as(
select 'aaa' id, '高' value from dual union all
  select 'bbb' id, '低' value from dual union all
  select 'aaa' id, '低' value from dual union all
  select 'aaa' id, '高' value from dual union all
  select 'bbb' id, '低' value from dual union all
  select 'bbb' id, '高' value from dual)
select id, 
count(decode(value,'高',1))高,
count(decode(value,'高',1))低
from tt
group by id

例子3
with aa as
     (select zbbh, zbmc, dept_code,dept_name, bssj, #{bszq} bszqq from cs_zbinfo)
    select a.dept_name,
           a.zbmc,
           decode(b.log_date, '', '否', '是') sfbs,
           a.bszqq || '-' || a.bssj ybssj,
           b.log_date,
           case
             when b.log_date is not null and to_char(b.log_date,'yyyy-mm-dd')>a.bszqq || '-' || a.bssj then
                '超期完成'
             when b.log_date is not null and to_char(b.log_date,'yyyy-mm-dd')<a.bszqq || '-' || a.bssj then 
                '准时完成'
             when b.log_date is null and to_char(sysdate,'yyyy-mm-dd')<=a.bszqq || '-' || a.bssj then
                 '未到期'
             when b.log_date is null and to_char(sysdate,'yyyy-mm-dd')>a.bszqq || '-' || a.bssj then
                  '超期未完成'
           end bszt
      from aa a, cs_zblog b
     where a.zbbh = b.zbbh(+)
       and a.bszqq = b.bszq(+)

ORACLE 11G listener.ora配置文件

# listener.ora Network Configuration File: E:\app\Dreamer\product\11.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = E:\app\Dreamer\product\11.2.0\dbhome_1)
      (PROGRAM = extproc)
      (ENVS = "EXTPROC_DLLS=ONLY:E:\app\Dreamer\product\11.2.0\dbhome_1\bin\oraclr11.dll")
    )
    (SID_DESC =
      (SID_NAME = ORCL)
      (ORACLE_HOME = E:\app\Dreamer\product\11.2.0\dbhome_1)
      (GLOBAL_DBNAME = ORCL)
      (ENVS = "EXTPROC_DLLS=ONLY:E:\app\Dreamer\product\11.2.0\dbhome_1\bin\oraclr11.dll")
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = Dream)(PORT = 1521))
    )
  )

ADR_BASE_LISTENER = E:\app\Dreamer

建表,默认值,注释

create  table CS_QYYD(
obj_id VARCHAR2(32) default sys_guid(),
yhmc   VARCHAR2(300),
yhdz   VARCHAR2(300),
tjsjq  VARCHAR2(32),
tjsjz  VARCHAR2(32),
bqs    NUMBER(18,2),
bnlj   NUMBER(18,2),
bszq   VARCHAR2(32),
zjr    VARCHAR2(32),
zjsj   VARCHAR2(32) default to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'),
xgr    VARCHAR2(32),
xgsj   VARCHAR2(32)
)
--给表加注释信息
comment on table CS_QYYD is '缴纳社保信息';

--给字段加注释信息
comment on column CS_QYYD.obj_id is 'ID';
comment on column CS_QYYD.yhmc  is '用户名称';
comment on column CS_QYYD.yhdz is '	用户地址	';
comment on column CS_QYYD.tjsjq is '统计时间起';
comment on column CS_QYYD.tjsjz is '	统计时间止	';
comment on column CS_QYYD.bqs is '本期数	';
comment on column CS_QYYD.bnlj is '本年累计数';
comment on column CS_QYYD.bszqm is '报送所属期';
comment on column CS_QYYD.zjr  is '增加人';
comment on column CS_QYYD.zjsj is '增加时间';
comment on column CS_QYYD.xgr is '修改人';
comment on column CS_QYYD.xgsj  is '修改时间';

PowerDesigner概念模型详解

概念模型的重要性

数据库设计的基本步骤:

需求分析

从系统需求中寻找一些概念性名词,并甄选,并对这些名词相关属性做了解,这部分是人工的,PD做不了什么

概念结构设计

针对甄选的名词进行分心,找出其中的关系(独立的、一对一、一对多、多对多、继承五种关系),并用E-R图描述出来,这是大学课本的做法。在PD中,这个过程可以用CDM(概念模型)来描述,PDM中实体概念模型表示方式比E-R更清晰,更好

逻辑结构设计

实际上就是设计表的结构和表之间的主外关系等。这部分在PD中对应的是PDM(物理模型),而PD中的物理模型一般都是直接从概念模型生成的。也就是说,只要你做好概念模型,物理模型就可以自动生成。当然,这种生成结果一般都需要做一些调整和优化。

物理结构设计

有了PDM,数据库的物理设计将不费吹灰之力,直接可以从PDM导出各种数据库系统的建库脚本。

数据库的建立和测试

这个过程也很简单,看看建库脚本的执行就知道了。不合理了重新修改PDM,然后生成sql再来

数据库运行和维护

这个一般是DBA的事情了,比如时间长了,数据量大了,在某些列上加上索引,调优等等。

从中可以看到,一上来就建PDM,是不合理的。实际上要求对概念模型有个透彻理解了才去做PDM,这种理解可以不画图,但至少是心中有图。

使用PD建立数据库概念模型

一对一CDM

一对多CDM

多对多CDM

继承关系CDM

总结

  • 数据库建模是系统设计中最重要一步,概念模型能很好的描述数据间的关系,还可以从概念模型精确生成符合一定标准范式的物理模型。
  • CDM能描述出更细微的数据关系,比如是0-n还1-n,这直接影响到数据业务上的约束,但是用PDM无法描述。CDM为业务交流节约了沟通成本。
  • CDM也为后来了解底层业务数据关系提供了依据,尤其是表很多很多时候,如果没有CDM,那只有设计数据库的人知道底层的关系了。
  • 如果表很多,分模块的情况,还可以讲CDM分包来管理,这样可以避免将所有的实体关系画到一张图中所带来阅读上烦恼。
  • PD还有其他很多很强悍的功能,比如数据库反响到PDM,PDM导出脚本,PDM导出Java模型对象、XML模型。还可以生成DAO层的持久化代码,甚至hbm文件,还可以做业务流程建模、生成数据字典报表等等。但PD最擅长的就是CDM–>PDM–>SQL,数据库反向工程,报表功能,用好这些就不错了。