oracle - Oracle 存储过程从现有表创建临时表
问题描述
我正在尝试在 oracle 中编写一个存储过程,它应该做一些相对简单的事情:
- 根据数据库中的现有表创建一个新的临时表,并
- 根据 where 子句将现有表中的记录复制到临时表中
我希望存储过程采用三个参数,以便可以将其用于表和 where 子句
CREATE OR REPLACE PROCEDURE SYSTEM.COPY_TO_TEMP_TABLE(
FROM_TABLE IN NCHAR,
TO_TABLE IN NCHAR,
WHERE_CLAUSE IN NCHAR
)
IS
BEGIN
CREATE TABLE TO_TABLE AS SELECT * FROM FROM_TABLE WHERE WHERE_CLAUSE;
END COPY_TO_TEMP_TABLE;
我很难相信过去没有这样做过数千次 - 任何想法为什么这不会为我编译?
解决方案
- 创建表不是在存储过程中通常会做的事情。与其他一些数据库不同,Oracle 没有本地临时表。如果您必须创建一个临时表,您可以在安装时创建所有其他表时执行此操作。临时表的数据对于插入它的会话是本地的,但定义是跨会话共享的。
- 不要在
sys
orsystem
模式中创建对象。这些是为 Oracle 保留的。为要创建的对象创建一个新架构。 nchar
如果您正在构建 SQL 语句,则不太可能使用参数。SQL 语句需要使用数据库字符集而不是国家字符集。
如果你想这样做,你需要使用动态 SQL。你可以做类似的事情
create or replace procedure create_table( p_from in varchar2,
p_to in varchar2,
p_where in varchar2 )
as
l_sql varchar2(1000);
begin
l_sql := ' create table ' || p_to ||
' as ' ||
' select * from ' || p_from ||
' where ' || p_where;
-- Print it out so you can debug when things inevitably go wrong
dbms_output.put_line( l_sql );
execute immediate l_sql;
end;
请注意,这对防止 SQL 注入攻击没有任何作用。我还假设您传入的任何内容都p_where
已经正确转义,以便可以将其连接起来(即p_where
“foo = ''bar''”而不是“foo = 'bar'”)。您显然可以更改该假设并将转义逻辑添加到过程中。
推荐阅读
- javascript - 当错误消息或成功消息向父级添加类时的欧芹
- python - 如何使用 CSV 输入共享 Jupyter Notebook
- asp.net-core-webapi - .Net Core Session Cookie 部署到 Azure 时未设置
- immutable.js - 是否可以将两个 Immutable.js 映射与对数运行时复杂度进行比较?
- c - sigwait 在 MacOS 上复制和转换信号
- javascript - 如何根据对象数组中属性的第一个字符过滤对象数组?
- django - 在 django rest 框架中使用嵌套用户更新配置文件
- python - 数据中随后年份的累积周数
- python - 使用基于系列值的多个过程
- php - 如何在 laravel 中将值从刀片传递到控制器?