Tabela temporária no Oracle
Colegas, boa tarde!
O código abaixo funciona fora da procedure mas quando eu coloco dentro de uma procedure ela dá o seguinte erro:
Erro(6,1): PLS-00103: Encontrado o símbolo CREATE quando um dos seguintes símbolos era esperado: ( começar case declare sair for goto if loop mod nulo pragma raise retornar selecionar atualizar while com <um identificador> <um identificador delimitado por aspas duplas> <uma variável de ligação> << continuar fechar atual deletar fetch lock insert aberto rollback savepoint set sql executar commit forall intercalar pipe expurgar
----------------------------------------------------------------------------------------------------
Segue abaixo procedure:
CREATE OR REPLACE procedure SGIPA.PROC_IMP_EVENTO_NVOCC iS
BEGIN
create global temporary table TB_FILA (ID_FILA number(5));
INSERT INTO TB_FILA SELECT ID_FILA FROM TB_IMP_EVENTO_FILA WHERE PROCESSADO = 0;
declare V_QTDE NUMBER;
SET V_QTDE := (SELECT COUNT(ID_FILA) FROM TB_FILA);
IF V_QTDE > 0 THEN
SELECT TRK AS TRK , NEW AS NEW
, case when length(B.NUMERO) < 16 then B.NUMERO else substr(B.NUMERO, 2, length(B.NUMERO)) end as NUMERO_BL
, AS RANKING, AS SUFFIX
, E.PROCARS AS EVENTO
, CONCAT(PAIS, TRIGRAMA) AS PORTO
, TO_CHAR( F.DATA, DD-MM-YYYY hh:mm:ss) as DATA
, (LPAD( , 40 , )) AS OBS, RCNT AS RCNT, C.ID_CONTEINER
FROM SGIPA.TB_IMP_EVENTO_FILA F
INNER JOIN SGIPA.TB_IMP_CAD_EVENTO E
ON F.ID_EVENTO = E.ID_EVENTO
INNER JOIN SGIPA.TB_BL B
ON F.AUTONUM_BL = B.AUTONUM
INNER JOIN SGIPA.TB_CNTR_BL C
ON F.AUTONUM_CNTR = C.AUTONUM
INNER JOIN SGIPA.DTE_TB_PORTOS P
ON B.PORTO_ORIGEM = P.CODE
WHERE F.PROCESSADO = 0;
AND ID_FILA IN (SELECT * FROM TB_FILA);
UPDATE SGIPA.TB_IMP_EVENTO_FILA SET PROCESSADO = 1 WHERE ID_FILA IN (SELECT * FROM TB_FILA)
END IF;
DROP TABLE TB_FILA;
commit;
END;
----------------------------------------------------------------------------------------------------
Grata, Indy
O código abaixo funciona fora da procedure mas quando eu coloco dentro de uma procedure ela dá o seguinte erro:
Erro(6,1): PLS-00103: Encontrado o símbolo CREATE quando um dos seguintes símbolos era esperado: ( começar case declare sair for goto if loop mod nulo pragma raise retornar selecionar atualizar while com <um identificador> <um identificador delimitado por aspas duplas> <uma variável de ligação> << continuar fechar atual deletar fetch lock insert aberto rollback savepoint set sql executar commit forall intercalar pipe expurgar
----------------------------------------------------------------------------------------------------
Segue abaixo procedure:
CREATE OR REPLACE procedure SGIPA.PROC_IMP_EVENTO_NVOCC iS
BEGIN
create global temporary table TB_FILA (ID_FILA number(5));
INSERT INTO TB_FILA SELECT ID_FILA FROM TB_IMP_EVENTO_FILA WHERE PROCESSADO = 0;
declare V_QTDE NUMBER;
SET V_QTDE := (SELECT COUNT(ID_FILA) FROM TB_FILA);
IF V_QTDE > 0 THEN
SELECT TRK AS TRK , NEW AS NEW
, case when length(B.NUMERO) < 16 then B.NUMERO else substr(B.NUMERO, 2, length(B.NUMERO)) end as NUMERO_BL
, AS RANKING, AS SUFFIX
, E.PROCARS AS EVENTO
, CONCAT(PAIS, TRIGRAMA) AS PORTO
, TO_CHAR( F.DATA, DD-MM-YYYY hh:mm:ss) as DATA
, (LPAD( , 40 , )) AS OBS, RCNT AS RCNT, C.ID_CONTEINER
FROM SGIPA.TB_IMP_EVENTO_FILA F
INNER JOIN SGIPA.TB_IMP_CAD_EVENTO E
ON F.ID_EVENTO = E.ID_EVENTO
INNER JOIN SGIPA.TB_BL B
ON F.AUTONUM_BL = B.AUTONUM
INNER JOIN SGIPA.TB_CNTR_BL C
ON F.AUTONUM_CNTR = C.AUTONUM
INNER JOIN SGIPA.DTE_TB_PORTOS P
ON B.PORTO_ORIGEM = P.CODE
WHERE F.PROCESSADO = 0;
AND ID_FILA IN (SELECT * FROM TB_FILA);
UPDATE SGIPA.TB_IMP_EVENTO_FILA SET PROCESSADO = 1 WHERE ID_FILA IN (SELECT * FROM TB_FILA)
END IF;
DROP TABLE TB_FILA;
commit;
END;
----------------------------------------------------------------------------------------------------
Grata, Indy
Ingrid Valentim
Curtidas 0
Respostas
Diego Lusa
01/03/2012
Ingrid, tudo bem?
Comandos DDL não são permitidos dentro de procedures. Mas você pode ultrapassar este impedimento utilizando o comando EXECUTE IMMEDIATE. Você pode encontrar mais informações neste link http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/executeimmediate_statement.htm
Comandos DDL não são permitidos dentro de procedures. Mas você pode ultrapassar este impedimento utilizando o comando EXECUTE IMMEDIATE. Você pode encontrar mais informações neste link http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/executeimmediate_statement.htm
GOSTEI 0
Danielle Lemos
01/03/2012
Ingrid,
Nao precisa criar e dropar a tabela em cada execucao da stored procedure.
Vc pode criar a tabela temporaria e apenas referencia-la dentro da SP.
Atc,
Dani
Nao precisa criar e dropar a tabela em cada execucao da stored procedure.
Vc pode criar a tabela temporaria e apenas referencia-la dentro da SP.
Atc,
Dani
GOSTEI 0
Marcelo Migliorança
01/03/2012
Pessoal
Eu estava fazendo uma pesquisa e tropecei neste assunto. Mesmo sendo uma postagem antiga, fica a minha sugestão para os navegantes.
Comigo o código abaixo é infalível:
DROP TABLE TEMP_TB;
--
CREATE GLOBAL TEMPORARY TABLE TEMP_TB
(CIA NUMBER(2) NOT NULL,
PRODUTO NUMBER(3),
QUANTIDADE NUMBER(6)
) ON COMMIT PRESERVE ROWS ;
INSERT INTO TEMP_TB VALUES (1,123,177);
commit;
DECLARE V_COUNT1 NUMBER :=0;
BEGIN
FOR C IN (
SELECT
CIA ,
PRODUTO ,
QUANTIDADE
FROM
TEMP_TB
) LOOP
BEGIN
UPDATE TB_PRODUTO_QTD A
SET A.QUANTIDADE = C.QUANTIDADE
WHERE A.CIA = C.CIA
AND A.PRODUTO = C.PRODUTO;
if sql%rowcount = 1 then
commit;
else
rollback;
end if;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
END LOOP;
END;
/
--
TRUNCATE TABLE TEMP_TB;
DROP TABLE TEMP_TB;
OBS: Na minha opinião convém dropar a tabela temporária antes da execução e também truca-la e dropa-la após a execução (é mais seguro).
Eu estava fazendo uma pesquisa e tropecei neste assunto. Mesmo sendo uma postagem antiga, fica a minha sugestão para os navegantes.
Comigo o código abaixo é infalível:
DROP TABLE TEMP_TB;
--
CREATE GLOBAL TEMPORARY TABLE TEMP_TB
(CIA NUMBER(2) NOT NULL,
PRODUTO NUMBER(3),
QUANTIDADE NUMBER(6)
) ON COMMIT PRESERVE ROWS ;
INSERT INTO TEMP_TB VALUES (1,123,177);
commit;
DECLARE V_COUNT1 NUMBER :=0;
BEGIN
FOR C IN (
SELECT
CIA ,
PRODUTO ,
QUANTIDADE
FROM
TEMP_TB
) LOOP
BEGIN
UPDATE TB_PRODUTO_QTD A
SET A.QUANTIDADE = C.QUANTIDADE
WHERE A.CIA = C.CIA
AND A.PRODUTO = C.PRODUTO;
if sql%rowcount = 1 then
commit;
else
rollback;
end if;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
END LOOP;
END;
/
--
TRUNCATE TABLE TEMP_TB;
DROP TABLE TEMP_TB;
OBS: Na minha opinião convém dropar a tabela temporária antes da execução e também truca-la e dropa-la após a execução (é mais seguro).
GOSTEI 0
José
01/03/2012
Obrigado pela dica, e como aparentemente a duvida foi sanada, estou dando o tópico por concluído.
GOSTEI 0