2017-08-30 91 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;