Erro ao montar um cursor dinâmico

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
rsalbano
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 76
Registrado em: Seg, 11 Jul 2011 9:55 am
Localização: Curitiba

Olá,
Ao executar uma procedure com cursor dinâmico apresenta a mensagem "comando SQL não encerrado adequadamente".

Segue o cursor:

Selecionar tudo

   vSQL := 'Select nome, valor from vendas where datavenda > ' || VarData;
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

coloca um ; dentro da string.
rsalbano
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 76
Registrado em: Seg, 11 Jul 2011 9:55 am
Localização: Curitiba

Olá,

Realmente coloquei o ;dentro da string e funcionou, mas tenho outro problema que é o seguinte:

A coluna datavenda é timestamp e a vardata é date (vem de outra tabela).

Tentei assim:

Selecionar tudo

vSQL := Select nome, valor from vendas where 
                TO_CHAR(datavenda ,''MM/DD/YYYY'') >  ' || to_char(VarData , 'DD/MM/YYYY') || ';' ;
Aparece a mensagem "caractere inválido"
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

É muito facil achar o problema.
Basta verificar o que você ta montando no seu SQL dinamico.

De um PRINT nesse SQL e você verá que ele está montando algo assim:

FALTA ASPAS NA DATA

Selecionar tudo

Select nome, valor from vendas where 
TO_CHAR(datavenda ,'MM/DD/YYYY') >  15/10/2011; 



Ou seja, está faltando coisa aí !

Outra coisa: Se você comparar TEXTO, você terá como VERDADEIRO o seguinte: '11/jan/2011' < '20/jan/1980'
Isso porque o primeiro caracter 1 é menor que 2... Você ta comparando TEXTO aí e não datas.

Se quer comparar texto, use a máscara YYYY/MM/DD
OU faça a comparação com datas mesmo. (TO DATE)
rsalbano
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 76
Registrado em: Seg, 11 Jul 2011 9:55 am
Localização: Curitiba

Olá,

Realmente estava faltando algumas aspas simples
Ficou assim:

Selecionar tudo

vSQL := Select nome, valor from vendas where 
                cast(datavenda as date) >  ' || ''''|| DATA1 || '''; ';
Ao dar um print:

Selecionar tudo

 Select nome, valor from vendas where 
                cast(datavenda as date) >  '01/01/07'; 
Mas na procedure continua a aparecer a mensagem de caracter inválido.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

tem que ficar:

Selecionar tudo

to_date('01/01/07','mascara');
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

SIM, e como eu disse acima, a mascara DD/MM/YYYY NÃO vai funcionar.

Selecionar tudo

 '11/jan/2011' < '20/jan/1980'  
!!!!!!!!!
dom99
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Seg, 16 Jan 2012 4:18 am

Pessoal para não criar outro tópico resolvi colocar meu código aqui.
A empresa está mudando de software e precisam "validar" o que já foi migrado.
Então em cada tabela que deve ser migrada eu criei uma coluna chamada CORINGA.
Então eu deveria criar uma procedure dinâmica, onde o cara vai entrar com os valores que quiser para "validar" o campo CORINGA.
Para tratar a string vou fazer vários ifs para cada coluna da tabela.

Como eu sou novato e nunca fiz nada parecido, estou sofrendo um pouco.

Alguém pode me ajudar??

Selecionar tudo

CREATE OR REPLACE
PROCEDURE pcr_teste(
    tabela        IN VARCHAR2,
    unidade     IN VARCHAR2,
    valor         IN VARCHAR2
)
IS
  TYPE cursor1 IS REF CURSOR;
  c_cursor cursor1;
  whereclause VARCHAR2(100);
  condicao VARCHAR2(200);
  vsql VARCHAR2(500);
  saidasql varchar2(4000);
BEGIN

  IF unidade IS NOT NULL THEN
    condicao := tabela||'.unidade=' || unidade;
  END IF;
  
  whereclause := ' WHERE ' || condicao;
  
 open c_cursor for 'select unidade, cvcoringa from '||tabela||whereclause;

  loop
    fetch c_cursor INTO saidasql;
    exit WHEN c_cursor%notfound;
  END loop;
  EXECUTE IMMEDIATE 'UPDATE '||tabela||' SET cvcoringa ='||valor||whereclause;

  close c_cursor;


