0

我有一个表名SAMPLETABLE,其中包含我在 column 中需要的表的表名TABLENAMES。假设表名是TABLEA,TABLEBTABLEC

查询时

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 上,任何帮助表示赞赏。

4

2 回答 2

1

As table name is not known at compile time you need to use dynamic SQL(execute immediate, native dynamic SQL, for instance) to be able to select from a table, name of which is stored as a string literal - you cannot accomplish it with static SQL

Here is an example:

-- 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

As a second option you could use weakly typed cursors - refcursors to execute a dynamically formed select statement:

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 about cursors and cursor variables

于 2013-09-11T06:32:45.670 回答
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
/

我只是举个例子。您声明一个变量以获取数据或您需要的其他内容。但是当您尝试使用带有输入参数的执行立即阅读有关 sql 注入的信息然后编写代码时。

于 2013-09-11T06:24:05.703 回答