【问题标题】:How to fetch column name in a table in dynamic sql through an array如何通过数组获取动态sql表中的列名
【发布时间】:2013-08-25 04:36:31
【问题描述】:

我收到一个错误

ORA-00904:“GLOBAL_VARIABLE_ARR”:无效标识符 ORA-06512:第 51 行。

它与global_variable_rec.where_clause 有关。

有人可以帮我解决这个问题吗?代码如下。假设从global_variable_arr('GLOBAL_DISTRIBUTION_ID') 返回distribution_id 值。但事实并非如此。

CREATE OR REPLACE Procedure updateGlobalvariables ( transmittal_id IN NUMBER,      distribution_id IN NUMBER )

IS

sql_data        VARCHAR2(500);    --Holds select statment resulting value
query_string    VARCHAR2(500);    --Holds query/sql
i               VARCHAR2(75);     --Used for looping through the array
--transmittal_id  NUMBER(3) := 321; 
--distribution_id NUMBER(3) := 123;

--place holder for LETTER_GLOBAL_VARIABLE.TABLE_NAME
table_name VARCHAR2(30);

--Array for the Global Variables
TYPE global_variable_table_arr IS TABLE OF VARCHAR2(500) INDEX BY VARCHAR2(30);
global_variable_arr global_variable_table_arr;

--Cursor to hold the global variables
CURSOR global_variable_cur IS 
SELECT * FROM LETTER_GLOBAL_VARIABLES 
WHERE TABLE_NAME IS NOT NULL AND WHERE_CLAUSE IS NOT NULL;

--Record for the cursor to hold the data from the cursor.
global_variable_rec global_variable_cur%rowtype; 

BEGIN  
--Filling the array with(Element) the value from Distribution ID
global_variable_arr('GLOBAL_DISTRIBUTION_ID') := distribution_id;
dbms_output.put_line('GLOBAL_DISTRIBUTION_ID := '||      global_variable_arr('GLOBAL_DISTRIBUTION_ID') );

--Filling the array with(Element) the value from Transmittal ID
global_variable_arr('GLOBAL_TRANSMITTAL_ID') := transmittal_id;
dbms_output.put_line('GLOBAL_TRANSMITTAL_ID := '||     global_variable_arr('GLOBAL_TRANSMITTAL_ID') );

OPEN global_variable_cur;
FETCH global_variable_cur INTO global_variable_rec;
LOOP

    FETCH global_variable_cur INTO global_variable_rec;
    EXIT WHEN global_variable_cur%NOTFOUND;

    --Display table name, column name,global variable and the where clause (All from the LETTER_GLOBAL_VARIABLE table)
    dbms_output.put_line('Table name is: '|| global_variable_rec.table_name ||', column name is: '|| global_variable_rec.column_name ||', global variable name is: '|| global_variable_rec.global_variable || ', where clause is: ' || global_variable_rec.where_clause);

    --This the query that will grab the value(s) from the table(s). It is stored inside a variable
    query_string:= 'SELECT '||global_variable_rec.column_name|| '  FROM '|| global_variable_rec.table_name ||' WHERE '|| global_variable_rec.where_clause;

/* the where_clause contains: DISTRIBUTION_ID=global_variable_arr('GLOBAL_DISTRIBUTION_ID') */

    --Displays the SQL Query (query_string)
    dbms_output.put_line('SQL QUERY IS: ' || query_string);

    --This Executes the Query(SQL statement) inside the query_string variable
    --and saves the result(Value) into the sql_data variable.
    EXECUTE IMMEDIATE query_string INTO sql_data;

    --Display the value inside the variable sql_data
    dbms_output.put_line('SQL data IS: ' || sql_data);

    --Fill in the array with the value(Elements) from the sql_data variable.
    global_variable_arr(global_variable_rec.global_variable) := sql_data;

END LOOP;

CLOSE global_variable_cur;

i := global_variable_arr.FIRST;  -- Get first element of array

WHILE i IS NOT NULL LOOP

    --Displaying the global variable and its value
    dbms_output.put_line('Global Varaible name : ' || i || ' Value : ' || global_variable_arr(i));
    i := global_variable_arr.NEXT(i);  -- Get next element of array

END LOOP;

END;
--EXECUTE updateGlobalvariables;

这是我的输出:

GLOBAL_DISTRIBUTION_ID := 123 GLOBAL_TRANSMITTAL_ID := 321 表名是:DISTRIBUTION,列名是:PERSON_ID,全局变量名是:Global_person_id,其中子句是:DISTRIBUTION_ID=global_variable_arr('GLOBAL_DISTRIBUTION_ID') SQL QUERY IS: SELECT PERSON_ID FROM DISTRIBUTION WHERE DISTRIBUTION_ID=global_variable_arr('GLOBAL_DISTRIBUTION_ID')

【问题讨论】:

    标签: sql oracle dynamic plsql


    【解决方案1】:

    如果您不明确将该变量提供给 SQL 引擎,动态 SQL 将无法看到该变量的内容。

    将动态 SQL 视为与您的过程完全隔离的独立引擎。就好像您在过程中打开了一个 SQL*Plus 终端并输入了查询。

    显然,以下内容在终端中会失败:

    SELECT PERSON_ID 
      FROM DISTRIBUTION 
     WHERE DISTRIBUTION_ID=global_variable_arr('GLOBAL_DISTRIBUTION_ID')
    

    为什么会失败?因为你的数据库中没有名为global_variable_arr的对象,所以出现invalid identifier错误。

    当您使用动态 SQL 时,您必须非常具体并手动将变量提供给引擎。您必须自己执行此操作,就好像您使用的是 java 或 C#,或者实际上是任何其他非静态 PL/SQL 的语言(这就是为什么您应该首先并尽可能长时间地坚持使用静态 SQL)。

    您的查询应该是:

    SELECT PERSON_ID FROM DISTRIBUTION WHERE DISTRIBUTION_ID = :VARIABLE_A
    

    你会call it with

    EXECUTE IMMEDIATE query_string 
                 INTO sql_data 
                USING global_variable_arr('GLOBAL_DISTRIBUTION_ID');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多