2014-05-19 67 views
0

這裏有一個問題給大家,有沒有什麼辦法通過動態替換cursor.column_name語法中的column_name來使PL/SQL代碼工作?我知道我混淆了PL/SQL引擎,但我不能就如何解決這一問題完全肯定...動態修整列值

目前我得到的錯誤如下,但我認爲實際的問題是,PL/SQL引擎不知道如何解釋TRIM (e_rec.v_temp_column_name)

「[錯誤] PLS-00302(133:26):PLS-00302:組件 'V_TEMP_COLUMN_NAME' 必須聲明爲」

參數:x_person_rec IN OUT xxsome_table%ROWTYPE

v_temp_column_name dba_tab_columns.column_name%TYPE; 
... 
BEGIN 
     FOR e_rec IN (SELECT * FROM xxsome_table WHERE ..) 
     LOOP 
     --LOG (3, 'Loading/Sanitizing Header Record'); 

     FOR col IN (SELECT column_name 
         FROM dba_tab_columns 
         WHERE table_name = UPPER ('xxsome_table')) 
     LOOP 
      --LOG (3, 'Sanitizing Column Name: ' || col.column_name); 
      v_temp_column_name := col.column_name; 
      x_person_rec.v_temp_column_name := TRIM (e_rec.v_temp_column_name); 
     END LOOP; 
     END LOOP; 

... 

我已經試過這樣做(這會導致不同的錯誤):x_person_rec.col.column_name := TRIM (e_rec.col.column_name);

回答

2

不,你不能和你的確混淆了PL/SQL引擎。問題是v_temp_column_name是一個字符,因此TRIM (e_rec.v_temp_column_name)被評估爲TRIM (e_rec.'v_temp_column_name'),這沒有任何意義。

做的最好的事情,如果尾隨空白是一個問題,就是確保所有的數據被放進你的數據庫是由您的應用程序/ ETL過程的時候修剪。如果你不能這樣做,那麼使用觸發器來確保它發生在數據庫中。如果這是一個確實不好的問題,你甚至可以執行檢查約束來阻止它發生。

現在,爲了回答你的問題,這裏沒有必要動態做任何事情。你的光標可能是隱含的,但它不是動態生成的。你知道表中的每一列,所以不要懶惰,然後全部輸入。

FOR e_rec IN (SELECT trim(col1) as col1 
        , trim(col2) as col2 
       FROM xxsome_table WHERE ... 

如果你不能修復您的數據(或者,如果它不破!),那麼這是很容易做到這一點的最簡單方法。

要真正回答你的問題,你可以使用你在這裏使用相同的技術動態生成SELECT語句...

declare 
    l_cols varchar2(4000); 
    l_curs sys_refcursor; 
begin 

    select wm_concat('trim(' || column_name || ')') 
    into l_cols 
    from user_tab_columns 
    where table_name = 'XXSOME_TABLE' 
      ; 

    open l_curs for 
    ' select ' || l_cols || ' from xxsome_table where ...'; 

    loop 
     ... 
    end loop; 

end; 
/

當你在10g中,你不能使用優秀LISTAGG() ,但有plenty of other string aggregation techniques。請注意,if the resulting string is greater than 4,000 bytes,您必須循環而不是在單個SQL語句中生成列列表。

P.S.,如果這些列CHAR(n)那麼你就必須每次選擇的時間來修剪它們。這可能是值得其更改爲VARCHAR2(n)

+0

感謝您的答覆,我想你說什麼,我需要聽到的,其中我會處理在ETL過程中修剪的數據。您建議動態構建SELECT實際上是解決此問題的好方法,所以我很欣賞額外的努力! –

+0

沒問題@Roberto;當設置一些東西來修剪所有東西時,很麻煩,但從長遠來看,它更容易,因爲您只需要一次而不是每次都這樣做。 – Ben