在 Oracle 中将结果集插入到表中

Posted

技术标签:

【中文标题】在 Oracle 中将结果集插入到表中【英文标题】:Inserting a resultset into a Table in Oracle 【发布时间】:2010-07-28 08:38:59 【问题描述】:

嘿嘿,

我必须编写一个将 select 语句中的结果集插入到表中的过程。 我的一位同事之前做过类似的事情,将值从一个表复制到另一个表。他的陈述是这样的:

CREATE OR REPLACE PROCEDURE Co-Worker(
    pId IN INT
)
AS
BEGIN
    INSERT INTO Table1_PROCESSED
    SELECT * FROM Table1
    WHERE ID = pId;

    DELETE FROM Table1
    WHERE ID = pId;

END Co-Worker;
/

这里提到的两个表具有相同的结构(实际上 table1_processed 只是表 1 的副本)。 所以我想“嘿!我也从我的选择语句中得到了一个结果集!所以我为什么不稍微调整一下呢!” 所以我像这样创建了我的表:

MyTable:
TIMEID (number) | NAME (varchar2 - 128)
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

我的程序是这样的:

CREATE OR REPLACE procedure MyProcedure(
pdate in date,
pJobtype in number  default 3,
pTasktype in number default 4,
pJobstatus in number default 1,
pTaskstatus in number default 4
)
AS
    pformateddate date;
BEGIN
    Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
    into pformateddate 
    from dual;
Insert into MyTable (TIMEID, NAME)
Select Function_GETTIMEID(to_date(st, 'DD.MM.YYYY HH24')) TIMEID
       ,to_char(ext) NAME 
from(
    Select to_char(arch_job.exec_start, 'DD.MM.YYYY HH24') st
           ,file.name ext
           , count(file.id) cnt
    from 
         arch_task_file 
             left join file on arch_task_file.File_ID = file.ID
             left join arch_task on arch_task_file.Task_ID = arch_task.ID
             left join arch_job on arch_task.Job_ID = arch_job.ID
    where 
        arch_job.exec_start > pformateddate 
        and arch_job.exec_end <pformateddate + 1 
        and arch_job.jobtype_id = pJobtype 
        and arch_job.jobstatus_id = pJobstatus 
        and arch_task.Tasktype_ID = pTasktype 
        and arch_task.Taskstatus_ID = pTaskstatus
     group by 
         file.name,
           to_char(arch_job.exec_start, 'DD.MM.YYYY HH24'
       )
    );
End MyProcedure;
/

大型 Select-Statement ALONE 的结果如下所示:

TIMEID      | NAME
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

但是如果我执行这个程序并给它一个 dummydate(sysdate - 12 或像 '16.07.2010 10:32:50' 这样的日期),我的 Toad 会给我一条消息“程序已完成”,我的表仍然是空的。 .! 但正如之前所说,大的 Select-Statement 给出了结果,所以不应该尝试插入一个空的结果集......!谁能告诉我为什么我的程序不起作用?

感谢每一个有用的答案。 =)

你好!

附:

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

需要缩短 pDate 值!我测试了它,所以它也可以工作,你可以在整个逻辑中忽略它。在这里只是为了让您全面了解情况!

【问题讨论】:

要更简单地“缩短” pDate 值,您可以这样做: pformateddate := trunc(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS')); 事实上,我没有发现 pDate 是一个日期,所以你只需要“pformatteddaet := trunc(pDate);” 【参考方案1】:

这是 SQL 论坛中非常常见的模式。模式是OP所说的

“我在我的 TOAD 工作表中运行此 SQL (或其他)并且它有效。但当 我将它包含在不同的上下文中- 比如一个存储过程——它 不起作用。什么给了?”

给出的是两个陈述不相同。某处有一个错误的转录。也许一个连接已被省略或添加了一个额外的连接。最可能的错误来源是用存储过程中的参数替换工作表中的文字。

显然我不能告诉你区别在哪里。我所能做的就是敦促您仔细检查这两个 SQL 语句并找出差异。

如果您真的找不到任何差异,那么您将需要调试您的代码。最快的开始方法是使用 Devil's Debugger。在插入语句之后添加这一行:

dbms_output.put_line('Rows inserted = '||to_char(sql%rowcount));

您需要在 TOAD 中启用 DBMS_OUTPUT;某处有一个标签。这至少会告诉您查询是否真的返回零行,或者您的过程是否正在插入行并且由于某种原因您没有看到它们。这是两个不同的问题。

【讨论】:

【参考方案2】:

您需要在运行此过程的 Toad 会话中进行 COMMIT,然后才能在任何其他会话(例如表浏览器)中查看表中的数据。你记得这样做吗?

【讨论】:

【参考方案3】:

与您的问题无关,但这个

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

只是从传递的参数中删除时间元素的一种冗长的方法。这做同样的事情:

Select trunc(pdate) 
into pformateddate 
from dual; 

或者正如托尼指出的那样,一个简单的任务:

pformateddate := trunc(pdate);

【讨论】:

@Tony。是的,我原本以为是 sysdate,后来发现是个参数后就没有跟进了。

以上是关于在 Oracle 中将结果集插入到表中的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle Apex 中将图像插入到表中

sql 将查询的结果集一次性插入到表变量中

Google BigQuery:将查询结果保存到表时找不到数据集

如何使用 VBA 将“整个”DAO 记录集插入到表中

在 Oracle 中为结果集生成插入语句

使用 PHP 将多行 Oracle 结果集插入 MYSQL