Oracle - UTL_FILE包之BLOB匯入和匯出
一、將檔案匯入到BLOB欄位中示例
CREATE OR REPLACE PROCEDURE SET_FILE_BY_BLOB(UPDATE_TABLE_NAME VARCHAR2, MARK_COLUMN_NAME VARCHAR2, MARK_COLUMN_VALUE VARCHAR2,
MARK_TYPE_ISNUM NUMBER, BLOB_COLUMN_NAME VARCHAR2, LOCAL_FILE_NAME VARCHAR2) IS
/******************************************
*引數描述:
* UPDATE_TABLE_NAME:匯入的表名(字元型)
* MARK_COLUMN_NAME:主鍵的欄位名(字元型)
* MARK_COLUMN_VALUE:主鍵欄位的值(字元型)
* MARK_TYPE_ISNUM:主鍵是否數值(0是1否,數值型)
* BLOB_COLUMN_NAME:檔案儲存的欄位名(字元型)
* LOCAL_FILE_NAME:本地的檔名(字元型)
*樣例:
* exec EPAYMENT.SET_FILE_BY_BLOB('t_audit_channel_file', 'audit_id', '756', 0, 'audit_file', 'test.zip');
******************************************/
UTL_FILE_OBJ UTL_FILE.FILE_TYPE; -- 要讀取檔案的控制程式碼
READ_MAX_SIZE BINARY_INTEGER := 32767; -- 一次讀取的最大長度
UTL_BUFF_RAW RAW(32767); -- 檔案讀取的快取
UTL_BLOB_OBJ BLOB; -- BLOB欄位的指標
LOB_CURR_POS BINARY_INTEGER := 1; -- 當前讀取位置
READ_CUUR_SIZE BINARY_INTEGER := 32767; -- 當前讀取到的長度
DYN_STR_SQL VARCHAR(250); -- 執行的動態SQL
BEGIN
DBMS_OUTPUT.PUT_LINE('INFO:Start...');
IF MARK_TYPE_ISNUM = 0 THEN
DYN_STR_SQL := 'SELECT ' || BLOB_COLUMN_NAME || ' FROM ' || UPDATE_TABLE_NAME || ' WHERE ' || MARK_COLUMN_NAME || ' = ' || MARK_COLUMN_VALUE || ' FOR UPDATE ';
ELSE
DYN_STR_SQL := 'SELECT ' || BLOB_COLUMN_NAME || ' FROM ' || UPDATE_TABLE_NAME || ' WHERE ' || MARK_COLUMN_NAME || ' = ''' || MARK_COLUMN_VALUE || '''' || ' FOR UPDATE ';
END IF;
DBMS_OUTPUT.PUT_LINE('DEBUG:' || DYN_STR_SQL);
-- 執行動態SQL,並將值賦給變數
EXECUTE IMMEDIATE DYN_STR_SQL INTO UTL_BLOB_OBJ; -- 將目標欄位鎖住,並且將目標欄位賦值給UTL_BLOB_OBJ,以待後續的操作
DBMS_LOB.OPEN(UTL_BLOB_OBJ, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.TRIM(UTL_BLOB_OBJ,0); -- 幹掉所有的內容
UTL_FILE_OBJ := UTL_FILE.FOPEN('DB_OUT', LOCAL_FILE_NAME, 'RB', READ_MAX_SIZE); --檔案超過4000要使用迴圈或者RAW(最大32767)
LOOP
BEGIN
UTL_FILE.GET_RAW(UTL_FILE_OBJ, UTL_BUFF_RAW, READ_MAX_SIZE);
READ_CUUR_SIZE := DBMS_LOB.GETLENGTH(UTL_BUFF_RAW);
DBMS_LOB.WRITE(UTL_BLOB_OBJ, READ_CUUR_SIZE, LOB_CURR_POS, UTL_BUFF_RAW);
LOB_CURR_POS := READ_CUUR_SIZE + LOB_CURR_POS;
DBMS_OUTPUT.PUT_LINE('DEBUG: Reading(Cuur='||READ_CUUR_SIZE||' | Total='|| LOB_CURR_POS||')...');
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
DBMS_LOB.CLOSE(UTL_BLOB_OBJ);
UTL_FILE.FCLOSE(UTL_FILE_OBJ);
COMMIT;
DBMS_OUTPUT.PUT_LINE('INFO:End...');
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN(UTL_FILE_OBJ) THEN
UTL_FILE.FCLOSE(UTL_FILE_OBJ);
END IF;
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('ERR:' || SQLERRM);
END SET_FILE_BY_BLOB;
二、將BLOB欄位中的檔案匯出示例:
CREATE OR REPLACE PROCEDURE GET_FILE_BY_BLOB(QUERY_TABLE_NAME VARCHAR2, MARK_COLUMN_NAME VARCHAR2, MARK_COLUMN_VALUE VARCHAR2,
MARK_TYPE_ISNUM NUMBER, BLOB_COLUMN_NAME VARCHAR2, FILE_NAME_COLUMN VARCHAR2) IS
/******************************************
*引數描述:
* QUERY_TABLE_NAME:查詢的表名(字元型)
* MARK_COLUMN_NAME:主鍵的欄位名(字元型)
* MARK_COLUMN_VALUE:主鍵欄位的值(字元型)
* MARK_TYPE_ISNUM:主鍵是否數值(0是1否,數值型)
* BLOB_COLUMN_NAME:檔案儲存的欄位名(字元型)
* FILE_NAME_COLUMN:檔名對應的欄位名(字元型)
*樣例:
* exec EPAYMENT.GET_FILE_BY_BLOB('t_audit_channel_file', 'audit_id', '756', 0, 'audit_file', 'file_name');
******************************************/
UTL_FILE_OBJ UTL_FILE.FILE_TYPE; -- 預生成檔案的控制程式碼
UTL_BUFF_RAW RAW(32767); -- 快取讀取的到BLOB(以位元組為單位,作為資料庫列最大2000,作為變數最大32767位元組)
READ_MAX_SIZE BINARY_INTEGER := 32767; -- 一次讀取的長度
UTL_CURR_POS INTEGER := 1; -- 當前讀取位置
UTL_BLOB_OBJ BLOB; -- BLOB的內容
UTL_BLOB_LEN INTEGER; -- BLOB的總長
GEN_FILE_NAME VARCHAR2(150); -- 預生成的檔名
DYN_STR_SQL VARCHAR(250); -- 執行的動態SQL
BEGIN
DBMS_OUTPUT.PUT_LINE('INFO:Start...');
IF MARK_TYPE_ISNUM = 0 THEN
DYN_STR_SQL := 'SELECT ' || FILE_NAME_COLUMN || ' , ' || BLOB_COLUMN_NAME || ' FROM ' || QUERY_TABLE_NAME || ' WHERE ' || MARK_COLUMN_NAME || ' = ' || MARK_COLUMN_VALUE;
ELSE
DYN_STR_SQL := 'SELECT ' || FILE_NAME_COLUMN || ' , ' || BLOB_COLUMN_NAME || ' FROM ' || QUERY_TABLE_NAME || ' WHERE ' || MARK_COLUMN_NAME || ' = ''' || MARK_COLUMN_VALUE || '''';
END IF;
DBMS_OUTPUT.PUT_LINE('DEBUG:' || DYN_STR_SQL);
-- 執行動態SQL,並將值賦給變數
EXECUTE IMMEDIATE DYN_STR_SQL INTO GEN_FILE_NAME, UTL_BLOB_OBJ;
DBMS_OUTPUT.PUT_LINE('DEBUG:'|| GEN_FILE_NAME);
DBMS_LOB.OPEN(UTL_BLOB_OBJ, DBMS_LOB.LOB_READONLY);
UTL_BLOB_LEN := DBMS_LOB.GETLENGTH(UTL_BLOB_OBJ);
UTL_FILE_OBJ := UTL_FILE.FOPEN('DB_OUT', GEN_FILE_NAME, 'WB', READ_MAX_SIZE);
WHILE UTL_CURR_POS < UTL_BLOB_LEN LOOP
-- DBMS_LOB.READ(LOB資料,指定長度,起始位置,儲存返回LOB型別值變數);
-- 第二個引數呼叫時按照該引數指定的長度來讀取資料,讀取完畢後,將其更新為實際讀取的字元(位元組)長度。當讀取後,該引數的值比你原來的值小,則說明已經讀取到 LOB 的末尾了
DBMS_LOB.READ(UTL_BLOB_OBJ, READ_MAX_SIZE, UTL_CURR_POS, UTL_BUFF_RAW);
-- UTL_FILE.PUT_RAW(檔案控制程式碼,快取,是否自動FLUSH)
UTL_FILE.PUT_RAW(UTL_FILE_OBJ, UTL_BUFF_RAW, TRUE);
UTL_CURR_POS := UTL_CURR_POS + READ_MAX_SIZE;
DBMS_OUTPUT.PUT_LINE('DEBUG: Reading(Cuur='||UTL_CURR_POS||' | Total='|| UTL_BLOB_LEN||')...');
END LOOP;
DBMS_LOB.CLOSE(UTL_BLOB_OBJ);
UTL_FILE.FCLOSE(UTL_FILE_OBJ);
DBMS_OUTPUT.PUT_LINE('INFO:End...');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('ERR: No data.');
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN(UTL_FILE_OBJ) THEN
UTL_FILE.FCLOSE(UTL_FILE_OBJ);
RAISE;
END IF;
DBMS_OUTPUT.PUT_LINE('ERR:' || SQLERRM);
END;
相關文章
- 【SQL】Oracle BLOB 批量匯入匯出圖片語句SQLOracle
- ORACLE百萬資料匯入匯出解決方法(LOADER、UTL_FILE)Oracle
- oracle匯入匯出之expdp/impdpOracle
- Oracle資料庫匯入匯出。imp匯入命令和exp匯出命令Oracle資料庫
- Oracle增量匯入匯出Oracle
- Oracle資料泵的匯入和匯出Oracle
- 【匯入匯出】Oracle 常用匯入匯出工具集錦Oracle
- Oracle 資料匯入匯出Oracle
- oracle排除表匯入匯出Oracle
- Oracle資料匯入匯出Oracle
- Oracle資料庫的匯入和匯出命令Oracle資料庫
- 【匯出匯入】匯出匯入 大物件物件
- Oracle匯入(imp )與匯出(exp )Oracle
- 【ORACLE 匯入匯出】exp 錯誤Oracle
- ORACLE匯入匯出命令exp/impOracle
- 【oracle 匯入、匯出】escape 的作用。Oracle
- Oracle 12c expdp和impdp匯出匯入表Oracle
- kxcel, 方便匯入和匯出 ExcelExcel
- 匯出和匯入Gradle工程Gradle
- postgresql 資料匯入和匯出SQL
- Oracle - 匯入匯出常用操作語句Oracle
- oracle資料匯出匯入(exp/imp)Oracle
- Oracle 遠端匯出匯入 imp/expOracle
- Oracle資料泵-schema匯入匯出Oracle
- 高速的匯出/匯入:Oracle Data PumpOracle
- oracle資料庫匯入匯出命令!Oracle資料庫
- Oracle資料匯入匯出詳解Oracle
- ORACLE統計資訊的匯出、匯入Oracle
- Oracle全庫匯出和特定使用者匯入Oracle
- 一個ORACLE匯入和匯出XML檔案的例子OracleXML
- 【匯入匯出】sqlldr 匯入案例SQL
- MySQL入門--匯出和匯入資料MySql
- 【匯出匯入】% 在匯入匯出中的應用。
- oracle10G新特性之資料泵匯出/匯入Oracle
- NPOI匯出和匯入Excel,Word和PDFExcel
- DB2 匯入和匯出 命令列和客戶端匯出DB2命令列客戶端
- 使用 UTL_FILE匯出TAB和逗號分割資料
- ES模組化的匯入和匯出