oracle 基础语法(二)

一、实现分页

说明以下tablename是同一表。这些操作是对同一表(tablename)的操作
=======================================
如何实现分页提取记录
方法1:oracle的ROWNUM伪列返回查询的行序号。
        例如要查询表的前10条记录,可以使用
        select * from tablename where ROWNUM<=10
        但是要返回第11-第20条记录,尝试以下的语句
        select * from tablename where ROWNUM<=20 and ROWNUM>=11;
        这个人报错。返回0条记录。因为ROWNUM是伪列,不能用>=条件
        使用以下方法可以查询第11-第20条记录
        select * from
        (select ROWNUM rn ,t.* from tablename t where ROWNUM<=20) where rn>=11;
方法2:使用分析函数ROW_NUMBER实现分页
        select * from (select ROW_NUMBER() OVER (ORDER BY id) rn,t.* from tablename t) 
                where rn between 11 and 20;
方法3:使用集合运算MINUS实现分页
        select * from tablename where ROWNUM<=20 MINUS
        select * from tablename where ROWNUM<11;
点评:方法1在查找前几页时速度很快。但在数据量很大时,最后几页速度比较慢。
方法2查询效率比较稳定,是推荐使用的方法。
方法3只适合查询结果在200行以内的情况,记录数很多时会导致oracle错误,需谨慎使用。
==================================
删除重复的行
在做本练习之前,最好先在ID列上创建索引,否则执行查询等待的时间将会很长。
使用以下的查询语句可以找到ID重复的记录。
select id,count(*) from tablename group by id having count(*)>1;
或
select id from tablename group by id having count(*)>1;
删除重复记录的方法至少有以下3种。
方法1:
        delete from tablename where id IN (select id from tablename group by id having count(*)>1)
            and ROWID NOT IN (select MIN(ROWID) from tablename group id having count(*)>1);
方法2:
        delete from tablename where ROWID IN 
                    (select a.ROWID from tablename a,tablename b wehre a.id=b.id and a.ROWID>b.ROWID);
方法3:
        delete from tablename t where t.rowid>
                (select MIN(x.rowid) from tablename x where t.id=x.id);
点评:方法1是最直观的方法,但是效率不高,因为使用了not in ,会增加一次全表描。
     方法2的效率是3种方法中比较高的。
     方法3在没有索引的情况下使用效率很低,建立索引之后可提高好几倍。
======================================
有关查询优化
在oracle的scott示例用户模式的emp表和dept表为例
第一条查询语句:select * from dept where deptno IN (select deptno from emp);
第二条查询语句:select * from dept d where exists 
                                    (select e.deptno from emp e where e.deptno=d.deptno);
使用exists(第二条语句)效率更高。当emp表记录非常多时,二者的差异非常明显。
相对而言,子查询的开销是大的。

 二、语法 

-- 临时修改日期语言, 以识别英文格式的月份
alter session set nls_date_language = 'AMERICAN';
-- 修改日期语言为简体中文
alter session set nls_date_language = 'SIMPLIFIED CHINESE';
--设置默认的日期格式
alter session set nls_date_format='YYYY-MM-DD HH24:MI:ss';
---日期TO_CHAR()
MM:本年中的2位的月份
MONTH:月份全部大写
MON:月份的前3个字母
WW:本年中的第几周,2位数字
W:本月中第几周,1位数字
DDD:本年中的第几天,3位数字
DD:本月中的第几天,2位数字
D:本周中的第几天,1位数字
DAY:周几的全名,全部大写
Day:周几的全名,首字母大写
select to_date(SYSDATE,'YYYY_MM_DD HH24:MI:SS') from dual;
select to_char(to_date('2006-04-5','YYYY-MM-DD'),'WW') from dual;
日期函数months_between(x,y);x-y=如果为负数:表示x的日期比Y日期早.
-----------------------------------
   create  table  sales (xm varchar2(10), dTime date, count number, totalmoney number,city varchar2(10))
    
    insert into sales values('张三',to_date('2003-01-01','yyyy-mm-dd'),1200,30000,'南昌');
    insert into sales values('张三',to_date('2004-01-01','yyyy-mm-dd'),1200,30000,'南昌');
    insert into sales values('张三',to_date('2003-01-01','yyyy-mm-dd'),1000,30000,'北京');
    insert into sales values('张三',to_date('2004-01-01','yyyy-mm-dd'),2333,40000,'北京');
     
    insert into sales values('李四',to_date('2003-01-01','yyyy-mm-dd'),800,24567,'南昌');
    insert into sales values('李四',to_date('2004-01-01','yyyy-mm-dd'),600,15000,'南昌');
    insert into sales values('李四',to_date('2003-01-01','yyyy-mm-dd'),400,20000,'北京');
    insert into sales values('李四',to_date('2004-01-01','yyyy-mm-dd'),1000,18000,'北京');
    
   select xm,sum(count) 数量,city from sales group by rollup(city,xm) ;
    
    --group分组语句 rollup函数形成类似交叉表
   select xm,sum(count) 数量,sum(totalmoney) 金额 ,city from sales group by xm ,count ,totalmoney,rollup(city)  having count>2000 order by xm ,count ,totalmoney,city
    
    --cube函数形成类似交叉表
    select xm,sum(count) 数量,city from sales group by cube(city,xm) ;
