Oracle 原理: 數據類型

一、PL/SQL 的數據類型和用法

PL/SQL可以使用變量和常量。變量賦值用兩種方式:一種是 :=    還有一種是 select .. into [變量],變量聲明語法:

變量名 [constraint]  數據類型 [NOT NULL] [ :=  | DEFAULT 表達式]

創建表,初始化表

drop table salary_tbl;

create   table salary_tbl(
   employer_nm varchar(20),
   department varchar(20) not null,
   salary number not null,
   leader_nm varchar(20)
);
truncate table salary_tbl;
declare
 totalnum number := 130000;
begin
 for i in  1..totalnum
     loop
     insert into salary_tbl values('僱傭者'||i,'部門'||Mod(i,50),100+sqrt(i),'僱傭者'||Mod(i,20)); 
     if Mod(i,1000)=0 then 
       commit;
     end if;
   end loop;
end; 
/
commit;

當過程寫錯時,可以show error 來看編譯錯誤信息

PL/SQL支持的內置數據類型有三種:標量類型、LOB類型、屬性類型;

標量類型 包含了:日期時間、數字、字符、布爾型。

日期類型包括了:DATE類型、TIMESTEMP類型

數字類型包括了BINARY_INTEGER類型(表示一個有符號整數,表示的範圍爲-2的31次方到2的31次方),此類型中的子類型有:SIGNTYPE(正負符號,只能取-1,,0,1)、POSITIVEN(非空正整數),POSITIVE(正整數)、NATURALLN(非空自然數)、NATURAL(自然數);數字類型包括了NUMBER類型,子類型包括了 DECIMAL(精確的小數,可存儲 38 個數字),FLOAT(單精度浮點型採用四捨五入的方法近似)、INTEGER(可以簡寫爲INT,和NUMBER(38)相同)、REAL(實數,雙精度浮點型採用四捨五入的方法近似);數字類型包括了PLS_INTERGER類型,(有符號的整數,適用於複雜的運算)。SIMPLE_INTEGER 是11g的新的數據類型(直接作用於硬件的數據類型,大大提高性能可存值 -2^31 ~2^31-1)

字符類型包括了char類型、varchar2、long(最多2GB的字符數據)類型、raw(最多4KB二進制數據)、long raw(最多2GB的二進制數據) 類型。

布爾類型 boolean

LOB類型 包含了:BFILE、BLOB、CLOB、NCLOB類型,用於存儲大文本、圖像、視頻、聲音可存儲4GB

BLOB:存儲二進制對象;CLOB存儲大型字符數據;NCLOB,存儲UNICODE字符數據;BFILE 存儲二進制對象在操作系統文件中,數據庫只存放 BFILE文件的指針。LOB類型無法通過select 語句完整的讀取數據。需要通過PL/SQL才能實現

 

屬性類型 包含了:%TYPE 表某一列的字段類型, %ROWTYPE表某一行的數據類型。

二、Oracle11g 中隊LOB類型進行操作的方法,即

