这是我第一次写博客,主要是记录下自己这半个多月以来的学习笔记,以备以后可以随时查看。
首先就是安装Oracle的问题的,我系统是Win7 64位的,出现各种问题郁闷得不行,最终安装个Oracle10203_Vista_w2k8_x86_client客户端连接公司的服务器暂时先用着吧,如果需要使用Odbc则需在C:/Windows/SysWOW64/odbcad32.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_test2 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:/Oracle/oradata/DBTest_tbs/Ordering.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_temp12 tempfile 'E:/Oracle/oradata/DBTest_tbs/Temp.dbf' size 100M autoextend on next 1M maxsize 1000M extent management local;13 --创建索引表空间14 create tablespace DBTest_index15 datafile 'E:/Oracle/oradata/DBTest_tbs/Index.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 declare16 ecount tb_food.count%Type; --定义表中的字段类型17 eno number;18 eresult number;19 food tb_food%rowtype; --定义表类型,只能存储一条记录20 begin21 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 then29 dbms_output.put_line('error');30 end;31 / --执行语句32 33 --loop循环34 declare35 cou number;36 begin37 cou:=1;38 loop39 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 declare48 cou number;49 begin50 cou:=1;51 while(cou<10)52 loop53 dbms_output.put_line('cou='cou);54 cou:=cou+1;55 end loop;56 end;57 /58 59 --for循环60 declare61 cou number;62 begin63 for cou in 1..10 loop64 dbms_output.put_line('cou='||cou);65 end loop;66 end;67 /68 69 --if...else语句70 declare71 cou number;72 begin73 cou:=1;74 if cou>10 then75 dbms_output.put_line('cou='||cou);76 else77 dmbs_ouput.put_line(条件不满足);78 end if;79 end;80 /81 82 --goto语句83 declare84 eID tb_food.FoodID%Type;85 ecount tb_food.Count%Type;86 begin87 eID:=%ne;88 select count into ecount from tb_food where FoodID=eID;89 if ecout>5 then90 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 /
注意: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 declare18 fid tb_food.foodid%type;19 begin20 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 is10 procedure pro_test11 (cur out refcursor)12 is13 begin14 open cur for15 select * from tb_food;16 return;17 end;18 end;19 /20 21 --执行存储过程22 declare23 v_cur pak_test.refcursor;24 v_food tb_food%rowtype;25 begin26 pak_test.pro_test(v_cur);27 FETCH v_cur INTO v_food;28 WHILE v_cur%FOUND LOOP29 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_sal15 before update of sal on emp16 for each row17 begin18 if:new.sal<:old.sal then19 raise_application_error(-20010,'员工工资不能低于原有工资');20 end if;21 end;22 /23 24 --限制行触发器25 create or replace trigger tr_sal_sal26 after update of sal on emp27 for each row28 when (old.job='salesman')29 declare30 v_temp int;31 begin32 select count(*) into v_temp from emp where name=:old.name;33 if v_temp=0 then34 insert into emp values(:old.name,:old.sal,:new.sal);35 else36 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 immediate11 sql_stmt:='insert into tb_foodKind(kindid,KindName) values(:1,:2)';12 execute immediate sql_stmt using kind_id,kind_name;13 --into子句的execute immediate14 --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 immediate18 --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(?,?,?,?,?)}"这样的格式才能执行,如果没有参数则可以直接使用存储过程名称。
好了,暂时就先记录到这里了,如果以后有继续学到更多的知识再来补充。
新闻热点
疑难解答