END pcr_teste
;
Riba
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Seg, 07 Jun 2010 3:16 pm
Localização: São Paulo, São Paulo

Sim, mas qual exatamente sua duvida?
Está dando algum erro?
dom99
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Seg, 16 Jan 2012 4:18 am

sim, está retornado este erro:

Erro ao iniciar na linha 1 no comando

Selecionar tudo

exec pcr_bruno('cvdesen', 'são paulo', 'teste')
Relatório de erro:

Selecionar tudo

ORA-00933: comando SQL não encerrado adequadamente
ORA-06512: em "DESENV.PCR_TESTE", line 21
ORA-06512: em line 1
00933. 00000 -  "SQL command not properly ended"
*Cause:    
*Action:
não consigo sair disso =/
Riba
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Seg, 07 Jun 2010 3:16 pm
Localização: São Paulo, São Paulo

Cara, eu testei aqui e não vi erro nenhum!
Verifica de novo o código que você esta testando.
dom99
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Seg, 16 Jan 2012 4:18 am

então cara, o erro está quando eu executo a procedure.

Esse erro que eu mostrei, é o retorno da execução da procedure.
Você viu no erro que eu entrei com 3 parâmetros ('cvdesen','são paulo','teste')
onde 'cvdesen' é a tabela, 'são paulo' é a unidade e 'teste' tem que gravar no update, na coluna coringa.
O Objetivo é passar o restante dos parametros depois, mas eu não consigo fazer o Update funcionar.
Dá erro.
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Dentre alguns problemas encontrados, o que não faz rodar é isso:

Selecionar tudo

open c_cursor for 'select unidade, cvcoringa from '||tabela||whereclause;

  loop
    fetch c_cursor INTO saidasql;
Você insere dois campos "unidade, cvcoringa" em uma única variável "saidasql".
Crie um row, um objeto, um collection para inserir o valor do cursor. Ou então crie uma variável para cada campo do seu cursor.

No seu caso você pode usar, por exemplo, seu campo "vsql" não utilizado e colocar :

Selecionar tudo

 fetch c_cursor INTO saidasql,vsql;
Obviamente se cvcoringa for do tipo varchar.
dom99
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Seg, 16 Jan 2012 4:18 am

continua dando erro =/

Erro ao iniciar na linha 1 no comando

Selecionar tudo

exec pcr_bruno('cvdesen', 'são paulo', 'teste')
Relatório de erro:

Selecionar tudo

ORA-00933: comando SQL não encerrado adequadamente
ORA-06512: em "DESENV.PCR_BRUNO", line 21
ORA-06512: em line 1
00933. 00000 -  "SQL command not properly ended"
*Cause:    
*Action:
Alguma sugestão para fazer isso de outra forma?
Acho que vou tentar fazer algo diferente...
Riba
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Seg, 07 Jun 2010 3:16 pm
Localização: São Paulo, São Paulo

Qual é a linha 21?
dom99
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Seg, 16 Jan 2012 4:18 am

Pessoal valeu a ajuda, resolvi fazer de outra maneira e deu certo aqui...
Valeu pessoal pela ajuda...

Selecionar tudo

create or replace
procedure vale_teste1(
    tabela        IN VARCHAR2,
    unidade       IN VARCHAR2,
    valor         in VARCHAR2
)
IS
  whereclause VARCHAR2(200);
  condicao VARCHAR2(200);
                              
BEGIN
  whereclause := Null;
 
  IF unidade IS NOT NULL THEN
    whereclause := 'cvareaunidade'||' = ' || '''' || unidade || '''';
  END IF;
 
  IF whereclause is not null then
     whereclause := 'WHERE ' || whereclause;
  end if;
 
 EXECUTE IMMEDIATE  'UPDATE '||tabela||' SET cvcoringa = '|| '''' || valor || '''' ||' '||whereclause;
END vale_teste1
;
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 3 visitantes