----------------------------------------------    

--scott用户给system用户授权。它们都是有accp数据库下
grant all on emp to system;
--这是收权
revoke all on emp from system;

--这system用户创建同义词
create synonym emp for scott.emp;
select * from emp;
--创建公有同义词
create public synonym emp_public for scott.emp;
select * from emp_public;
--这是查询字典视图user_synonyms来查看用户所创建的同义词的详细信息
select * from User_Synonyms;

--这是查询字典视图user_sequences来查看用户所创建的序列的详细信息
select * from user_secondary_objects;

--创建序列
create sequence abc
    start with 10    --指定要生成的第一个序列号,
    increment by 2    --步长
    maxvalue[nomaxvalue] 2000 --最大值
    minvalue[nominvalue]
    cycle --是否环。
    nocycle--默认为不环

--创建表employee的副本,但不包含表中的记录
create table employee_copy as select * from employee where 1=2;
--把employee表中符合条件的行插入到副本(employee_copy)中
insert into employee_copy select * from employee where deptcode='dp02';
--建表
create table salary_records
(
 empcode varchar2(10),
 working_Days number(5),
 empsal number(10)
);       
--这是增加表的字段列
alter table myfirst add(title varchar2(20));
--这是删除表的字段列
alter table myfirst drop column title;
--这是修改现有表的字段列的定义如:类型
alter table myfirst modify(age int);
--ASC这是升序,distinct无重复行出现
select * from myfirst where age>20 order by age DESC;

--集合操作(1具有相同的列,并且数据类型相同2不该有LONG类型3列标题来自第一个select语句)
select vencode from vendor_master 
minus(减集-不相同的行数),intersect(交集-相同的行数)
select vencode from order_master;

--这是插入建表时日期字段默认值为'sysdate',在插入时要写'sysdate'
insert into datetest values(dt1.nextval,sysdate,'jon');

-----------------
sqlplus /nolog
connect system/accp as sysdba
startup mount
alter database open;
--关闭数据库
shutdown --当用户都断开后,才断开连接关闭数据库
shutdown immediate--当用户执行完sql语句后断开连接关闭数据库

 三、查询语句 

 

=======================子查询(不能包含order by子句)
--1.in :可以用来检查在一个值列表中是否包含指定的值。这个值列表也可以来自一个子查询的返回结果。
--2.any :用来将一个值与一个列表中的"任何值"进行比较。在查询中any操作之前,必须使用一个=,>,>=等比较操作符。
select id from userinfo where uid= any(select id from product);
--3.all :用来将一个值与一个列表中的"所有值"进行比较。在查询中all操作之前,必须使用一个=,>,>=等比较操作符。
select id from userinfo where uid= all(select id from product);
--4.Exists :用于检查子查询所返回的行的存在性。用在select语句中。
由于Exists只检查子查询返回的行的存在性,因此查询不必返回一列,可以返回一个学量值(1).
  示例:用not exists检索从来未曾被购买过的产品
    select product_id,name from product outer
      where not exists (select 1 from purchases inner
     where inner.product_id=outer.product_id);
