2009-08-28 5 views

Répondre

39

PostgreSQL ne prend pas en charge le stockage NULL (\ 0x00) caractères dans les champs de texte (ce qui est évidemment différent de la base de données valeur NULL, qui est entièrement pris en charge).

Source: http://www.postgresql.org/docs/9.1/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE

Si vous devez stocker le caractère NULL, vous devez utiliser un champ bytea - qui devrait stocker tout ce que vous voulez, mais ne sera pas en charge les opérations de texte sur elle. Etant donné que PostgreSQL ne le supporte pas dans les valeurs de texte, il n'y a pas de bon moyen de le faire pour le supprimer. Vous pouvez importer vos données dans bytea et les convertir ultérieurement en texte en utilisant une fonction spéciale (en perl ou quelque chose, peut-être?), Mais il sera probablement plus facile de le faire en pré-traitement avant de le charger.

+0

Exemple: 'CREER store_bytes TABLE ( ENTIER clé NOT NULL , data bytea NOT NULL ); ' – zengr

1

Vous pouvez d'abord insérer des données dans le champ blob, puis copier le champ de texte avec la fonction folloing

CREATE OR REPLACE FUNCTION blob2text() RETURNS void AS $$ 
Declare 
    ref record; 
    i integer; 
Begin 
    FOR ref IN SELECT id, blob_field FROM table LOOP 

      -- find 0x00 and replace with space  
     i := position(E'\\000'::bytea in ref.blob_field); 
     WHILE i > 0 LOOP 
     ref.bob_field := set_byte(ref.blob_field, i-1, 20); 
     i := position(E'\\000'::bytea in ref.blobl_field); 
     END LOOP 

    UPDATE table SET field = encode(ref.blob_field, 'escape') WHERE id = ref.id; 
    END LOOP; 

End; $$ LANGUAGE plpgsql; 

-

SELECT blob2text(); 
15

Juste regex sur des octets nuls:

s/\x00//g; 
+1

est une chaîne vide considérée comme un octet nul? Est-ce que 'replaceAll (" s/\ x00 // g "," ")' ne va pas les remplacer par d'autres null? –

+2

Les chaînes vides ne sont pas considérées comme des octets nuls. Les valeurs d'octet nul sont des caractères réels, mais invisibles. –

4

Si vous utilisez Java, vous pouvez simplement remplacer les caractères x00 avant l'insertion comme suit:

myValue.replaceAll("\u0000", "") 

La solution a été fournie et expliquée par Csaba en suivant après:

https://www.postgresql.org/message-id/1171970019.3101.328.camel%40coppola.muc.ecircle.de

Respectivement:

in Java you can actually have a "0x0" character in your string, and that's valid unicode. So that's translated to the character 0x0 in UTF8, which in turn is not accepted because the server uses null terminated strings... so the only way is to make sure your strings don't contain the character '\u0000'.

Questions connexes