2017-08-30 83 views
0

我在下面的動態查詢中,我從一個查詢中獲取列名,表名,我需要這些值作爲全局變量。在Oracle中的動態查詢

列名稱可以更改從5列到50列。 我寫下面的查詢,但它不工作。給下面的消息 匿名塊完成 消息:-905-ORA-00905:缺少關鍵字

問題與解析的語句,DBMS_SQL.PARSE不知道誰進行

  DECLARE 
    TYPE lc_pdh_cur IS REF CURSOR; 
      ont_pdh lc_pdh_cur; 
      lv_sql_stmt VARCHAR2(3000); 
      lv_value VARCHAR2(1000); 
      lv_view_name VARCHAR2(1000); 
      lv_columns VARCHAR2(1000); 
      lv_var_columns VARCHAR2(1000); 
      LV_VAR_STMT VARCHAR2(1000); 
      LV_COL_STMT VARCHAR2(1000); 
      v_cursor integer; 
      v_dname char(20); 
    v_rows integer; 
     TYPE l_column_pair IS TABLE OF VARCHAR2(2400) -- Associative array type 
     INDEX BY VARCHAR2(200);   -- indexed by string 
     l_pairs l_column_pair;  -- Associative array variable 
     CURSOR lc_agv_name 
     is 
      SELECT database_column,decode (value_set_name,null,substr(attr_name,0,24),substr(attr_name,0,24)||'_disp') attr_name FROM ego_attrs_v a WHERE attr_group_name = 'Claims'; 
    BEGIN 
      SELECT agv_name INTO lv_view_name FROM ego_attr_groups_v WHERE attr_group_name = 'Claims'; 
      BEGIN 
      FOR lc_agv_name_rec in lc_agv_name 
      LOOP 
       lv_col_stmt := lv_col_stmt || lc_agv_name_rec.attr_name ||','; 
       lv_var_stmt := lv_var_stmt || 'l_pairs('''|| lc_agv_name_rec.database_column ||''') ,'; 
      END LOOP; 
       lv_columns := SUBSTR(lv_col_stmt,0,length(lv_col_stmt)-1); 
       lv_var_columns := SUBSTR(lv_var_stmt,0,length(lv_var_stmt)-1); 
    EXCEPTION 
     when others 
     then 
      dbms_output.put_LINE('mESSAGE :'||lv_columns||'--'||lv_var_columns||'-'||SQLCODE||'-'||SQLERRM); 
      END; 
      BEGIN 
       v_cursor := DBMS_SQL.OPEN_CURSOR; 
       DBMS_SQL.PARSE(v_cursor, 'SELECT '||lv_columns||' INTO '||lv_var_columns|| ' FROM '||lv_view_name||' WHERE header_id = 8175', DBMS_SQL.NATIVE); 
       v_rows :=DBMS_SQL.EXECUTE(v_cursor); 
       loop 
       if DBMS_SQL.FETCH_ROWS(v_cursor) = 0 then 
     dbms_output.put_LINE('No Data :View '||lv_view_name||' Columns '||lv_columns); 
       exit; 
       end if; 
      end loop; 
       DBMS_SQL.CLOSE_CURSOR(v_cursor); 
     dbms_output.put_LINE('Values :'||l_pairs('Coulmn1') ||'some variable'||l_pairs('Coulmn2')); 
     EXCEPTION 
     when others 
     then 
      dbms_output.put_LINE('Message :'||lv_sql_stmt||SQLCODE||'-'||SQLERRM); 
      END; 
     END; 
    /
+1

您的問題是? –

+0

@tonyAndrews我寫了查詢並且沒有工作。 – vakul

+0

「不工作」是什麼意思?任何錯誤消息? –

回答

1

看一看這部分

BEGIN 
     SELECT agv_name INTO lv_view_name FROM ego_attr_groups_v WHERE attr_group_name = 'Claims'; 
     BEGIN 
     FOR lc_agv_name_rec in lc_agv_name 
     LOOP 
      lv_col_stmt := lv_col_stmt || lc_agv_name_rec.attr_name ||','; 
      lv_var_stmt := lv_var_stmt || 'l_pairs('''|| lc_agv_name_rec.database_column ||''') ,'; 
     END LOOP; 
      lv_columns := SUBSTR(lv_col_stmt,0,length(lv_col_stmt)-1); 
      lv_var_columns := SUBSTR(lv_var_stmt,0,length(lv_var_stmt)-1); 
EXCEPTION 
    when others 
    then 
    .... 

我認爲這部分的異常是不太可能的,這意味着你將永遠不會運行動態SQL的主要部分。

無論如何,這一個不工作:

DBMS_SQL.PARSE(v_cursor, 'SELECT '||lv_columns||' INTO '||lv_var_columns|| ' FROM '||lv_view_name||' WHERE header_id = 8175', DBMS_SQL.NATIVE); 

你必須做,與此類似:

TYPE l_column_pair IS TABLE OF VARCHAR2(2400) -- PL/SQL table 
    l_pairs l_column_pair := l_column_pair(); 
    ColumnCount INTEGER := 0; 
BEGIN 

FOR lc_agv_name_rec in lc_agv_name LOOP 
    ColumnCount := ColumnCount + 1; 
    lv_col_stmt := lv_col_stmt || lc_agv_name_rec.attr_name ||','; 
END LOOP; 
lv_columns := SUBSTR(lv_col_stmt,0,length(lv_col_stmt)-1); 


DBMS_SQL.PARSE(v_cursor, 'SELECT '||lv_columns|| ' FROM '||lv_view_name||' WHERE header_id = :headerId', DBMS_SQL.NATIVE); 

DBMS_SQL.BIND_VARIABLE (v_cursor, ':headerId', 8175); 
FOR c_agv_name_rec in lc_agv_name LOOP 
    DBMS_SQL.DEFINE_COLUMN(v_cursor, lc_agv_name_rec.ROWNUM, lc_agv_name_rec.attr_name, 2400); 
END LOOP; 
res := DBMS_SQL.EXECUTE_AND_FETCH(v_cursor, TRUE); 
FOR c in 1..ColumnCount LOOP 
    l_pairs.EXTEND; 
    DBMS_SQL.COLUMN_VALUE(v_cursor, c, l_pairs(c)); 
END LOOP; 
DBMS_SQL.CLOSE_CURSOR(v_cursor); 

注意,DBMS_SQL.EXECUTE_AND_FETCH(v_cursor, TRUE);獲取只有一個(即第一)一行。如果您的查詢可能會返回多行,您必須這樣做:

l_pairs.EXTEND(ColumnCount); 

res := DBMS_SQL.EXECUTE(v_cursor); 
WHILE (DBMS_SQL.FETCH_ROWS(v_cursor) > 0) LOOP 
    FOR c in 1..ColumnCount LOOP 
     DBMS_SQL.COLUMN_VALUE(v_cursor, c, l_pairs(c)); 
    END LOOP;  
END LOOP;