--5.比较Exists和In之间的区别
Exists与In不同:Exists只检查行的存在性,而In则要检查实际值的存在性.
通常来讲,Exists比In的性能要高,应尽可能使用Exists.
Not Exists与Not In的查询区别:
当一个值列表包含一个空值时,not exists就返回一个true,而not in则返回false;
 示例:not exists
   select product_type_id,name from product_type_id outer
     where not exists (select 1 from products inner
       where inner.product_type_id=outer.product_type_id)
  这个查询是有结果的.正常情况下,products产品表中不定有所有的产品类型的产品.所以这个本应是无结果.
  示例:not in
    select product_type_id,name from product_type_id 
     where product_type_id not in (select produt_type_id from     products )

========================分析函数
first()和last()
示例:查询2004年中销量最高和最低的月份
select 
 min(month) keep(dense_rank first order by sum(amount)) as     highest_sales_month,
 min(month) keep(dense_rank last order by sum(amount)) as
        lowest_sales_month
 from all_sales
 where year=2003
 group by month
 order by month;
==================查询闪回
如果错误地提交了"修改"(只是修改)操作,并想看修改的原来的值,可以使用查询闪回。然后如果需要,就可以使用查询闪回的结果将这些行手工地修改回原来的值。
----使用闪回的授权
grant execute on sys.dbms_flashback to store;
----禁用闪回操作
 execute dbms_flashback.disable();
------时间闪回
 执行dbms_flashback.enable_at_time(时间参数)过程。
24*60=1440分钟
execute dbms_flashback.enable_at_time(sysdate-10/1440);
现在再执行任何查询都将显示10分钟之前的状态。
execute dbms_flashback.disable();--禁用闪回
这时禁用闪回操作,如果再执行查询,检索结果就是当前的状态
-------系统变更号(SCN)查询闪回
这种操作比时间闪回更精确。因为数据库就是使用SCN来跟踪数据库的变化的。
--1.获得当前的SCN.
dbms_flashback.get_system_change_number();
 例如:
variable current_scn number 
 execute :current_scn:=dbms_flashback.get_system_change_number();
print current_scn
--2.运行SCN
  示例:
  insert into userinfo values('2001','abc');
  commit;
  select * from userinfo where id='2001';
execute dbms_flashback.enable_at_system_change_number(:current_scn);
现在再执行任何查询都将显示insert语句之前的状态。
execute dbms_flashback.disable();--禁用闪回
这时禁用闪回操作,如果再执行查询,检索结果就是当前的状态
---在再次启用闪回操作之前,必须先将其禁用.
===============在select中使用case
select case 
             when name='aa' then 'book'
             when name='bb' then 'video'
             else 'cd'
             end
 from idtest;
======================使用Exception(自定义)
SET SERVEROUTPUT ON 
DECLARE 
  invalidCATEGORY EXCEPTION;
  category varchar2(10);
BEGIN
  category := '&Category';
  IF category NOT IN ('附件','顶盖','备件') THEN
    RAISE invalidCATEGORY;
  ELSE
    DBMS_OUTPUT.PUT_LINE('您输入的类别是'|| category);
  END IF;
EXCEPTION
  WHEN invalidCATEGORY THEN
    DBMS_OUTPUT.PUT_LINE('无法识别该类别');
END;
=============================
数据字典视图,USER_SOURCE 包含存储过程的代码文本。

四、游标异常动态执行SQL语句 

----------------动态SQL
declare
 sql_stmt varchar2(200);
 emp_id number(4) :=7563;
 emp_rec emp%rowtype;
begin
 exceute immediate
     'create table bonusl(id number,amt number)';
--:id相当于一个参数变量。就像是java中的?
 sql_stmt:='select * from emp where empno=:id';
 exceute immediate 
       sql_stmt into emp_rec USING emp_id;
end;
------------------异常
----内置异常
 declare
 ordernum varchar2(10);
  begin
   select orderno into ordernum from order_master;
--orthers可以捕获所有错误异常。本例中的例异常是一个变量接受多行。
   exception
    when orthers then
    dbms_output.put_line('返回多行');
  end;
