Reputation: 43
I get an error
ORA-00904: "GLOBAL_VARIABLE_ARR": invalid identifier ORA-06512: at line 51.
It has something to with the global_variable_rec.where_clause
.
Can somebody help me solve this? The code follows. It's suppose to return the distribution_id
value from global_variable_arr('GLOBAL_DISTRIBUTION_ID')
. But it is not.
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;
This is my out put:
GLOBAL_DISTRIBUTION_ID := 123 GLOBAL_TRANSMITTAL_ID := 321 Table name is: DISTRIBUTION, column name is: PERSON_ID, global variable name is: Global_person_id, where clause is: 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')
Upvotes: 0
Views: 1904
Reputation: 67802
There is no way that dynamic SQL can see the content of a variable if you don't explicitely give this variable to the SQL engine.
Consider dynamic SQL as a standalone engine completely isolated from your procedure. It is as if you opened a SQL*Plus terminal inside your procedure and you typed your query.
Obviously the following would fail in a terminal:
SELECT PERSON_ID
FROM DISTRIBUTION
WHERE DISTRIBUTION_ID=global_variable_arr('GLOBAL_DISTRIBUTION_ID')
Why would it fail? Because there is no object named global_variable_arr
in your database, thus the invalid identifier error.
When you use dynamic SQL you have to be very specific and manually feed the variables to the engine. You have to do this yourself, as if you were using java or C#, or really any other language that is not static PL/SQL (which is why you should stick with static SQL at first and as long as possible).
Your query should be:
SELECT PERSON_ID FROM DISTRIBUTION WHERE DISTRIBUTION_ID = :VARIABLE_A
And you would call it with:
EXECUTE IMMEDIATE query_string
INTO sql_data
USING global_variable_arr('GLOBAL_DISTRIBUTION_ID');
Upvotes: 1