在存储过程中组合多个语句

Posted

技术标签:

【中文标题】在存储过程中组合多个语句【英文标题】:Combining Multiple Statements in a Stored Procedure 【发布时间】:2014-08-16 08:45:42 【问题描述】:

我是 Oracle 的新手,我正在努力实现我可以在 SQL 中实现的目标,但我在 Oracle 中遇到了困难。

所以在存储过程中,我尝试截断表,然后插入值,最后对表运行 SELECT 语句。

这是我所拥有的,但它不起作用,当我运行这个脚本时,它运行没有错误,但它似乎只通过第一个 (TRUNCATE) 语句,仅此而已。

我希望它创建存储过程(它会这样做),然后从 SELECT 语句中向我显示表的内容。

CREATE OR REPLACE procedure MYSTOREDPROCEDURE is
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE MYTABLE';
INSERT INTO MYTABLE
(COL1,
COL2,
COL3)

SELECT COL1, COL2, COL3 FROM MYOTHERTABLE;
end ;
/

SELECT * FROM MYTABLE

END MYSTOREDPROCEDURE;

【问题讨论】:

【参考方案1】:

为了澄清,SQL 是一种由许多 RDBMS 实现的语言,包括 SQL Server、PostgreSQL 等。如果您在 Oracle 中执行此操作,则 使用 SQL。但是,大多数 RDBMS 还为 SQL 添加了过程扩展,例如 T-SQL (SQL Server)、pgPL/SQL (PostgreSQL) 和 PL/SQL (Oracle)。在这种情况下,您正在尝试使用 PL/SQL。

根据您的尝试,我假设您已经习惯了 SQL Server 和临时表。在Oracle中使用临时表是less common and less necessary。

首先,EXECUTE IMMEDIATE 'TRUNCATE TABLE MYTABLE';。在 Oracle 的存储过程中应该很少需要执行 DDL;这通常表明数据模型存在缺陷。在这种情况下,您似乎将实际表用作临时表。我不会这样做的。如果您需要临时表,请使用global temporary table。

其次,SELECT * FROM MYTABLE。您不能在 PL/SQL 中执行此操作。如果您需要选择一些数据,您必须使用SELECT <columns> INTO <variables> FROM ...。如果你这样做,它不会向你显示表格的内容。

根据您对尝试的描述,只有需要执行以下操作:

SELECT COL1, COL2, COL3 FROM MYOTHERTABLE;

根本不需要PL/SQL(存储过程)。

【讨论】:

嗨 Ben,我简化了我的帖子,声明我从 MYOTHERTABLE 获取数据并将其插入 MYTABLE,实际上我必须连接多个表,然后将数据插入 MYTABLE。然后这个存储过程将在 RDL 报告中使用,这就是为什么我想在最后使用 SELECT * FROM MYTABLE。 没关系@tonto。你先截断表格。如果数据不需要持久化,那么使用临时表是没有意义的。【参考方案2】:

我怀疑您打算在编译和执行过程后执行SELECT * FROM MYTABLE。以上可以改写为:

CREATE OR REPLACE procedure MYSTOREDPROCEDURE is
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE MYTABLE';

  INSERT INTO MYTABLE (COL1, COL2, COL3)
    SELECT COL1, COL2, COL3
      FROM MYOTHERTABLE;

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error in MYSTOREDPROCEDURE : ' || SQLCODE || ' - ' || SQLERRM);
    RAISE;
END MYSTOREDPROCEDURE;
/

EXECUTE MYSTOREDPROCEDURE
/

SELECT * FROM MYTABLE
/

分享和享受。

【讨论】:

【参考方案3】:

我的 DBA 不会让我拥有 TRUNCATE 权限,即使与 delete MYTABLE; 相比,截断删除了高水位标记,如果没有这些权限,您的代码将失败。 @Ben 和 @Bob Jarvis 都为缺失的 INTO 和更好的形式提供了合理的建议。 Bob Jarvis 回答的一个补充是您需要以SET SERVEROUTPUT ON SIZE 100000; 启动命令。否则,他精心设计的错误信息将不会显示。 serveroutput 命令用于DBMS_OUTPUT,并且仅在您的数据库会话持续时持续。

【讨论】:

以上是关于在存储过程中组合多个语句的主要内容,如果未能解决你的问题,请参考以下文章

项目开发中使用存储过程和直接使用SQL语句的区别

在 Snowflake 中处理多个 SQL 语句的存储过程

Mysql对象

一个存储过程中更新多个表可以用一个COMMIT吗 ?

Asp.net(C#) 获取 执行sql server 语句/存储过程后的 多个返回值?

存储过程和sql语句有啥区别