----用户自定异常
 declare
   invalid EXCEPTION;--定义自己定义的异常
   category varchar2(10);
 begin
   category :='&Category';--会弹出输入对话框。
   if cartegory not in ('附件','顶盖','备件') then
       RAISE invalid;---抛出自定义异常
   else
       dbms_output.put_line('你输入的类别是:'||category);
   end if;
  exception
    when invalid then
       dbms_output.put_line('无法识别该类别');
 end;
=========================================================
----------------------游标
------隐式游标
影响一行。 oracle为隐式游标的名为SQL。如insert,update,delete,select都是隐式游标。有四个属性
SQL%found :只有在DML(数据操纵语句)语句影响一行或多行时,返回true.
SQL%notfound :与上一个属性正好相反.如果DML没有影响任何行,则返回true.
SQL%rowcount :返回DML语句影响的行数.如果没有影响任何行.则返回0.
SQL%isopen:是否打开.默认是false. oracle会自动的打开或关闭隐式游标.
begin
  update order_master set ordername='rose' where orderno='123';
  if SQL%found then
    dbms_output.put_line('表已更新');
    dbms_output.put_line('影响的行数: '||SQL%rowcount);
  elsif SQL%notfound then
    dbms_output.put_line('没有更新,编号未找到');
  elsif SQL%rowcount=0 then
     dbms_output.put_line('没有影响任何行');
  end if;
end;
--------显式游标
   影响多行,可以查询返回的行集可以包含0行或多行.这些行称为活动集.游标将指向活动集中的当前行.
  open:打开游标
  fetch:从游标提取行
  close:关闭游标.
也有四个属性
显式游标名%found :如果执行最后一条fetch语句成功返回行,则%found返回为true.
显式游标名%notfound :如果执行最后一条fetch语句未能提取行时,则返回false.
显式游标名%isopen :如果游标已经打开,则返回true.
显式游标名%rowcount :返回到目前为止游标提取的行数.当第一次获取之前,%rowcount为0.当fetch语句返回一行时,则该数加1.
   declare
     myprice toys.toyprice%type;
     COUSOR toy_cur IS  --定义显工游标
       select toyprice from toys where toyprice<250;
   begin
     open toy_cur;  --打开显式游标.
     Loop
      fetch toy_cur into myprice;
      exit when toy_cur%rowcount;
      dbms_output.put_line(toy_cur%rowcount || '玩具单价:'||myprice);
    end loop;
    close toy_cur;--关闭显式游标.
   end;
-------带参数的显式游标
    declare
     dept_code emp.deptno%type;
     emp_code emp.empno%type;
     emp_name emp.ename%tepe;
  --定义游标(有参数)
     CURSOR emp_cur (detparam number) IS 
       select empno,ename from emp where deptno=deptparm(参数);
   begin
     dept_code :='&部门编号';
     open emp_cur(dept_code);--打开游标(同定义时的一样有参数)
     loop
       fetch emp_cur into emp_code,emp_name;--游标定义的查询只查询两个字段
       exit when emp_cur%notfound;
       dbms_output.put_line('在游标中提取的行数:'||toy_cur%rowcount ||emp_code ||emp_name);
     end loop;
    close emp_cur;
   end;
------循环游标可以简化显式游标,并且自动打开或关闭游标
循环游标自动创建%rowtype类型的变量并将此变量用作记录索引.语法如下:
FOR record_inder IN cursor_name
loop
  主体
end loop;
其中record_index是PL/SQL声明的记录变量.此变量的属性声明为%rowtype类型.
作用域在FOR循环之内,即在FOR循环之外不能访问此变量.
特性:
  在从游标中提取了所有记录后自动终止.提取和处理游标中的每一条记录.
  如果在提取记录之后%notfound属性返回true.则终止循环.如果未返回行,则不进入循环.
   declare
     cursor mytoy_cur IS
           select toyid,toyname,toyprice from toys;
   begin
     FOR toy_rec in mytoy_cur;--把游标赋给一个变量.这个变量称为游标变量.
     Loop
        dbms_output.put_line(
        '玩具编号:'||toy_rec.toyid || ' '
        '玩具名称:'||toy_rec.toyname || ' '
          '玩具单价:'||toy_rec.toyprice || ' ');
        --从游标中获取相应查询的三个字段
     end loop;
   end;
