sql - una - ¿Cómo puedo insertar varias filas en el oráculo con un valor de secuencia?
secuencia alfanumerica oracle (6)
De http://www.orafaq.com/wiki/ORA-02287 , el error 02287 es
ORA-02287 se produce cuando utiliza una secuencia donde no está permitido.
De los lugares donde las secuencias no se pueden usar, parece que estás intentando:
En una subconsulta
Entonces parece que no puedes hacer múltiplos en la misma declaración.
La solución que ofrecen es:
Si desea que el valor de la secuencia se inserte en la columna para cada fila creada, cree un desencadenante antes de insertar y busque el valor de la secuencia en el desencadenador y asígnelo a la columna
Sé que puedo insertar varias filas usando una sola declaración, si uso la sintaxis en esta respuesta .
Sin embargo, uno de los valores que estoy insertando está tomado de una secuencia, es decir,
insert into TABLE_NAME
(COL1,COL2)
select MY_SEQ.nextval,''some value'' from dual
union all
select MY_SEQ.nextval,''another value'' from dual
;
Si trato de ejecutarlo, aparece un error ORA-02287. ¿Hay alguna forma de evitar esto, o debería usar muchas instrucciones INSERT?
EDITAR:
Si tengo que especificar nombres de columna para todas las demás columnas que no sean la secuencia, pierdo la brevedad original, por lo que simplemente no vale la pena. En ese caso, solo usaré múltiples instrucciones INSERT.
Esto funciona:
insert into TABLE_NAME (COL1,COL2)
select my_seq.nextval, a
from
(SELECT ''SOME VALUE'' as a FROM DUAL
UNION ALL
SELECT ''ANOTHER VALUE'' FROM DUAL)
No funciona porque la secuencia no funciona en los siguientes escenarios:
- En una cláusula WHERE
- En una cláusula GROUP BY u ORDER BY
- En una cláusula DISTINCT
- Junto con UNIÓN o INTERSECCIONAR o MENOS
- En una subconsulta
Fuente: http://www.orafaq.com/wiki/ORA-02287
Sin embargo, esto funciona:
insert into table_name
(col1, col2)
select my_seq.nextval, inner_view.*
from (select ''some value'' someval
from dual
union all
select ''another value'' someval
from dual) inner_view;
Pruébalo:
create table table_name(col1 varchar2(100), col2 varchar2(100));
create sequence vcert.my_seq
start with 1
increment by 1
minvalue 0;
select * from table_name;
Una posibilidad es crear un disparador en la inserción para agregar el número de secuencia correcto.
esto funciona y no hay necesidad de usar la unión de todo.
Insert into BARCODECHANGEHISTORY (IDENTIFIER,MESSAGETYPE,FORMERBARCODE,NEWBARCODE,REPLACEMENTDATETIME,OPERATORID,REASON)
select SEQ_BARCODECHANGEHISTORY.nextval, MESSAGETYPE, FORMERBARCODE, NEWBARCODE, REPLACEMENTDATETIME, OPERATORID, REASON
from (
SELECT
''BAR'' MESSAGETYPE,
''1234567890'' FORMERBARCODE,
''1234567899'' NEWBARCODE,
to_timestamp(''20/07/12'',''DD/MM/RR HH24:MI:SSXFF'') REPLACEMENTDATETIME,
''PIMATD'' OPERATORID,
''CORRECTION'' REASON
FROM dual
);
insert into TABLE_NAME
(COL1,COL2)
WITH
data AS
(
select ''some value'' x from dual
union all
select ''another value'' x from dual
)
SELECT my_seq.NEXTVAL, x
FROM data
;
Creo que eso es lo que quieres, pero no tengo acceso a Oracle para probarlo ahora mismo.