从子查询中获取表名以在一行中用于 Oracle 中的删除/更新/插入子句
Posted
技术标签:
【中文标题】从子查询中获取表名以在一行中用于 Oracle 中的删除/更新/插入子句【英文标题】:Get table name from sub-query to use in delete / update / insert clauses in Oracle in one line 【发布时间】:2017-04-25 12:03:07 【问题描述】:目标是在插入/更新/删除语句中使用从子选择返回的表名。它未能达到预期的效果。
如果我们使用 TABLE 执行(TABLE 是 reference 中描述的 oracle 语法词)
delete from TABLE
(select DECODE(this returns table name as string) from REF_TABLE where where_clause);
然后: 22905. 00000 - “无法访问非嵌套表项中的行”
如果我们在没有 TABLE 的情况下执行:
delete from
(select DECODE(this returns table name as string) from REF_TABLE where where_clause);
然后它实际上从 REF_TABLE 中删除满足 when 子句的记录。
将表名从子选择传递到外部查询的正确方法是什么?
Doc examples
EXECUTE IMMEDIATE 'delete from table :1' USING (select DECODE(...) from REF_TABLE WHERE where_clause);
PLS-00103:遇到符号“从表 :1 中删除”时 期待以下之一:
:= 。 (@%; 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:
【问题讨论】:
提示:execute immediate
。你不能用一条语句来做到这一点。您必须使用动态 SQL。
谢谢,但它不想按照错误提示进行编译。为什么?
您需要提前创建字符串。您不能将标识符作为参数传递。
有什么方法可以在一行中使用“立即执行”或其他方式实现目标吗?
为什么需要一行?您只是在寻找最简单的解决方案,还是需要解决一些奇怪的工具限制? Sandeep 在下面的回答是一个单一的陈述,可以说是“一行代码”。这有点牵强,但您可以将 PL/SQL 逻辑放在 SELECT 的 WITH 子句中,并在大多数人认为“一行”的单个 SELECT 语句中运行它。最干净的解决方案可能是创建一个过程来完成这项工作,然后在一行中调用该过程。
【参考方案1】:
在执行 DML 查询(例如插入、更新和删除)时,您永远不会提及 table 关键字
delete from table_name;
update table_name set field='value';
insert into table_name (field) values ('value');
在执行 Create、Alter、drop 和 Truncate 等 DDL 语句时会提到 Table 关键字
Create table table_name (field varchar2(100));
Alter table table_name modify field1 varchar2(1000);
Drop table table_name;
truncate table table_name;
因此您提到的以下查询是正确的
delete from
(select DECODE(this returns table name as string) from REF_TABLE where where_clause);
上述查询的唯一限制是您必须使用来自固定表或视图的 table_name 源,即不能从数据字典视图中选择它,否则您将收到以下错误。
SQL Error: ORA-02030: can only select from fixed tables/views
02030. 00000 - "can only select from fixed tables/views"
*Cause: An attempt is being made to perform an operation other than
a retrieval from a fixed table/view.
*Action: You may only select rows from fixed tables/views.
您可以使用类似于下面提到的 PL/SQL 块来递归删除表
DECLARE
CURSOR c
IS
SELECT table_name FROM user_tables WHERE table_name LIKE '%SANDEEP26FEB16_2%';
BEGIN
FOR c1 IN c
LOOP
EXECUTE IMMEDIATE 'delete from ' || c1.table_name;
COMMIT;
END LOOP;
END;
【讨论】:
以上是关于从子查询中获取表名以在一行中用于 Oracle 中的删除/更新/插入子句的主要内容,如果未能解决你的问题,请参考以下文章
在 Python Flask 中从数据库中查询数据时获取表名
如何使用 jQuery 从子元素中获取数据以在 xml api 中查找其他子元素?
从子记录(或超链接)获取数据以在 netsuite 高级 html pdf 中打印