-----------带参数的循环游标
 语法如下:  FOR record_index IN cursor_name(parameters)
            LOOP
             主体....
            end LOOP;
------------------------REF
---------REF游标(动态游标)(隐式游标和显式游标都是静态游标)
带有返回语句的表示是强类型REF游标.不带有返回则是弱类型REF游标.
REF游标语法如下:
--声明REF CURSOR语法
Type ref_corsor_name IS REF CURSOR
[return record_type]
--打开游标语法
OPEN cursor_name FOR select_statement
----示例1
set serveroutput on
accept tabl prompt '你想查看什么信息?员工信息(E)或部门信息(D) :';
  declare
    TYPE refcur_t IS REF CURSOR; --声明REF游标
    refcur refcur_t; --这是把REF游标赋给一个游标变量吗?(声明游标类型变量)
    p_id number;
    p_name varchar2(100);
            --这不是查询,而是赋给变量
    selection varcahr2(1) :=upper(substr('&tab',1,1));
  begin
    if selection='E' then
       OPEN refcur FOR --打开游标,注意没有;号(分员)
       select empno id,ename name from emp;
        dbms_output.put_line( '==========员工信息:======');
    elsif selection='D' then
       OPEN refcur FOR --打开游标,注意没有;号(分员)
       select deptno id dname name from dept;
        dbms_output.put_line( '==========部门信息:======');
    else
       dbms_output.put_line( '请输入员工信息(E)或部门信息(D)');
       return;
    end if;
  ---前面相当于定义REF游标的内容,下面fetch相当于读取了,如同显式游标的做法
   FETCH refucr into p_id,p_name;
   while refcur%found 
    loop
      dbms_output.put_line('#'||p_id||': '||p_name);
      fetch refcur into p_id,p_name;
    end loop;
  close refcur;---关闭游标.
  end;
===============实现动态SQL的REF游标
语法:打开游标 OPEN cursor_name FOR dynamic_select_string
              [using bind_argument_list]
示例动态SQL的用法
set serveroutput on
variable maxsal number---variable:万能,常量
execute :maxsal :=2500
declare
  r_emp emp%rowtype;
  TYPE c_type IS REF CURSOR;
  cur c_type;声明游标类型变量
  p_salary number;
begin
  p_salary := :maxsal;
--:1相当于一个参数变量。就像是java中的?
  OPEN cur FOR 'select * from emp where sal>:1 order by sal desc'
  USING p_salary;
  dbms_output.put_line( '薪水大于'||p_salary||'的员工有:');
  LOOP
   FETCH cur into r_emp;
   exit when cur%notfound;
   dbms_output.put_line(
         '编号:'||r_emp.empno
      '姓名:'||r_emp.ename
        '薪水:'||r_emp.sal);
  end LOOP;
  close cur;--关闭游标
end;
===============================================
-----------游标的优点:
1.游标变量可用于从不同的结果集中提取记录
2.游标变量可作为过程的参数进行传递.
3.游标变量可以引用游标的所有属性.
4.游标变量可用于赋值运算.
-----游标受限制的地方:
1.FOR UPDATE 子名不能与游标变量一起使用
2.不允许在程序包中声明游标变量
3.另一服务器上的远程子过程不能接受游标变量参数的值
4.不能将NULL值赋给比较运算符.
5.游标变量不能使用比较运算符.
6.数据库的列不能存储游标变量
=====自我总结游标
游标是个什么东西?游标相当是一个记录集.
除隐式游标和循环游标外,显式游标和REF游标都是要OPEN(打开游标)和CLOSE(关闭游标).只有在REF游标中才有,才能把游标赋给一个变量.
首先是定义一个游标.可以把定义了的游标赋给一个变量,就成了游标变量.
一般定义的游标是一个SQL语句(如查询select * from table).
然后通过循环(loop end loop)遍历这个游标.
在REF游标中,可以通过游标变量.(点)字段名的方式得到SQL语句中的字段.

五、建表命令 

 

--在system/accp下
create table dual
(dummy varchar2(1));
-----------
create table customers
(customer_id INTEGER constraint customer_id primary key,
 first_name varchar2(10) not null,
 last_name varchar2(10) not null,
 dob date,
 phone varchar2(12));
 --这样插入行,企业管理器日期会变成01-十二月-2007 12:00:00 AM
 insert into customers values(1,'John','Brown',To_DATE('2007-12-1','YYYY-MM-DD'),'800-555-1211');
  commit;
  --设置默认的日期格式
