假设我触发了一个查询:
select MyProc(id) from tableName;
我是否可以通过以下过程访问上述查询中from子句中使用的tableName:MyProc()?
然后我就可以在MyProc()过程中动态使用'from table'。'
感谢。
答案 0 :(得分:2)
不,你不能这样做。您可以将表作为过程的参数发送,并在过程中使用动态SQL:
SELECT MyProc( id, 'tablename' ) FROM dual;
但即使这样也很尴尬,并且具有动态SQL的所有限制。为什么你的程序需要表名?你想做什么?
答案 1 :(得分:0)
您必须使用动态构建的查询来执行您尝试的操作。尝试像
这样的东西strSQL VARCHAR2(32767);
csr SYS_REFCURSOR;
nVal1 NUMBER;
nVal2 NUMBER;
strVal3 VARCHAR2(2000);
strSQL := 'SELECT val1, val2, val3 FROM ' || tableName || ' WHERE whatever = somethingelse';
OPEN csr FOR strSQL;
FETCH csr INTO nVal1, nVal2, strVal3;
CLOSE csr;
分享并享受。
答案 2 :(得分:0)
create or replace function myProc(p_id number) return varchar2 is
v_sql_id varchar2(13);
v_table_name varchar2(100);
begin
--Get the SQL used to call this function
select sql_id into v_sql_id
from v$sql
where lower(sql_text) like 'select myproc(id)%'
and users_executing > 0;
--Get the table name
select object_name into v_table_name
from v$sql_plan
where sql_id = v_sql_id
and operation = 'TABLE ACCESS';
--For testing, return the table name.
return v_table_name;
end;
/
create table test1(id number);
create table test2(id number);
insert into test1 values(1);
insert into test2 values(2);
commit;
--Returns TEST1 (careful, your IDE may add this comment to the SQL!)
select MyProc(id) from test1;
--Returns TEST2
select MyProc(id) from test2;
这里的想法是找到当前正在执行的SQL,然后找到该SQL使用的表。但是存在很多潜在的问题。
获取SQL_ID
有很多方法可以找到SQL_ID,但没有一种方法可以正常工作。以下是我尝试过的方法,也许有人可以弄清楚如何使其中一个更好用。
例如,在v $ session中,SQL_ID将引用自身,而PREV_SQL_ID引用一些无用的事务查询(至少在我的系统上)。
select sql_id, prev_sql_id from v$session where sid = sys_context('USERENV', 'SID');
在v $ sql中查找查询并订购LAST_LOAD_TIME并不总是有效,LAST_LOAD_TIME并不总是更新。
select sql_id from v$sql
where lower(sql_text) like 'select myproc(id)%'
order by last_load_time desc;
使用SQL_TEXT和USERS_EXECUTING> 0将起作用,但仅当一次只有一个会话正在执行此查询时。搜索这样的文本非常危险。某些环境可能会在select之前放置文本,例如空格或注释。但是你不能搜索'%select ...',因为那时查询会自行返回。
select sql_id into v_sql_id
from v$sql
where lower(sql_text) like 'select myproc(id)%'
and users_executing > 0;
查找表格
使用SQL_ID,我们可以轻松地从v $ sql.sql_text或v $ sql.sql_fulltext获取查询文本。 可能可以解析该查询,但一般情况下我建议你避免解析 SQL。这比大多数人想象的要困难得多。如果您完全确定只使用特定的简单查询,那么这种方法可能会有效。
更现实的方法可能是使用v $ sql_plan来查找使用的表。这将适用于您的查询,但如果您的查询可以有多个表,或者如果有视图或索引(您必须加入user_index以查找实际表),您将不得不做更多的工作,等
select object_name
from v$sql_plan
where sql_id = <SQL_ID>
and operation = 'TABLE ACCESS'
您可能需要向用户授予对v_ $ sql和v_ $ sql_plan的select。哦,这真的很慢。 @ Eaolson将表名作为参数传递的想法要好得多,如果有效的话。