create  table file_lobtest(
   filePath varchar2(50),
   clob_content clob ,
   blob_content blob ,
   bfile_content bfile
);
truncate table file_lobtest;
declare 
content_test clob := '我與父親不相見已二年餘了,我最不能忘記的是他的背影。那年冬天,祖母死了,父親的差使也交卸了,正是禍不單行的日子,我從北京到徐州,打算跟着父親奔喪回家。到徐州見着父親,看見滿院狼藉的東西,又想起祖母,不禁簌簌地流下眼淚。父親說,“事已如此,不必難過,好在天無絕人之路!”
  回家變賣典質,父親還了虧空;又借錢辦了喪事。這些日子,家中光景很是慘淡,一半爲了喪事,一半爲了父親賦閒。喪事完畢,父親要到南京謀事,我也要回北京唸書,我們便同行。
  到南京時,有朋友約去遊逛,勾留了一日;第二日上午便須渡江到浦口,下午上車北去。父親因爲事忙,本已說定不送我,叫旅館裏一個熟識的茶房陪我同去。他再三囑咐茶房,甚是仔細。但他終於不放心,怕茶房不妥帖;頗躊躇了一會。其實我那年已二十歲,北京已來往過兩三次,是沒有甚麼要緊的了。他躊躇了一會,終於決定還是自己送我去。我兩三回勸他不必去;他只說,“不要緊,他們去不好!”
  我們過了江,進了車站。我買票,他忙着照看行李。行李太多了,得向腳伕行些小費,纔可過去。他便又忙着和他們講價錢。我那時真是聰明過分,總覺他說話不大漂亮,非自己插嘴不可。但他終於講定了價錢;就送我上車。他給我揀定了靠車門的一張椅子;我將他給我做的紫毛大衣鋪好坐位。他囑我路上小心,夜裏警醒些,不要受涼。又囑託茶房好好照應我。我心裏暗笑他的迂;他們只認得錢,託他們直是白託!而且我這樣大年紀的人,難道還不能料理自己麼?唉,我現在想想,那時真是太聰明瞭!
  我說道,“爸爸,你走吧。”他望車外看了看,說,“我買幾個橘子去。你就在此地,不要走動。”我看那邊月臺的柵欄外有幾個賣東西的等着顧客。走到那邊月臺,須穿過鐵道,須跳下去又爬上去。父親是一個胖子,走過去自然要費事些。我本來要去的,他不肯,只好讓他去。我看見他戴着黑布小帽,穿着黑布大馬褂,深青布棉袍,蹣跚地走到鐵道邊,慢慢探身下去,尚不大難。可是他穿過鐵道,要爬上那邊月臺,就不容易了。他用兩手攀着上面,兩腳再向上縮;他肥胖的身子向左微傾,顯出努力的樣子。這時我看見他的背影,我的淚很快地流下來了。我趕緊拭乾了淚,怕他看見,也怕別人看見。我再向外看時,他已抱了硃紅的橘子望回走了。過鐵道時,他先將橘子散放在地上,自己慢慢爬下,再抱起橘子走。到這邊時,我趕緊去攙他。他和我走到車上,將橘子一股腦兒放在我的皮大衣上。於是撲撲衣上的泥土,心裏很輕鬆似的,過一會說,“我走了;到那邊來信!”我望着他走出去。他走了幾步,回過頭看見我,說,“進去吧,裏邊沒人。”等他的背影混入來來往往的人裏,再找不着了,我便進來坐下,我的眼淚又來了。
  近幾年來,父親和我都是東奔西走,家中光景是一日不如一日。他少年出外謀生,獨力支持,做了許多大事。那知老境卻如此頹唐!他觸目傷懷,自然情不能自已。情鬱於中,自然要發之於外;家庭瑣屑便往往觸他之怒。他待我漸漸不同往日。但最近兩年的不見,他終於忘卻我的不好,只是惦記着我,惦記着我的兒子。我北來後,他寫了一信給我,信中說道,“我身體平安,惟膀子疼痛利害,舉箸提筆,諸多不便,大約大去之期不遠矣。”我讀到此處,在晶瑩的淚光中,又看見那肥胖的,青布棉袍,黑布馬褂的背影。唉!我不知何時再能與他相見!'; 
 
begin
    insert into file_lobtest values('F:\\sqllobtest',content_test,null,null); 
end; 
/
commit;

select * from file_lobtest 查看結果如下

可以看見,除了在PL/SQL develop點擊"..."查看。select 是不能看到完整內容的。查詢完整的CLOB需要用過程或者函數來實現。

在SQL命令窗口或者SQLPLUS下

select to_char(Clob_content) from file_lobtest; 或者

set serveroutput on;
declare 
 clob_var clob;
 amount INTEGER :=5000;
 offset INTEGER :=1;
 output_var varchar2(5000);
begin
 select clob_content into clob_var from file_lobtest where filepath='F:\c.txt'; 
 dbms_lob.read(clob_var,amount,offset,output_var);
 dbms_output.put_line(output_var );  
--不用緩存時直接 dbms_output.put_line(clob_var );  
end;
/

就能看見全部值了,如果緩存區太小就增加些

 

插入BFILE 和BLOB需要用到存儲過程來插入,示例如下

create or replace procedure insertBlob(ifilepath in  varchar2,ifilename  in varchar2  )
authid current_user is
       img_file bfile;
       img_blob blob;
       lob_length number;
       sqlcommand  varchar2(500); 
       isexit number;
begin
   ----動態SQL,需要相應權限 create table  read,write on directory等 ---
     --設置虛擬路徑
     sqlcommand :='create or replace directory PHOTOPATH as ''' ||ifilepath ||'''' ;
     execute immediate sqlcommand;
      --獲取bfile文件
     img_file := bfilename('PHOTOPATH',ifilename);
       --打開文件
     dbms_lob.open(img_file);
     --獲取文件長度
     lob_length := dbms_lob.getlength(img_file);
     --判斷文件是否存在,先把blob設成empty_blob()
     select count(1) into isexit from file_lobtest t1 where t1.filepath = ifilepath;
     if isexit = 0 then 
        insert into file_lobtest values(ifilepath,null,empty_blob(),img_file);
     else 
        update file_lobtest t1 set bfile_content=img_file,blob_content=empty_blob() where t1.filepath = ifilepath;
     end if ;
       --然後賦值blob變量
     select blob_content into img_blob from file_lobtest t1 where t1.filepath = ifilepath;
       --加載blob
     dbms_lob.loadfromfile(img_blob,img_file,lob_length);
     --關閉文件
     dbms_lob.close(img_file);
     commit;
end;

編譯完後,在本地文件路徑上放個照片

調用存儲過程

begin
insertBlob ('F:\\sqllobtest','aaa.jpg');
end;
/

查看得到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章