alter session set nls_date_format='YYYY-MM-DD HH24:MI:ss';
  insert into customers values(7,'John','Brown','2006-05-10','800-555-1211');
rollback;回滚
 select * from customers;
--------主键和外键
create table products
(product_id INTEGER constraint products_pk primary key,
product_type_id INTEGER constraint product_fk_product_types references product_types(product_type_id),
name varchar2(30) not null,
description varchar2(50),
price number(5,2));
---联全主键
create table purchases
(
 product_id INTEGER constraint purchases_fk_products references products(product_id),
 customer_id INTEGER constraint purchases_fk_customers references customers(customer_id),
 quantity INTEGER not null,
 constraint purchases_pk primary key(product_id,customer_id)
);
--利用查询判断是否空值
select customer_id,first_name,last_name,dob
from customers where dob is null;
--利用where in查询
select * from customers where customer_id in (2,3,5);

 

员工基本信息表EMPINFO
 CREATE TABLE EMPINFO
 (
  EMP_ID  char(10)  PRIMARY KEY,  
 NAME  char(6) ,
 BIRTHDAY  date ,   
 SAL  number(4)      
 );
输出结果;
Table created

积分表(INTEG)共有3个字段:
 CREATE TABLE INTEG
 (
 INTEGER_ID  char(10) PRIMARY KEY,
 HABITUDE  varchar2(10),  
 SCORE number(4)    
 );
输出结果;
Table created

积分情况表:
CREATE TABLE THING
 (
EMP_ID  char(10),  
 INTEGER_id  char(10) 
 );
输出结果;
Table created

信息表表中插入相应的几条数据:
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
 VALUES ('iex_0001','王彪','12-8月-1983',600);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL) 
VALUES ('iex_0002','祝新平','11-5月-1984',600);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
VALUES ('iex_0003','谢青营','5-7月-1985',400);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
VALUES ('iex_0004','王淼','17-8月-1986',400);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
VALUES ('iex_0005','张求熙','25-9月-1984',800);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
VALUES ('iex_0006','习哲亮','14-8月-1986',1200);
INSERT INTO EMPINFO(EMP_ID, NAME, BIRTHDAY,SAL ) 
VALUES ('iex_0007','许丽丽','15-7月-1985',500);
输出结果;
1 row inserted

积分表中插入3条记录如下:
INSERT INTO INTEG values('I_001','公司类别',4);
INSERT INTO INTEG values('I_002','学习类别',2.5);
INSERT INTO INTEG values('I_003','协作类别',2.5);
INSERT INTO INTEG values('I_004','其他类别',1);
输出结果;
1 row inserted 

积分情况表插入6条如下;
INSERT INTO THING values('iex_0001','I_001');
INSERT INTO THING values('iex_0001','I_002');
INSERT INTO THING values('iex_0002','I_003');
INSERT INTO THING values('iex_0002','I_002');
INSERT INTO THING values('iex_0004','I_004');
INSERT INTO THING values('iex_0005','I_001');
输出结果;
1 row inserted 
 
1,查询员工基本信息表中的所有信息
 select * from EMPINFO;
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
iex_0001   王彪   1983-8-12     600
iex_0002   祝新平 1984-5-11     600
iex_0003   谢青营 1985-7-5      400
iex_0004   王淼   1986-8-17     400
iex_0005   张求熙 1984-9-25     800
iex_0006   习哲亮 1986-8-14    1200
iex_0007   许丽丽 1985-7-15     500

2、    查询员工基本信息表中所有员工的员工编号,姓名和薪水。
select EMP_ID,NAME,SAL from EMPINFO;
输出结果;
EMP_ID     NAME     SAL
---------- ------ -----
iex_0001   王彪     600
iex_0002   祝新平   600
iex_0003   谢青营   400
iex_0004   王淼     400
iex_0005   张求熙   800
iex_0006   习哲亮  1200
iex_0007   许丽丽   500

