2015-03-19 1 views
0

J'essaie d'utiliser une insertion, une séquence et une sélection * pour travailler ensemble.Insérer dans le tableau avec la première colonne étant une séquence

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); 

Cela me donne l'erreur suivante:

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

J'ai essayé de supprimer l'ordre et par toujours la même erreur.

Cependant, si je ne diffusez que

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; 

Il me montre les entrées appropriées. Alors, pourquoi select * ne fonctionne pas pour ça? Veuillez nous aider.

Répondre

1

Je vois ce que vous essayez de faire. Vous souhaitez insérer des lignes dans la table BRK_INDV dans un ordre particulier. Le numéro de séquence, que je suppose être la clé primaire de BRK_INDV, sera généré séquentiellement dans l'ordre trié des lignes d'entrée.

Vous travaillez avec une base de données relationnelle. L'une des premières caractéristiques que nous connaissons tous d'une base de données relationnelle est que l'ordre des lignes dans une table est insignifiant. C'est juste un mot de fantaisie pour fugitaboutit.

Vous ne pouvez pas supposer qu'un select * from table retournera les lignes dans le même ordre que celui dans lequel elles ont été écrites. Ça pourrait. Cela pourrait durer longtemps. Puis quelque chose - le nombre de lignes, le regroupement de certaines valeurs de colonne, la phase de la lune - quelque chose va changer et vous les sortirez dans un ordre apparemment totalement aléatoire.

Si vous voulez l'ordre, il doit être imposé dans la requête, pas l'insertion.

Voici la déclaration que vous devriez d'exécution:

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; 

avis il n'y a pas order by. Si vous voulez voir les lignes générées dans un ordre particulier:

select * from Brk_Indv order by src_hour; 

Depuis qu'il pourrait y avoir des centaines ou des milliers de transactions en une heure particulière, vous avez probablement ordre par autre chose que l'heure de toute façon.

Dans Oracle, la fonction trunc est le meilleur moyen d'obtenir une date avec la partie heure supprimée. Cependant, vous ne voulez pas l'utiliser dans la clause where (ou, aamof, toute autre fonction telle que to_date ou to_char) car cela rendrait la clause non-sargable et entraînerait un balayage de table complet.

+0

Merci un million monsieur. Ça a marché comme sur des roulettes. – user2967948

1

Le problème est que vous ne pouvez pas utiliser une séquence dans une sous-requête. Par exemple, cela donne la même ORA-02287 erreur que vous obtenez:

create table T (x number); 

create sequence s; 

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

Ce que vous pouvez faire, cependant, est de créer une fonction qui retourne nextval de la séquence, et l'utiliser dans une sous-requête:

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

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