2016-05-20 8 views
0

私は、PostgreSQLに新しいです、と私はInteger to Varchar(20)から列のデータ型を変更しようとしているのデータ型を変更することができませんでしたが、私は奇妙なエラーが出る:Postgresqlの列

ERROR: operator does not exist: character varying <> integer : 
     No operator matches the given name and argument type(s). 
    You might need to add explicit type casts.********** Error ********** 

スクリプトIをテーブルを作成するために書いている:

CREATE TABLE LOGIN(
USERNAME INTEGER NOT NULL CHECK(USERNAME != NULL), 
PASSWORD VARCHAR(10) NOT NULL CHECK(PASSWORD <>'' AND USERNAME != NULL) 
); 

これは私がVARCHARに整数から列を変更するために使用するスクリプトです:

ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20); 

私は助けていただきありがとうございます。ありがとう。

+0

です。テーブルが空であるか、データがありますか? – jarlh

+1

NOT NULLはこのトリックを行います.Null以外の別の試行を追加する必要はありません。 – jarlh

答えて

0

エラーの原因は、あなたが持っている役に立たない追加のチェック制約(<> null)です:

operator does not exist: character varying <> integer :

はあなたのチェック制約の両方に条件USERNAME != NULLを指します。

(SQLで「等しくない」演算子は<>あると!=は、その中に再書き込まれます)

あなたが最初のものをチェック制約を取り除く必要があります。デフォルトでは、チェックがlogin_username_checkになるの名前を生成するので、以下ではおそらく動作します:

alter table login 
    drop constraint login_username_check; 

他のチェックは、おそらくlogin_checkです:

alter table login 
    drop constraint login_check; 

これらのチェック制約が削除されたら、あなたが変更することができますデータの種類:

ALTER TABLE LOGIN 
    ALTER COLUMN USERNAME set data TYPE varchar(20); 

は今、あなたはパスワードの制約を再度追加する必要があります。

alter table login 
    add constraint check_password check (password <> ''); 

生成された制約名が、その後私が想定しているものと異なっているいくつかの理由で、あなたが使用して名前を見つけることができる場合:jarlhはすでにNOT NULLとして列を定義し、コメントしたように

select c.conname, c.consrc 
from pg_constraint c 
    join pg_class t on c.conrelid = t.oid 
    join pg_namespace n on t.relnamespace = n.oid 
where t.relname = 'login' 
    and n.nspname = 'public'; --<< change here for the correct schema name 

を十分です。別の "not null"チェックを追加する必要はありません。プラス:とにかくチェックが間違っています。 nullの値を=または<>を使用して比較することはできません。 nullでない値をテストするには、IS NOT NULLを使用する必要があります。明示的なチェック制約を書く正しい方法は、

username check (username is not null) 
1

USING expressionを使用してください。それはあなたが値変換を定義することができます:PostgreSQL documentationから

ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20) USING ...expression...; 

The optional USING clause specifies how to compute the new column value from the old; if omitted, the default conversion is the same as an assignment cast from old data type to new. A USING clause must be provided if there is no implicit or assignment cast from old to new type.

+0

(無駄な)チェック制約 'USERNAME!= NULL'のために動作しません。エラーメッセージは、その中に '<> '演算子があるため、実際にはその制約を指しています。 –

0

問題がUSERNAMEのCHECK制約です。 「(ユーザー名<> NULL ::整数)」フィールド「consrc」あなたは制約が実際のように見えることに気づくかもしれでは

SELECT conname, consrc 
    FROM pg_constraint 
WHERE conrelid = 
    (SELECT oid 
     FROM pg_class 
     WHERE relname LIKE 'login'); 

、およびそれ:あなたはそのように何とかカタログpg_constraintを使用して、それから抜け出す道を得ることができます列の型を整数からvarcharに変更しようとするとエラーが発生します。制約を削除するには

は 'login_username_check' と 'login_checkは' あなたが上記のクエリから得たconnames(注意が必要と名称ことをdoublecheck)です

ALTER TABLE LOGIN DROP CONSTRAINT login_username_check; 
ALTER TABLE LOGIN DROP CONSTRAINT login_check; 

を使用しています。

その後は、あなたのテーブルには、そこにデータがない場合は動作するはずです

ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20); 

これに試してみてください。そうでない場合、あなたはおそらく「」チェック> PASSWORD <を復元したいたより

ALTER TABLE dev.tests_LOGIN ALTER COLUMN USERNAME TYPE varchar(20) USING USERNAME::VARCHAR; 

を追加するので、あなたはそれを戻すために1以上のALTERを行う必要があるでしょう。がんばろう!

pg_constraint doc

alter doc

PS:あなたは便利かもしれません

一部PostgreSQLのドキュメントときすでに前述したように、あなたは制約(!= NULL)を取得する必要はありませんが確認してください列の説明にNULLがありません。また、NULLチェックは少し異なります。クイックイラスト:

SELECT (NULL = NULL); 
SELECT (NULL != NULL); 
SELECT (NULL IS NULL); 
SELECT (NULL IS NOT NULL);