3、    查询所有员工的姓名,出生年月,并在出生年月前显示“出生日期”字串。
select name,'出生年月'||BIRTHDAY from EMPINFO;
输出结果;
NAME   '出生年月'||BIRTHDAY
------ --------------------
王彪   出生年月12-8月 -83
祝新平 出生年月11-5月 -84
谢青营 出生年月05-7月 -85
王淼   出生年月17-8月 -86
张求熙 出生年月25-9月 -84
习哲亮 出生年月14-8月 -86
许丽丽 出生年月15-7月 -85

4、    查询员工基本信息表中的所有信息,要求列标题显示为中文。
 select EMP_ID as 员工编号,NAME as 员工姓名,BIRTHDAY as 出生日期,SAL as 薪水 from EMPINFO;
输出结果;
   员工姓名 出生日期     薪水
---------- -------- ----------- -----
iex_0001   王彪     1983-8-12     600
iex_0002   祝新平   1984-5-11     600
iex_0003   谢青营   1985-7-5      400
iex_0004   王淼     1986-8-17     400
iex_0005   张求熙   1984-9-25     800
iex_0006   习哲亮   1986-8-14    1200
iex_0007   许丽丽   1985-7-15     500

5、    查询员工基本信息表中姓名和加200后的薪水。
update EMPINFO set SAL=sal+200;
select NAME,SAL from EMPINFO;
输出结果;
NAME     SAL
------ -----
王彪     800
祝新平   800
谢青营   600
王淼     600
张求熙  1000
习哲亮  1400
许丽丽   700

6、    查询员工基本信息表中姓名和负值薪水。
select NAME,SAL from EMPINFO where sal<0;
输出结果;
NAME     SAL
------ -----

7、    查询员工基本信息表中姓名及提高5%后的薪水。
update EMPINFO set SAL=sal*1.5;
select NAME,SAL from EMPINFO;
输出结果;
NAME     SAL
------ -----
王彪    1200
祝新平  1200
谢青营   900
王淼     900
张求熙  1500
习哲亮  2100
许丽丽  1050

8、    查询员工基本信息表中姓名及一个月中每天的薪水。
select NAME,SAL/30 as 每天的薪水 from EMPINFO;
输出结果;
NAME   每天的薪水
------ ----------
王彪           40
祝新平         40
谢青营         30
王淼           30
张求熙         50
习哲亮         70
许丽丽         35

9、    查询积分表中的所有信息,要求输出格式为“XXX----XXX----XXX----XXX”。
select INTEGER_ID,'----'||HABITUDE,'----'||SCORE from INTEG;
输出结果;
INTEGER_ID '----'||HABITUDE '----'||SCORE
---------- ---------------- --------------------------------------------
I_001      ----公司类别     ----4
I_002      ----学习类别     ----3
I_003      ----协作类别     ----3
I_004      ----其他类别     ----1

10、    查询员工基本信息表中薪水低于300员的所有员工信息。
select * from EMPINFO where SAL<300;
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----

11、    查询姓名是“王彪”的员工信息。
select * from EMPINFO where name='王彪';
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
iex_0001   王彪   1983-8-12    1200

12、    查询薪水在300至600之间的员工信息。
 select * from EMPINFO where sal>300 and sal<600;
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
13、    查询出生年月在“1-5月-1983”至“31-12月-1986”之间的所有员工信息。
SQL> select * from EMPINFO where BIRTHDAY>'1-5月-1983' and BIRTHDAY<'31-12月-1986';
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
iex_0001   王彪   1983-8-12    1200
iex_0002   祝新平 1984-5-11    1200
iex_0003   谢青营 1985-7-5      900
iex_0004   王淼   1986-8-17     900
iex_0005   张求熙 1984-9-25    1500
iex_0006   习哲亮 1986-8-14    2100
iex_0007   许丽丽 1985-7-15    1050

14、    查询积分编号为“I_001”和“I_004”,“I_002”的所有信息。
select * from INTEG where INTEGER_ID='I_001' or INTEGER_ID='I_004' or INTEGER_ID='I_002';
输出结果;
INTEGER_ID HABITUDE   SCORE
---------- ---------- -----
I_002      学习类别       3
I_004      其他类别       1
I_001      公司类别       4

