Pergunta

Essa pergunta já tem resposta aqui:

Eu tenho um banco de dados com nomes como John Doe etc.Infelizmente, alguns desses nomes contêm citações como Keiran O'Keefe.Agora, quando tento pesquisar os nomes a seguir:

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

Eu (compreensivelmente) recebo um erro.

Como evito que esse erro ocorra.Estou usando Oracle e PLSQL.

Foi útil?

Solução

O caractere de escape é ', então você precisaria substituir a aspa por duas aspas.

Por exemplo,

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

torna-se

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

Dito isto, provavelmente é incorreto fazer isso sozinho.Sua linguagem pode ter uma função para escapar de strings para uso em SQL, mas uma opção ainda melhor é usar parâmetros.Geralmente isso funciona da seguinte maneira.

Seu comando SQL seria:

SELECT * FROM PEOPLE WHERE SURNAME=?

Então, ao executá-lo, você passa "O'Keefe" como parâmetro.

Como o SQL é analisado antes de o valor do parâmetro ser definido, não há como o valor do parâmetro alterar a estrutura do SQL (e é ainda um pouco mais rápido se você quiser executar a mesma instrução várias vezes com parâmetros diferentes).

Devo também salientar que, embora seu exemplo apenas cause um erro, você se expõe a muitos outros problemas ao não escapar das strings de maneira adequada.Ver http://en.wikipedia.org/wiki/SQL_injection para um bom ponto de partida ou o seguinte clássico quadrinhos xkcd.

alt text

Outras dicas

A solução Oracle 10 é

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'

Consultas parametrizadas são suas amigas, conforme sugerido por Matt.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

Eles irão protegê-lo de dores de cabeça envolvidas com

  • Strings com aspas
  • Consultando usando datas
  • Injeção SQL

O uso de SQL parametrizado tem outros benefícios: reduz a sobrecarga da CPU (bem como outros recursos) no Oracle, reduzindo a quantidade de trabalho que o Oracle requer para analisar a instrução.Se você não usar parâmetros (nós os chamamos de variáveis ​​de ligação no Oracle), então "select * from foo where bar='cat'" e "select * from foo where bar='dog'" serão tratados como instruções separadas, onde como " select * from foo where bar=:b1" é a mesma instrução, o que significa que coisas como sintaxe, validade de objetos referenciados, etc... não precisam ser verificadas novamente.Existem problemas ocasionais que surgem ao usar variáveis ​​de ligação que geralmente se manifestam na não obtenção do plano de execução SQL mais eficiente, mas existem soluções alternativas para isso e esses problemas realmente dependem dos predicados que você está usando, indexação e distorção de dados.

A filtragem de entrada geralmente é feita no nível da linguagem, e não nas camadas do banco de dados.
php e .NET têm suas respectivas bibliotecas para escapar de instruções sql.Verifique seu idioma, veja o que está disponível.
Se seus dados forem confiáveis, você pode simplesmente substituir uma string para adicionar outro ' na frente do ' para escapar dele.Normalmente, isso é suficiente se não houver riscos de a entrada ser maliciosa.

Suponho que uma boa pergunta é qual idioma você está usando?
Em PHP você faria:SELECIONE * DE PESSOAS ONDE SOBRENOME='mysql_escape_string(O'Keefe)'
Mas como você não especificou o idioma, sugiro que você procure uma função de string de escape mysql ou de outra forma no seu idioma.

Para negociar cotações se você estiver usando Zend Framework aqui está o código

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

por exemplo ;

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''

Encontrado em menores de 30 anos no Google...

Perguntas frequentes sobre Oracle SQL

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top