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)
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..
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 .
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.
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êteVALUES
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
: