Por que a última instrução PL / SQL falha usando dbms_assert.enquote_literal?

9

As declarações firs e second "put_line" no bloco PL / SQL abaixo serão bem-sucedidas, mas a última falhará. Por quê? Poderia ser um bug?

declare
  x varchar2(100);
begin
  x := 'Test'''; 
  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', ''''''))); 

  x := 'Te''st';
  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', '''''')));  

  x := '''Test';
  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || dbms_assert.enquote_literal(replace(x, '''', ''''''))); 
end;
/

O erro é:

Error report:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.DBMS_ASSERT", line 317
ORA-06512: at "SYS.DBMS_ASSERT", line 381
ORA-06512: at line 11
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    
*Action:

Alguma ideia?

    
por RGO 20.08.2015 в 14:08
fonte

2 respostas

1

Não é possível dizer por que isso está acontecendo, mas você pode tentar abaixo para lidar com isso:

    set serveroutput on;
declare
  x varchar2(100);
begin
  x := 'Test'''; 
  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '''''')), ''' ', '''')); 

  x := 'Te''st';
  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '''''')), ''' ', ''''));  

  x := '''Test';

  dbms_output.put_line('x is: ' || x || ', enquoted x is: ' 
  || replace(dbms_assert.enquote_literal(replace(x, '''', ' ''''')), ''' ', '''')
  ); 
end;
/

x is: Test', enquoted x is: 'Test'''
x is: Te'st, enquoted x is: 'Te''st'
x is:  'Test, enquoted x is: '''Test'
PL/SQL procedure successfully completed.
    
por Vinish Kapoor 20.08.2015 / 15:22
fonte
1

é mencionado em link que When using ENQUOTE_LITERAL, remember to escape single quotes in the input. mas não explicou muito bem.

Nos documentos da oracle, link

 Usage Notes    
        Verify that all single quotes except leading and trailing characters are paired with adjacent single quotes.    
        No additional quotes are added if the name was already in quotes.

Esta pergunta é um bom exemplo de que ENQUOTE_LITERAL não irá solicitar strings que já tenham sido citadas. Mas o que foi mencionado acima apenas nos limita a ENQUOTE_LITERAL.So que é a solução para isso. Como @Vinish Kapoor faz um truque em sua resposta que você pode ver. Então, em caso de limitações, podemos converter string em algum outro padrão e substituí-lo de volta ao normal. você pode usar abaixo também

 dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '#')), '#', ''''));

ou este aqui

 dbms_output.put_line('x is: ' || x || ', enquoted x is: ' || replace(dbms_assert.enquote_literal(replace(x, '''', '~')), '~', ''''));

porque os qoutes simples à esquerda e à direita estão causando problemas, podemos convertê-los em # ou ~ e depois que a enquote_literal tiver feito seu trabalho, podemos substituí-los de volta para qoutes únicos.

    
por Shravan Yadav 20.08.2015 / 15:53
fonte