PLSQL 中的动态游标 - Oracle
Dynamic cursor in PLSQL - Oracle
有什么方法可以重命名此光标处的 table。
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;
我想 运行 这个游标,但 table 名称不同
table_name = 'employees202110';
OPEN l_cursor FOR
q'[select first_name || ' ' || last_name, salary
from ]' || table_name || q'[
order by salary desc]';
或者你推荐我用什么方式制作光标
您的方向是正确的 - 正如您可能知道的那样,您不能在原生动态中将标识符名称作为绑定变量传入 sql,因此连接是前进的方向。
但是,您应该检查您连接的内容是否实际上是一个标识符名称,否则您将让自己为 SQL 注入敞开大门。这可以使用 DBMS_ASSERT.
来实现
根据您传递 table_name 的方式,您可能想要使用 DBMS_ASSERT.SIMPLE_SQL_NAME
(如果您没有传递架构名称以及 table_name ) 或 DBMS_ASSERT.QUALIFIED_SQL_NAME
(如果您要传递架构名称或数据库 link 等),例如:
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 关于使用 DBMS_ASSERT 清理动态 SQL 的输入。
有什么方法可以重命名此光标处的 table。
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;
我想 运行 这个游标,但 table 名称不同
table_name = 'employees202110';
OPEN l_cursor FOR
q'[select first_name || ' ' || last_name, salary
from ]' || table_name || q'[
order by salary desc]';
或者你推荐我用什么方式制作光标
您的方向是正确的 - 正如您可能知道的那样,您不能在原生动态中将标识符名称作为绑定变量传入 sql,因此连接是前进的方向。
但是,您应该检查您连接的内容是否实际上是一个标识符名称,否则您将让自己为 SQL 注入敞开大门。这可以使用 DBMS_ASSERT.
来实现根据您传递 table_name 的方式,您可能想要使用 DBMS_ASSERT.SIMPLE_SQL_NAME
(如果您没有传递架构名称以及 table_name ) 或 DBMS_ASSERT.QUALIFIED_SQL_NAME
(如果您要传递架构名称或数据库 link 等),例如:
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 关于使用 DBMS_ASSERT 清理动态 SQL 的输入。