1、在oracle項目開發中越到問題:html
在利用ODP向oracle中插入數據時,若是這樣寫:
insert into clobTable (id, story) values(1,'....'); 其中story爲clob類型
若是story的長度大於2000字節,直接插入將出現 ORA-01704:文字字符串過長 的錯誤。
解決方案:
方案1、利用參數
insert into clobTable (id, story) values(1,:story);
OracleParameter param = new OracleParameter("story", OracleDbType.Clob);
param.Direction = ParameterDirection.Input;
param.Value = str;
cmd.Parameters.Add(param);
方案2、利用存儲過程
這個就不用說了,寫個存儲過程,把參數傳入便可。sql
2、解決方法session
oracle 中,以下操做:oracle
insert into table values(a,3,'一個長文章');函數
ORA-01704: 文字字符串過長!post
雖然在表中已是clob字段,足夠存儲4G的內容,可是若是存的是特別長的字符串,超過4000就會報錯。學習
解決方法:測試
方法一:就寫個存儲過程,而後用參數傳過去就沒問題了。spa
declarecode
v_clob clob :='一個長文章';
begin
insert into table values(a,3,:clob);
end;
這樣就能夠插進去了,因此我以爲應該是隱式轉換,oracle默認把字符串 轉換成 varchar2 類型,
而這個字符串的長度,又比4000大 因此會報ora-01704錯誤.
真實環境用的存儲過程:
CREATE OR REPLACE PROCEDURE "BAI"."LOGMNRTXT" (tab1 in varchar2,scns in number,timestamps in varchar2,seg_owner in varchar2,
table_name in varchar2,session_info in varchar2,sql_redo in clob,ssession in varchar2,serial in varchar2,operation in varchar2) is
str varchar(1000);
--注意tab1必需要更改,發現原來的logmnr_contents20140524中的sql_redo爲varchar,須要改爲clob
begin
str:= 'insert into '||tab1||' values(:1,:2,:3,:4,:5,:6,:7,:8,:9)';
execute immediate str using scns,to_date(timestamps,'yyyy-MM-dd hh24:mi:ss'),seg_owner,table_name,session_info,sql_redo,ssession,serial,operation;
end logmnrtxt;
/
方法二:很複雜,其實不必這麼用,主要是爲了學習高級的存儲過程寫法
建立存儲過程:
CREATE OR REPLACE PROCEDURE p_In_Clob(pId IN NUMBER,outVar IN VARCHAR2)
IS
text_Var CLOB;
amount_Var NUMBER;
offset_Var NUMBER;
BEGIN
INSERT INTO test VALUES(pId,empty_clob());
SELECT text INTO text_var FROM test
WHERE id=pId;
amount_var:=LENGTH(outVar);
offset_var:=1;
DBMS_LOB.WRITE(text_Var,amount_Var,offset_Var,outVar);
COMMIT;
END p_In_Clob;
調用存儲過程:
begin
p_In_Clob(1,'...');
end;
3、oracle 存儲過程使用動態sql
Oracle存儲過程使用動態SQL 有兩種寫法:用 DBMS_SQL 或 execute immediate,建議使用後者。試驗步驟以下:
1. DDL和DML (注意DDL中能夠用拼接字符串的方法用來create table或drop table,在DML中,相似於insert則不能夠直接用execute immediate中直接拼接的方法,必須用using傳遞參數)
1 /*** DDL ***/ 2 begin 3 EXECUTE IMMEDIATE 'drop table temp_1'; 4 EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))'; 5 end; 6 7 /*** DML ***/ 8 declare 9 v_1 varchar2(8); 10 v_2 varchar2(10); 11 str varchar2(50); 12 begin 13 v_1:='測試人員'; --這裏的v_1,v_2能夠是直接存儲過程當中傳過來的參數 14 v_2:='北京'; 15 str := 'INSERT INTO test (name ,address) VALUES (:1, :2)'; 16 EXECUTE IMMEDIATE str USING v_1, v_2; 17 commit; 18 end;
2. 返回單條結果
例1:
1 declare 2 str varchar2(500); 3 c_1 varchar2(10); 4 r_1 test%rowtype; 5 begin 6 c_1:='測試人員'; 7 str:='select * from test where name=:c WHERE ROWNUM=1'; 8 execute immediate str into r_1 using c_1; 9 DBMS_OUTPUT.PUT_LINE(R_1.NAME||R_1.ADDRESS); 10 end ;
例2:
1 declare 2 v_col_name varchar2(30) := 'name'; --字段名 name 用變量來表示 3 v_user_name varchar2(30); --用戶名稱 4 v_user_age integer; --用戶年齡 5 v_sql_str varchar2(500); --動態 SQL 語句 6 begin 7 v_sql_str := 'select '||v_col_name||',age from users --字段名後面不能緊隨 into 到變量了 8 where age between :start_age and :end_age and rownum=1'; --兩個命名參數 ,注意拼接的方法 9 10 --用 execute immediate 動態執行 SQL 語句 11 --注意其後的 into 字段值到變量的寫法,還有 using 來代入參數 12 execute immediate v_sql_str into v_user_name,v_user_age using 18,25; 13 14 dbms_output.put_line('第一個符合條件的用戶:'||v_user_name||',年齡:'||v_user_age); 15 end;
3. 返回結果集
1 CREATE OR REPLACE package pkg_test as 2 /* 定義ref cursor類型 3 不加return類型,爲弱類型,容許動態sql查詢, 4 不然爲強類型,沒法使用動態sql查詢; 5 */ 6 type myrctype is ref cursor; 7 8 --函數申明 9 function get(intID number) return myrctype; 10 end pkg_test; 11 / 12 13 CREATE OR REPLACE package body pkg_test as 14 --函數體 15 function get(intID number) return myrctype is 16 rc myrctype; --定義ref cursor變量 17 sqlstr varchar2(500); 18 begin 19 if intID=0 then 20 --靜態測試,直接用select語句直接返回結果 21 open rc for select id,name,sex,address,postcode,birthday from 22 student; 23 else 24 --動態sql賦值,用:w_id來申明該變量從外部得到 25 sqlstr := 'select id,name,sex,address,postcode,birthday from student 26 where id=:w_id'; 27 --動態測試,用sqlstr字符串返回結果,用using關鍵詞傳遞參數 28 open rc for sqlstr using intid; 29 end if; 30 31 return rc; 32 end get; 33 34 end pkg_test; 35 /
4、存儲過程一個總結的很是全的博客
http://www.cnblogs.com/chinafine/archive/2010/07/12/1776102.html