簡體   English   中英

perl執行sql文件(DBI oracle)

[英]perl execute sql file (DBI oracle)

我有以下問題,我有一個使用DBI CPAN模塊Perl執行的SQL文件,我在該網站上看到了兩種解決方案來解決我的問題。

  1. 逐行讀取SQL文件

  2. 在一條指令中讀取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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM