我有一个表名SAMPLETABLE
,它具有我在TABLENAMES
列中需要的表的表名。可以说表格名为TABLEA
,TABLEB
和TABLEC
。
查询
SELECT TABLENAMES FROM SAMPLETABLE WHERE ROWNUM = 1
我得到输出TABLENAMES列的输出,其值为TABLEA
。
我的问题是,现在我想在select语句中使用这个选定的值。也就是说,
SELECT * FROM (SELECT TABLENAMES FROM SAMPLETABLE WHERE ROWNUM = 1)
我的想法是它返回TABLEA
的内容,因为当嵌套的SELECT返回TABLEA时,外部SELECT应该捕获并显示它。
相反,我只得到内部语句的输出,即
SELECT TABLENAMES FROM SAMPLETABLE WHERE ROWNUM = 1
和
SELECT * FROM (SELECT TABLENAMES FROM SAMPLETABLE WHERE ROWNUM = 1)
返回相同的输出。
我希望第一个SELECT语句获取第二个SELECT的返回值并显示该表。他们上面的查询不这样做,所以我该怎么做?我的想法出了什么问题?
我在Oracle 10g上,任何帮助表示赞赏。
答案 0 :(得分:1)
你可以借助动态sql来做到这一点。由于表名是在运行时获取的,因此您必须动态构建查询并运行它。
Declare
Tab_Name Varchar2(30);
Begin
SELECT TABLENAMES into Tab_Name FROM SAMPLETABLE WHERE ROWNUM = 1;
Execute Immediate 'Select * into (Collection Variable) from ' || Tab_Name;
End
/
我只是举了它作为例子。您声明一个变量以根据需要获取数据或其他内容。但是当你尝试使用execute immediate和输入参数读取sql注入然后编写你的代码时。
答案 1 :(得分:1)
由于在编译时未知表名,因此您需要使用动态SQL(例如,execute immediate,本机动态SQL)来从表中进行选择,其名称存储为字符串文字 - 您无法使用静态SQL
完成它以下是一个例子:
-- table which contains names of other tables
-- in the table_name column
SQL> create table Table_Names as
2 select 'employees' as table_name
3 from dual
4 ;
Table created
SQL> set serveroutput on;
-- example of an anonymous PL/SQL block
-- where native dynamic SQL (execute immediate statement)
-- is used to execute a dynamically formed select statement
SQL> declare
2 type T_record is record( -- example of record for fetched data
3 f_name varchar2(123),
4 l_name varchar2(123)
5 );
6
7 l_table_name varchar2(123); -- variable that will contain table name
8 l_select varchar2(201);
9 l_record T_Record; -- record we are going to fetch data into
10 begin
11 select table_name
12 into l_table_name -- querying a name of a table
13 from table_names -- and storing it in the l_table_name variable
14 where rownum = 1;
15
16 l_select := 'select first_name, last_name from ' ||
17 dbms_assert.simple_sql_name(l_table_name) ||
18 ' where rownum = 1'; -- forming a query
19
20 execute immediate l_select -- executing the query
21 into l_record;
22 -- simple output of data just for the sake of demonstration
23 dbms_output.put_line('First_name: ' || l_record.f_name || chr(10) ||
24 'Last name: ' || l_record.l_name);
25 exception
26 when no_data_found
27 then dbms_output.put_line('Nothing is found');
28 end;
29 /
First_name: Steven
Last name: King
PL/SQL procedure successfully completed
作为第二个选项,您可以使用弱类型游标 - 用于执行动态形成的select语句的refcursors:
SQL> variable refcur refcursor;
SQL> declare
2 l_table_name varchar2(123);
3 l_select varchar2(201);
4 begin
5 select table_name
6 into l_table_name
7 from table_names
8 where rownum = 1;
9
10 l_select := 'select first_name, last_name from ' ||
11 dbms_assert.simple_sql_name(l_table_name) ||
12 ' where rownum = 1';
13
14 open :refcur
15 for l_select;
16
17 exception
18 when no_data_found
19 then dbms_output.put_line('Nothing is found');
20 end;
21 /
PL/SQL procedure successfully completed.
SQL> print refcur;
FIRST_NAME LAST_NAME
-------------------- -------------------------
Steven King
SQL> spool off;
Find out more关于游标和游标变量