15、    查询所有姓王的员工信息。
select * from EMPINFO where name LIKE '王%';
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
iex_0001   王彪   1983-8-12    1200
iex_0004   王淼   1986-8-17     900

16、    查询没有登记出生年月的员工信息。
select * from EMPINFO where BIRTHDAY=null;
输出结果;

EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----

17、    查询公司的薪水发放标准。
?
18、    查询员工编号为iex_0001完成的积分总数。
select THING.EMP_ID,INTEG.SCORE from THING join INTEG on THING.Emp_Id='iex_0001';
输出结果;
EMP_ID     SCORE
---------- -----
iex_0001       4
iex_0001       4
iex_0001       3
iex_0001       3
iex_0001       3
iex_0001       3
iex_0001       1
iex_0001       1

--错了19、    查询习哲亮的所有信息,并把他的出生年月推迟一个月。
 select EMP_ID, NAME,SAL,BIRTHDAY from EMPINFO where name='习哲亮';

20、    查询习哲亮出生那个月的最后一天。
 select EMP_ID, NAME,SAL,BIRTHDAY from EMPINFO where name='习哲亮';

23、    查询今天的日期。
 SELECT TO_CHAR(sysdate,'YYYY"年"fmMM"月"fmDD"日"') FROM dual;
输出结果;
TO_CHAR(SYSDATE,'YYYY"年"FMMM"
------------------------------
2007年3月29日

24、    查询所有员工信息,按薪水的升序显示
 select * from EMPINFO order by SAL;
输出结果;
EMP_ID     NAME   BIRTHDAY      SAL
---------- ------ ----------- -----
iex_0003   谢青营 1985-7-5      900
iex_0004   王淼   1986-8-17     900
iex_0007   许丽丽 1985-7-15    1050
iex_0001   王彪   1983-8-12    1200
iex_0002   祝新平 1984-5-11    1200
iex_0005   张求熙 1984-9-25    1500
iex_0006   习哲亮 1986-8-14    2100

25、    对员工基本信息表和积分情况表进行非限制连接查询员工编号,姓名,积分编号;

 

六、日志触发器 

 

--建立一张日志表及触发器
create table logger(shijian date,name varchar(10),rema varchar2(100),oper varchar(10))

--before 在。。之前 after 在。。之后
--用户表
create or replace trigger cuidake before insert or delete or update 
--for each row 行触发
on first for each row
declare
 cdk1 varchar2(10);
begin
--dual 系统表 user在此系统中为用户
 select user into cdk1 from dual;
 if(inserting) then
 insert into logger values(sysdate,cdk1,'用户你插入的姓名是:'||:new.name||'年龄是:'||:new.age,'insert');
 end if;
 if(deleting) then
 insert into logger values(sysdate,cdk1,'用户你删除的姓名是:'||:old.name||'年龄是:'||:old.age||'的人','delete');
 end if;
 if(updating) then
 insert into logger values(sysdate,cdk1,'用户你更新了姓名是:'||:old.name||'年龄是:'||:old.age||'的人,更新为姓名为'||:new.name||'年龄为:'||:new.age,'update');
 end if;
end;
insert into first values('老汉','26')
update first set age=22 where name='老汉'
delete first where name='老汉'

select * from first 
  

select * from logger
================ 1.创建一个触发器,无论用户插入新记录,还是修改emp表的JOB列,都将用户指定的JOB列的值转换成大写.
说明。dual表是数据库本身就具有的表,主要作用是临时存放数据的。如
tempName varchar2(10);
select name into tempName from dual;
---------------
create  table aa
(
 id varchar2(10),
 name varchar2(10)
);
create or replace trigger tri_upper
before insert or update of name
on aa
for each row
declare
tempStr varchar2(10);
begin
 if (inserting) then
  select upper(:new.name) into :new.name from dual;
 end if;
 if (updating) then
  select upper(:new.name) into :new.name from dual where :new.id=:old.id;
 end if;
end ;
insert into aa values('2','aaa');
select * from aa;
update aa set name='fff' where id='1';

select sysdate as aa from dual;
 drop table dual;
 drop table aa;

 

posted @ 2014-01-23 10:39  若 ♂ 只如初见  阅读(842)  评论(0编辑  收藏  举报