[英]perl execute sql file (DBI oracle)
我有以下問題,我有一個使用DBI CPAN模塊Perl執行的SQL文件,我在該網站上看到了兩種解決方案來解決我的問題。
那么,哪個更好,每個解決方案之間的真正區別是什么?
編輯
它用於圖書館。 我需要檢索輸出和返回代碼。
傳遞的文件種類可能如下:
set serveroutput on;
set pagesize 20000;
spool "&1."
DECLARE
-- Récupération des arguments
-- &2: FLX_REF, &3: SVR_ID, &4: ACQ_STT, &5: ACQ_LOG, &6: FLX_COD_DOC, &7: ACQ_NEL, &8: ACQ_TYP
VAR_FLX_REF VARCHAR2(100):=&2;
VAR_SVR_ID NUMBER(10):=&3;
VAR_ACQ_STT NUMBER(4):=&4;
VAR_ACQ_LOG VARCHAR2(255):=&5;
VAR_FLX_COD_DOC VARCHAR2(30):=&6;
VAR_ACQ_NEL NUMBER(10):=&7;
VAR_ACQ_TYP NUMBER:=&8;
BEGIN
INSERT INTO ACQUISITION_CFT
(ACQ_ID, FLX_REF, SVR_ID, ACQ_DATE, ACQ_STT, ACQ_LOG, FLX_COD_DOC, ACQ_NEL, ACQ_TYP)
VALUES
(TRACKING.SEQ_ACQUISITION_CFT.NEXTVAL, ''VAR_FLX_REF'',
''VAR_SVR_ID'', sysdate, VAR_ACQ_STT, ''VAR_ACQ_LOG'',
''VAR_FLX_COD_DOC'', VAR_ACQ_NEL, VAR_ACQ_TYP);
END;
/
exit;
我又要問另一個關於DBI Oracle模塊的問題。 我可以對SQL文件和控制文件使用相同的代碼嗎?
(SQL控制文件示例)
LOAD DATA
APPEND INTO TABLE DOSSIER
FIELDS TERMINATED BY ';'
(
DSR_IDT,
DSR_CNL,
DSR_PRQ,
DSR_CEN,
DSR_FEN,
DSR_AN1,
DSR_AN2,
DSR_AN3,
DSR_AN4,
DSR_AN5,
DSR_AN6,
DSR_PI1,
DSR_PI2,
DSR_PI3,
DSR_PI4,
DSR_NP1,
DSR_NP2,
DSR_NP3,
DSR_NP4,
DSR_NFL,
DSR_NPG,
DSR_LTP,
DSR_FLF,
DSR_CLR,
DSR_MIM,
DSR_TIM,
DSR_NDC,
DSR_EMS NULLIF DSR_EMS=BLANKS "sysdate",
JOB_IDT,
DSR_STT,
DSR_DAQ "CASE WHEN :DSR_DAQ IS NOT NULL THEN SYSDATE ELSE NULL END"
)
一次讀取一張表比較復雜,但是它可以使用更少的內存-只要您構造代碼以利用每個項目的數據並且以后不再需要它即可。
通常,您希望單獨處理每個項目(例如,對數據進行處理),在這種情況下,您最好使用逐行讀取方法來定義循環。
默認情況下,我傾向於使用單指令方法,但是一旦我擔心記錄的數量(尤其是在長時間運行的批處理過程中),或者需要遍歷數據作為第一個任務,那么我就會讀取記錄-一一。
實際上,您所引用的兩個答案提出了相同的解決方案,以逐行讀取和執行(但第一個答案很明確)。 第二個問題有一個可選答案,其中文件包含一個語句 。
如果您不逐行執行SQL,則很難捕獲任何錯誤。
僅當每個SQL語句都在一行上時,“逐行”才有意義。 您可能是逐條陳述。
除此之外,它還取決於您的SQL文件的外觀以及您要執行的操作。
您的SQL文件有多復雜? 可以包含這樣的內容嗎?
select foo from table where column1 = 'bar;'; --Get foo; it will be used later.
按語句讀取SQL文件語句的簡單方法是用分號(或任何語句分隔符)分割。 但是,如果您可能在其他地方使用分號(例如注釋或字符串),則此方法將失敗。 如果用分號分隔該語句,則嘗試執行以下四個“命令”:
select foo from table where column1 = 'bar;
';
--Get foo;
it will be used later.
顯然,這些都不是有效的。 正確處理這樣的語句絕非易事。 您必須完全解析SQL才能弄清楚語句是什么。 不幸的是,沒有現成的模塊可以為您做到這一點( SQL::Script
是SQL文件處理模塊的一個很好的開始,但是根據文檔,此時它只是在分號上分割)。
如果您的SQL文件很簡單,則在語句或注釋中不包含任何語句分隔符; 或者如果可以通過其他方式預測(例如,每行只有一條語句),則很容易將文件拆分為多個語句並逐個執行它們。 但是,如果您必須處理任意的SQL語法(包括上述情況),這將是一項復雜的任務。
什么樣的任務?
如果您只是運行而忘記了它,則可以讓Perl執行系統命令,告訴Oracle處理文件。 這比您自己處理所有語句要簡單。 但是,如果您需要在Perl中處理結果或處理錯誤,則必須自己逐條語句進行操作。
更新:根據您的響應,您想編寫一個可以處理任意SQL語句的庫。 在這種情況下,您肯定需要解析SQL並一次執行一個語句。 這是可行的,但並不簡單。 BEGIN...END
塊的可能性意味着您必須能夠正確處理語句中的分號。
模塊的SQL::Statement
類可能會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.