練習用に小さな開発データベースを作成しました。列cities
とcityname
を持つテーブルstate
があります。そこのcityname
には、「シンシナティ」という長い名前がありますね。
mytestdb=# SELECT * FROM cities;
cityid | cityname | state
--------+------------+-------
12345 | Cincinnati | Ohio
(1 row)
「サンフランシスコ」を追加しようとしたときにこのエラーメッセージが表示される方法と理由については不明です。
mytestdb=# INSERT INTO cities VALUES ('San Francisco','CA'); ERROR: value too long for type character varying(5)
まず、違いは何ですか。
_SELECT x, length(x)
FROM ( VALUES
('Cincinnati'),
('San Francisco')
) AS t(x);
_
これが出力です
_ x | length
---------------+--------
Cincinnati | 10
San Francisco | 13
_
そう..
さらに、Cincinnati
がvarchar(5)
内にあった場合、切り捨てられる必要があります。
したがって、問題はあなたのcityid
です。 varchar(5)
です。とにかく、それをint
にしたいでしょう-よりコンパクトで高速になります。したがって、ALTER
テーブルを修正します。
_ALTER TABLE cities
ALTER COLUMN cityid SET DATA TYPE int
USING cityid::int;
_
余談ですが... いつかPostgreSQLはエラーメッセージで列名を話すでしょう それまで 少なくともそれはSQL Serverよりも詳細 。
問題の根源はINSERT
ターゲット列リストなし
-これは、自分を足で撃つための一般的な方法です。この構文のショートカットは、正確に何をしているのかを知っている場合にのみ使用してください。
ターゲット列名は任意の順序でリストできます。列名のリストがまったく指定されていない場合、デフォルトは宣言された順序でのテーブルのすべての列です。または、最初の[〜#〜] n [〜#〜]列名(ある場合)
VALUES
句またはquery。VALUES
句またはクエリによって提供される値は、明示的または暗黙的な列リストに左から右に関連付けられます。
cure:ターゲット列を明示的にリストします。
INSERT INTO cities (cityname, state) -- target columns!
VALUES ('San Francisco','CA');
これは、cityid
がNULLであるか、列のデフォルトがあることを前提としています。
通常、テーブルは次のようになります。
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)
);
理想的には、すべての可能な状態をリストするテーブルstate
と FOREIGN KEY
それへの参照。
serial
について: