zoukankan      html  css  js  c++  java
  • 初次使用Oracle

      这是我第一次写博客,主要是记录下自己这半个多月以来的学习笔记,以备以后可以随时查看。

      首先就是安装Oracle的问题的,我系统是Win7 64位的,出现各种问题郁闷得不行,最终安装个Oracle10203_vista_w2k8_x86_client客户端连接公司的服务器暂时先用着吧,如果需要使用Odbc则需在C:WindowsSysWOW64odbcad32.exe上的系统DSN中添加Odbc的驱动管理,选择Oracle in OraClient10g_home1,有很多警告框的不用管它,Data Source Name的名称是Odbc连接字符串中的DSN名称,其他的就不罗嗦了。

      安装完客户端就安装PLSQL+Developer9.0.2来操作数据库了,默认是英文的,只要把Chinese.lang文件放到pl/sql安装目录下,再Tools->Preferences->Appearance的Language里选择Chinese.lang就可以了,为了能更加快速的找到Tables等文件夹的信息,随便把工具->浏览器文件夹中的Tables、Procedures、Indexes、Functions、Triggers、Views、Sequences、Tablespaces、Packages、Roles、Users移到最上面并将颜色设为蓝色,把工具->浏览器过滤器中的My objects设为默认,最后按照自己的习惯,把窗口的位置调整下,选择窗口->保存版面,好了,大功告成了。

    现在开始Oracle的学习了,Oracle跟SQL Server很大的一个不同点就是Oracle使用表空间这一个概念,我感觉表空间就类似SQL Server的一个数据库了,然后Oracle中没有SQL Server中的自增这一概念,不过可以使用Sequences代替,使用方法是:

    1 CREATE SEQUENCE Seq_test
    2   
    3   INCREMENT BY 1  -- 每次加几个
    4   START WITH 1   -- 从1开始计数
    5   NOMAXVALUE    -- 不设置最大值
    6   NOCYCLE     -- 一直累加,不循环
    7   CACHE 10;

    创建完之后就可以直接使用了

    insert tb_Test(tId,tName) values(Seq_test.NEXTVAL,'测试');
    select Seq_test.CURRVAL from dual;    --返回当前的序列值

    注意第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。而dual是一个伪表,不用自己创建的,只是为了操作上的方便而存在的,例如select返回的变量,入日期等。

    使用Oracle最开始就是先创建表空间跟用户了

     1 -----------------创建表空间-----------------------------
     2 create tablespace DBTest_tbs                          --一般建N个存数据的表空间和一个索引空间
     3 datafile 'E:OracleoradataDBTest_tbsOrdering.dbf'  --表空间的路径
     4 size 100M                                             --大小
     5 autoextend on                                         --自动增长
     6 --定义大小的命令
     7 next 1M maxsize 1000M extent management local;
     8 --删除表空间
     9 --drop tablespace DBTest_tbs including contents and datafiles cascade constraints;
    10 --创建临时表空间
    11 create temporary tablespace DBTest_temp
    12 tempfile 'E:OracleoradataDBTest_tbsTemp.dbf' size 100M autoextend on next 1M maxsize 1000M extent management local;
    13 --创建索引表空间
    14 create tablespace DBTest_index
    15 datafile 'E:OracleoradataDBTest_tbsIndex.dbf' size 100M extent management local;

    然后就是创建用户了

     1 create user DBTest_user identified by 441821
     2 default tablespace DBTest_tbs
     3 temporary tablespace DBTest_temp;
     4 --授权
     5 --一般授予的权限:create session,create table,unlimited tablespace;
     6 --对象权限:用户创建的表属于用户自己的,想给被所有人用,则grant all on table to public;
     7 --可以指定列的权限:grant update(name) on tb to DBTest_user;
     8 grant connect,resource,dba to DBTest_user;
     9 --收权
    10 Revoke dba from DBTest_user;

    创建完用户并授予相应的权限就可以创建表之类的DDL操作了,具体语法跟T-SQL语法差不多的,注意一下Oracle的数据类型就可以了。

    然后记录下PL/SQL的基本使用方法:

     1 ----------------------PL/SQL语句基础------------------------
     2 --merge into的用法,通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,
     3 --连接条件匹配上的进行UPDATE,无法匹配的执行INSERT,效率要高于INSERT+UPDATE
     4 merge into fzq1 aa --fzq1表是需要更新的表
     5   using fzq bb -- 关联表
     6   on (aa.id=bb.id) --关联条件
     7   when matched then --匹配关联条件,作更新处理
     8   update set
     9   aa.chengji=bb.chengji+1,
    10   aa.name=bb.name --此处只是说明可以同时更新多个字段。
    11   when not matched then --不匹配关联条件,作插入处理。如果只是作更新,下面的语句可以省略。
    12   insert values( bb.id, bb.name, bb.sex,bb.kecheng,bb.chengji);
    13 
    14 --pl/sql语句块
    15 declare
    16 ecount tb_food.count%Type;  --定义表中的字段类型
    17 eno number;
    18 eresult number;
    19 food tb_food%rowtype;       --定义表类型,只能存储一条记录
    20 begin
    21   eno:=&no;                 --要用户输入信息
    22   select count into ecount from tb_food where foodID='F001';
    23   select * into food from tb_food where foodID='F001';
    24   eresult:=ecount/eno;
    25   dbms_output.put_line(ecount||'/'||eno||'='||eresult);
    26   dbms_output.put_line(food.FoodID);
    27 exception  --捕捉异常
    28   when zero_divide then
    29     dbms_output.put_line('error');
    30   end;
    31 / --执行语句
    32 
    33 --loop循环
    34 declare
    35 cou number;
    36 begin
    37   cou:=1;
    38 loop
    39   dbms_output.put_line('cou='||cou);
    40   exit when cou>10;
    41   cou:=cou+1;
    42   end loop;
    43 end;
    44 /
    45 
    46 --while循环
    47 declare
    48 cou number;
    49 begin
    50   cou:=1;
    51   while(cou<10)
    52   loop
    53     dbms_output.put_line('cou='cou);
    54     cou:=cou+1;
    55     end loop;
    56 end;
    57 /
    58 
    59 --for循环
    60 declare
    61 cou number;
    62 begin
    63   for cou in 1..10 loop
    64     dbms_output.put_line('cou='||cou);
    65     end loop;
    66  end;
    67  /
    68  
    69 --if...else语句
    70 declare
    71 cou number;
    72 begin
    73   cou:=1;
    74   if cou>10 then
    75     dbms_output.put_line('cou='||cou);
    76     else
    77       dmbs_ouput.put_line(条件不满足);
    78   end if;
    79 end;
    80 /
    81 
    82 --goto语句
    83 declare
    84 eID tb_food.FoodID%Type;
    85 ecount tb_food.Count%Type;
    86 begin
    87   eID:=%ne;
    88   select count into ecount from tb_food where FoodID=eID;
    89   if ecout>5 then
    90     goto po1;
    91     else 
    92       goto po2;
    93    end if;
    94    <<po1>>dbms_output.put_line('数量大于5');
    95    <<po2>>dbms_output.put_line('数量小于等于5');
    96 end;
    97 /
    View Code

    注意:PL/SQL中的赋值是使用":="代替的,而字符串连接则使用"||"代替。

    创建函数的方法:

     1 create or replace function myfun(fid tb_food.foodID%type)
     2 return number
     3 as
     4 Fname narchar2;
     5    select FoodName into Fname from tb_food where FoodId=fid;
     6    return Fname;
     7 end;
     8 /
     9 --调用函数
    10 select myfun('F001') from dual;

    创建存储过程的方法:

     1 create or replace procedure myproc
     2 (fid in out tb_food.foodId%type)  --带值进带值出
     3 as
     4 cou number;
     5 v_id char;
     6 begin
     7   select count(*) into cou from tb_food where foodId=fid;
     8   if cou=0 then   --不存在ID
     9     insert into tb_food values(fid,'名称');
    10     else   --已存在,不能插入
    11       fid:=-1;
    12    end if;
    13 end;
    14 /
    15       
    16 --执行存储过程
    17 declare
    18 fid tb_food.foodid%type;
    19 begin
    20   fid:='F001';
    21   myproc(fid);
    22   dbms_output.put_line(fid);   
    23 end;
    24 /
    25 
    26 --删除存储过程
    27 drop procedure myproc;

    注意:存储过程返回数据集不像SQL Server的一样直接select就可以了,需要使用游标来存储数据集,具体使用方法如下:

     1 --带结果集的存储过程
     2 --创建包
     3 create or replace package pak_test
     4 is type refcursor is ref cursor;
     5 procedure pro_test(cur out refcursor);
     6 end;
     7 /
     8 --创建包体
     9 create or replace package body pak_test is
    10  procedure pro_test
    11 (cur out refcursor)
    12 is
    13 begin
    14   open cur for
    15   select * from tb_food;
    16   return;
    17  end;
    18 end;
    19 /
    20 
    21 --执行存储过程
    22 declare
    23 v_cur pak_test.refcursor;
    24 v_food tb_food%rowtype;
    25 begin
    26   pak_test.pro_test(v_cur);
    27   FETCH v_cur INTO v_food;
    28   WHILE v_cur%FOUND LOOP
    29      DBMS_OUTPUT.PUT_LINE(v_food.FoodID);
    30      FETCH v_cur INTO v_food;
    31   END LOOP;
    32 end;
    33 /

    创建触发器的方法:

     1 --------触发器------------
     2 --触发器不能从触发器所对应的基本中读取数据,否则执行时会出错
     3 --Before语句触发器
     4 create or replace trigger tr_src_emp
     5 before insert or update or delete on emp
     6 begin
     7   if to_char(sysdate,'DY','nls_date_language=AMERICAN') in('SAT','SUN') then
     8     raise_application_error(-20001,'工作人员不能在周末改变雇员信息');
     9   end if;
    10 end;
    11 /
    12 
    13 --Bofre行触发器,没作用一行就触发一次触发器
    14 create or replace trigger tr_emp_sal
    15 before update of sal on emp
    16 for each row
    17   begin
    18     if:new.sal<:old.sal then
    19     raise_application_error(-20010,'员工工资不能低于原有工资');
    20     end if;
    21   end;
    22 /
    23 
    24 --限制行触发器
    25 create or replace trigger tr_sal_sal
    26 after update of sal on emp
    27 for each row
    28   when (old.job='salesman')
    29 declare
    30 v_temp int;
    31 begin
    32   select count(*) into v_temp from emp where name=:old.name;
    33   if v_temp=0 then
    34     insert into emp values(:old.name,:old.sal,:new.sal);
    35    else
    36      update emp set oldsal=:old.sal,newsal=:new.sal where name=:old.name;
    37   end if;
    38 end;
    39 /

    动态执行SQL语句的方法:

     1 ----------动态执行SQL语句------------
     2 declare
     3   sql_stmt varchar2(200);  --动态SQL语句
     4   kind_name nvarchar2(50):='测试';
     5   kind_id tb_foodKind.Kindid%type:='55';
     6   cur_foodkind tb_foodKind%rowtype;
     7 begin
     8   --无子句的execute immediate
     9   execute immediate 'create table t_test(id number)';  
    10   --using子句的execute immediate
    11   sql_stmt:='insert into tb_foodKind(kindid,KindName) values(:1,:2)';
    12   execute immediate sql_stmt using kind_id,kind_name;
    13   --into子句的execute immediate
    14   --sql_stmt:='select * from tb_foodkind where kindID=:1';
    15   execute immediate sql_stmt into cur_foodkind using kind_id;
    16   dbms_output.put_line(cur_foodkind.kindid);
    17   --returning into子句的execute immediate
    18   --returning 可以把操作影响行中的数据返回
    19   sql_stmt:='update tb_foodkind set kindname=''西瓜'' where kindid=:1 returning kindname into :2';
    20   execute immediate sql_stmt using kind_id returning into kind_name;
    21   dbms_output.put_line(kind_name);
    22  end;
    23 /

      最后,讲一下在C#中操作Oracle数据库,我使用的是Odbc连接数据库的,连接字符串是"DSN=testdb;uid=dbtest;pwd=dbtest",DSN就是之前添加的ODBC驱动名称,其他的也就跟Sql的差不多了,还需要注意的是使用OdbcParameter参数的SQL语句中,参数的要用"?"作为替代符,例如"select * from tb_foodKind where KindID=?",而且如果想使用ODBC来调用存储过程,存储过程中如果存在参数,则需要使用cmd.CommandText = "{call pro_AddPackageDetail(?,?,?,?,?)}"这样的格式才能执行,如果没有参数则可以直接使用存储过程名称。

      好了,暂时就先记录到这里了,如果以后有继续学到更多的知识再来补充。

  • 相关阅读:
    如何闪开安装VS2013必须要有安装IE10的限制
    Java从键盘输入
    Java基本数据类型和关键字
    openssl windows编译 32位&64位
    eclipse代码提示配置
    手动启动Android模拟器
    Android编程中的实用快捷键
    pat1023. Have Fun with Numbers (20)
    pat1022. Digital Library (30)
    pat1020. Tree Traversals (25)
  • 原文地址:https://www.cnblogs.com/wszshz/p/3525147.html
Copyright © 2011-2022 走看看