web-dev-qa-db-ja.com

この値をタイプ文字のVariation(5)に対して長すぎるように修正するにはどうすればよいですか?

練習用に小さな開発データベースを作成しました。列citiescitynameを持つテーブル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)
7
Daniel

まず、違いは何ですか。

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

これが出力です

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

そう..

  1. サンフランシスコは3文字長くなります。
  2. どちらも5文字以上です。
  3. それは問題にはなりません。

さらに、Cincinnativarchar(5)内にあった場合、切り捨てられる必要があります。

したがって、問題はあなたのcityidです。 varchar(5)です。とにかく、それをintにしたいでしょう-よりコンパクトで高速になります。したがって、ALTERテーブルを修正します。

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

余談ですが... いつかPostgreSQLはエラーメッセージで列名を話すでしょう それまで 少なくともそれはSQL Serverよりも詳細

3
Evan Carroll

問題の根源INSERTターゲット列リストなし
-これは、自分を足で撃つための一般的な方法です。この構文のショートカットは、正確に何をしているのかを知っている場合にのみ使用してください。

INSERT:のマニュアル

ターゲット列名は任意の順序でリストできます。列名のリストがまったく指定されていない場合、デフォルトは宣言された順序でのテーブルのすべての列です。または、最初の[〜#〜] n [〜#〜]列名(ある場合) VALUES句またはqueryVALUES句またはクエリによって提供される値は、明示的または暗黙的な列リストに左から右に関連付けられます。

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)
);

理想的には、すべての可能な状態をリストするテーブルstateFOREIGN KEY それへの参照。

serialについて:

3