web-dev-qa-db-fra.com

Comment puis-je corriger cette valeur trop longtemps pour le caractère de type variant (5)?

J'ai créé une petite base de données de développement pour la pratique. Il a une table cities avec les colonnes cityname et state. Le cityname là-dedans est 'Cincinnati', nom long non?

mytestdb=# SELECT * FROM cities;
 cityid |  cityname  | state
--------+------------+-------
 12345  | Cincinnati | Ohio
(1 row)

Je ne sais pas comment et pourquoi j'obtiens ce message d'erreur en essayant d'ajouter "San Francisco".

mytestdb=# INSERT INTO cities VALUES ('San Francisco','CA');
ERROR:  value too long for type character varying(5)
7
Daniel

Alors d'abord, quelle est la différence ..

SELECT x, length(x)
FROM ( VALUES
  ('Cincinnati'),
  ('San Francisco')
) AS t(x);

Voici la sortie

       x       | length 
---------------+--------
 Cincinnati    |     10
 San Francisco |     13

Donc..

  1. San Francisco compte trois personnages de plus.
  2. Ils ont tous les deux plus de 5 caractères.
  3. Ça ne peut pas être le problème.

Et en outre, si Cincinnati était dans une varchar(5), elle devrait être tronquée.

Le problème est donc votre cityid. C'est varchar(5). vous voudrez probablement que ce soit un int de toute façon - ce sera plus compact et plus rapide. Donc ALTER la table et corrigez-la.

ALTER TABLE cities
  ALTER COLUMN cityid SET DATA TYPE int
  USING cityid::int;

En guise de remarque ... peut-être qu'un jour PostgreSQL prononcera les noms des colonnes dans les messages d'erreur. jusque-là au moins, c'est plus bavard que SQL Server .

3
Evan Carroll

La racine du problème est INSERT sans liste de colonnes cible
- qui est un moyen populaire de se tirer une balle dans le pied. N'utilisez ce raccourci de syntaxe que si vous savez exactement ce que vous faites.

Le manuel sur INSERT:

Les noms des colonnes cibles peuvent être répertoriés dans n'importe quel ordre. Si aucune liste de noms de colonnes n'est donnée, la valeur par défaut est toutes les colonnes de la table dans leur ordre déclaré; ou les premiers [~ # ~] n [~ # ~] noms de colonne, s'il n'y a que [~ # ~] n [~ # ~] colonnes fournies par la clause VALUES ou requête. Les valeurs fournies par la clause ou la requête VALUES sont associées de gauche à droite à la liste de colonnes explicite ou implicite.

Le cure: liste explicitement les colonnes cibles.

INSERT INTO cities (cityname, state)  -- target columns!
VALUES ('San Francisco','CA');

Cela suppose que cityid peut être NULL ou avoir une colonne par défaut.

En règle générale, la table devrait ressemble à ceci:

CREATE TABLE city  -- personal advice: use singular terms for table names
   city_id  serial PRIMARY KEY
 , cityname text NOT NULL
 , state    text NOT NULL  -- REFERENCES state(state_id)
);

Idéalement, vous disposez également d'un tableau state répertoriant tous les états possibles et d'un FOREIGN KEY référence à celui-ci.

À propos de serial:

3
Erwin Brandstetter