插入到 Table 中,第一列是序列

Insert into Table with the first column being a Sequence

我正在尝试使用插入、序列和 Select * 一起工作。

INSERT INTO BRK_INDV
Select * from (Select brk_seq.NEXTVAL as INDV_SEQ, a.*
FROM (select to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY') BUSINESS_DAY, to_char(REQUEST_DATETIME,'hh24') src_hour, 
CASE tran_type
WHEN 'V' THEN 'Visa'
WHEN 'M' THEN 'MasterCard'
ELSE tran_type
end text,
tran_type, count(*) as count 
from DLY_STATS
where 1=1
AND to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY') = '09-FEB-2015'
group by to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY'),to_char(REQUEST_DATETIME,'hh24'),tran_type order by src_hour)a);  

这给了我以下错误:

ERROR at line 2:
ORA-02287: sequence number not allowed here

我尝试删除订单,但仍然出现同样的错误。

但是,如果我只 运行

Select brk_seq.NEXTVAL as INDV_SEQ, a.*
FROM (select to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY') BUSINESS_DAY, to_char(REQUEST_DATETIME,'hh24') src_hour, 
CASE tran_type
WHEN 'V' THEN 'Visa'
WHEN 'M' THEN 'MasterCard'
ELSE tran_type
end text,
tran_type, count(*) as count 
from DLY_STATS
where 1=1
AND to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY') = '09-FEB-2015'
group by to_date(to_char(REQUEST_DATETIME,'DD-MM-YYYY'),'DD-MM-YYYY'),to_char(REQUEST_DATETIME,'hh24'),tran_type order by src_hour)a;

它向我显示了正确的条目。那么,为什么 select * 对此不起作用? 请帮忙。

问题是您不能在子查询中使用序列。例如,这会给出与您得到的相同的 ORA-02287 错误:

create table T (x number);

create sequence s;

insert into T (select * from (select s.nextval from dual));

不过,您可以做的是从序列中创建一个 returns nextval 的函数,并在子查询中使用它:

create function f return number as
begin
  return s.nextval;
end;
/

insert into T (select * from (select f() from dual));

我明白你想做什么了。您想要以特定顺序将行插入到 BRK_INDV table 中。序列号,我假设将是 BRK_INDV 的主键,将按照输入行的排序顺序依次生成。

您正在使用关系数据库。我们都了解关系数据库的第一个特征是 table 中行的顺序无关紧要。这只是 fugitaboutit.

的花哨词

您不能假设 select * from table 将 return 行以相同的写入顺序排列。它可能。可能会持续很长时间。然后一些东西——行数、一些列值的分组、月相——一些东西会改变,你会以看似完全随机的顺序把它们拿出来。

如果要排序,必须在查询中强加,不是插入。

这是您应该执行的语句:

INSERT INTO BRK_INDV
With
Grouped( Business_Day, Src_Hour, Text, Tran_Type, Count )As(
    Select  Trunc( Request_Datetime ) Business_Day,
            To_Char( Request_Datetime, 'hh24') Src_Hour,
        Case Tran_Type
            When 'V' Then 'Visa'
            When 'M' Then 'MasterCard'
            Else Tran_Type
        end Text,
        Tran_Type, count(*) as count 
    from DLY_STATS
    Where 1=1 --> Generated as dynamic SQL?
        And Request_Datetime >= Date '2015-02-09'
        And Request_Datetime < Date '2015-02-10'
    Group By Trunc( Request_Datetime ), To_Char( Request_Datetime, 'hh24'), Tran_Type
)
Select  brk_seq.Nextval Indv_Seq, G.*
from    Grouped G;

注意没有 order by。如果您想按特定顺序查看生成的行:

select * from Brk_Indv order by src_hour;

由于在任何特定时间可能有成百上千笔交易,您可能无论如何都按小时以外的时间订购。

在 Oracle 中,trunc 函数是获取去掉时间部分的日期的最佳方法。但是,您不想在 where 子句(或 aamof,任何其他函数,例如 to_dateto_char)中使用它,因为这会使子句不可搜索并且导致完整的 table 扫描。