Como faço para lidar com aspas 'em SQL [duplicado]
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.
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.
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...