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?

262
demandé sur a_horse_with_no_name 2012-09-07 15:11:11

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:

512
répondu Erwin Brandstetter 2018-07-19 15:43:10

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.

39
répondu Craig Ringer 2012-09-07 11:56:49

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.

15
répondu Claudix 2012-09-07 11:51:16

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');
6
répondu Hunter 2012-09-07 20:44:21

vous pouvez utiliser la fonction postrgesql chr(int):

insert into test values (2,'|| chr(39)||'my users'||chr(39)||');
3
répondu Slava Struminski 2017-12-29 10:00:36

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

1
répondu hatenine 2017-12-18 17:01:02