初次使用Oracle


  這是我第一次寫博客,主要是記錄下自己這半個多月以來的學習筆記,以備以后可以隨時查看。

  首先就是安裝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_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:\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_temp
12 tempfile 'E:\Oracle\oradata\DBTest_tbs\Temp.dbf' size 100M autoextend on next 1M maxsize 1000M extent management local;
13 --創建索引表空間
14 create tablespace DBTest_index
15 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 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(?,?,?,?,?)}"這樣的格式才能執行,如果沒有參數則可以直接使用存儲過程名稱。

  好了,暫時就先記錄到這里了,如果以后有繼續學到更多的知識再來補充。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM