Home > other >  Dynamic cursor in PLSQL - Oracle
Dynamic cursor in PLSQL - Oracle

Time:10-28

Is there any way to rename the table at this cursor.

DECLARE
   TYPE name_salary_rt IS RECORD (
      name     VARCHAR2 (1000),
      salary   NUMBER
   );         

   TYPE name_salary_aat IS TABLE OF name_salary_rt
      INDEX BY PLS_INTEGER;

   l_employees   name_salary_aat;   

   l_cursor   SYS_REFCURSOR;
   
   table_name = 'employees202110';
BEGIN
   OPEN l_cursor FOR 
      q'[select first_name || ' ' || last_name, salary 
           from employees202110
          order by salary desc]';

   FETCH l_cursor BULK COLLECT INTO l_employees;

   CLOSE l_cursor;

   FOR indx IN 1 .. l_employees.COUNT
   LOOP
      DBMS_OUTPUT.put_line (l_employees (indx).name);
   END LOOP;
END;

I want to run this cursor but with different table names

table_name = 'employees202110';

OPEN l_cursor FOR 
      q'[select first_name || ' ' || last_name, salary 
           from ]' || table_name || q'[
          order by salary desc]';

or in what way do you recommend me to make the cursor

CodePudding user response:

You're along the right tracks - as you're probably aware, you can't pass in identifier names as bind variables in native dynamic sql, so concatenating is the way forward.

However, you should check that what you're concatenating is actually an identifier name, otherwise you're leaving yourself wide open for SQL injection. This can be achieved using DBMS_ASSERT.

Depending on how you're passing the table_name in, you might want to use DBMS_ASSERT.SIMPLE_SQL_NAME (if you're not passing the schema name in as well as the table_name) or DBMS_ASSERT.QUALIFIED_SQL_NAME (if you're passing the schema name, or a db link, etc), e.g.:

OPEN l_cursor FOR 
      q'[select first_name || ' ' || last_name, salary 
           from ]' || DBMS_ASSERT.SIMPLE_SQL_NAME(table_name) || q'[
          order by salary desc]';

Tim Hall has a good article on using DBMS_ASSERT to sanitize your inputs for dynamic SQL.

  • Related