Insérer du texte avec des guillemets simples dans PostgreSQL
j'ai une table test(id,name)
.
je dois insérer des valeurs comme: user's log
, 'my user'
, customer's
.
insert into test values (1,'user's log');
insert into test values (2,''my users'');
insert into test values (3,'customer's');
j'obtiens une erreur si je n'ai aucun des énoncés ci-dessus.
S'il y a une méthode pour le faire correctement s'il vous plaît partager. Je ne veux pas de déclarations préparées.
est-il possible d'utiliser le mécanisme d'échappement sql?
6 réponses
échapper à des citations simples '
en les doublant - > ''
est la voie standard et fonctionne bien sûr.
'user's log' -- incorrect syntax (unbalanced quote)
'user''s log'
dans les anciennes versions ou si vous utilisez toujours standard_conforming_strings = off
ou, en général, si vous préparez votre chaîne de caractères avec E
pour déclarer syntaxe de la chaîne de caractères Posix , vous pouvez également vous échapper avec le antislash \
:
E'user\'s log'
mais c'est généralement pas souhaitable.
Si vous devez traiter avec de nombreuses citations simples ou plusieurs couches d'échapper, vous pouvez éviter de citer l'enfer dans PostgreSQL avec Dollar-quoted strings :
'escape '' with '''''
$$escape ' with ''$$
pour éviter toute confusion entre les guillemets, ajoutez un jeton unique à chaque paire:
$token$escape ' with ''$token$
qui peut être imbriqué dans n'importe quel nombre de niveaux:
$token2$Inner string: $token1$escape ' with ''$token1$ is nested$token2$
faites attention si le caractère $
devrait avoir une signification particulière dans votre logiciel client. Vous devrez peut-être y échapper en plus. Ce n'est pas le cas avec les clients PostgreSQL standards comme psql ou pgAdmin.
tout cela est très utile pour écrire des fonctions plpgsql ou des commandes SQL ad hoc. Il ne peut pas soulager la nécessité d'utiliser des déclarations préparées ou une autre méthode pour se prémunir contre L'injection SQL dans votre application lorsque l'utilisateur est possible d'entrer, bien. la réponse de @Craig en dit plus. Plus de détails:
C'est tellement de mondes de mauvais, parce que votre question implique que vous avez probablement gaping injection SQL trous dans votre application.
vous devriez utiliser des instructions paramétrées. Pour Java, utilisez PreparedStatement
avec des espaces réservés . Vous dites que vous ne voulez pas utiliser des déclarations paramétrées, mais vous n'expliquez pas pourquoi , et franchement il doit y avoir une très bonne raison de ne pas les utiliser parce qu'ils sont la plus simple, la plus sûre façon de résoudre le problème que vous essayez de résoudre.
Voir Prévenir l'Injection SQL en Java . Ne sois pas la prochaine victime de Bobby .
il n'y a pas de fonction publique dans PgJDBC pour la citation de chaîne et l'évasion. C'est en partie parce qu'il pourrait sembler comme une bonne idée.
il sont fonctions de citation intégrées quote_literal
et quote_ident
dans PostgreSQL, mais ils sont pour PL/PgSQL
fonctions qui utilisent EXECUTE
. Ces jours-ci quote_literal
est la plupart du temps obsolète par EXECUTE ... USING
, qui est la version paramétrée , parce que c'est plus sûr et plus facile . Vous ne pouvez pas les utiliser dans le but que vous expliquez ici, parce que ce sont des fonctions côté serveur.
imaginez ce qui se passe si vous obtenez la valeur ');DROP SCHEMA public;--
d'un utilisateur malveillant. Vous produiriez:
insert into test values (1,'');DROP SCHEMA public;--');
qui se décompose en deux déclarations et un commentaire qui est ignoré:
insert into test values (1,'');
DROP SCHEMA public;
--');
Oups, voilà votre base de données.
selon documentation PostgreSQL (4.1.2.1. Constantes De Chaîne) :
To include a single-quote character within a string constant, write two
adjacent single quotes, e.g. 'Dianne''s horse'.
Voir aussi le paramètre standard_conforming_strings , qui contrôle si l'évasion avec backslashes fonctionne.
en postgresql si vous voulez insérer des valeurs avec '
en elle, alors pour cela vous devez donner supplémentaire '
insert into test values (1,'user''s log');
insert into test values (2,'''my users''');
insert into test values (3,'customer''s');
vous pouvez utiliser la fonction postrgesql chr(int):
insert into test values (2,'|| chr(39)||'my users'||chr(39)||');
si vous avez besoin de faire le travail à L'intérieur de Pg:
to_json(value)
https://www.postgresql.org/docs/9.3/static/functions-json.html#FUNCTIONS-JSON-TABLE