我是Postgresql的新手,我正在尝试从Integer to Varchar(20)
更改列的数据类型,但我得到了一个奇怪的错误:
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 **********
我写的用于创建表的脚本是:
CREATE TABLE LOGIN(
USERNAME INTEGER NOT NULL CHECK(USERNAME != NULL),
PASSWORD VARCHAR(10) NOT NULL CHECK(PASSWORD <>'' AND USERNAME != NULL)
);
这是我用来修改从Integer到Varchar的列的脚本:
ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20);
我感谢任何帮助。感谢。
答案 0 :(得分:2)
使用USING expression
。它允许您定义值转换:
ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20) USING ...expression...;
可选的USING子句指定如何计算新列 来自旧的价值;如果省略,则默认转换与 从旧数据类型转换为new的赋值。 USING子句必须是 如果没有从旧到新的隐式或赋值转换,则提供 类型。
答案 1 :(得分:0)
问题出在USERNAME的CHECK约束中。您可以使用目录pg_constraint以某种方式找到解决方法:
SELECT conname, consrc
FROM pg_constraint
WHERE conrelid =
(SELECT oid
FROM pg_class
WHERE relname LIKE 'login');
在字段'consrc'中,您可能会注意到约束实际上看起来像“(用户名&lt;&gt; NULL :: integer)”,并且当您尝试将列类型从整数更改为varchar时会出现错误。
要删除约束,请使用
ALTER TABLE LOGIN DROP CONSTRAINT login_username_check;
ALTER TABLE LOGIN DROP CONSTRAINT login_check;
其中'login_username_check'和'login_check'是您从上面的查询得到的同名(小心并仔细检查这些名称)。
之后你应该尝试
ALTER TABLE LOGIN ALTER COLUMN USERNAME TYPE varchar(20);
如果您的表中没有数据,这应该有效。如果没有,请添加
ALTER TABLE dev.tests_LOGIN ALTER COLUMN USERNAME TYPE varchar(20) USING USERNAME::VARCHAR;
您可能想要恢复PASSWORD&lt;&gt;''检查,因此您必须再做一次更改才能恢复它。祝你好运!
您可能会发现一些方便的PostgreSQL文档:
PS:如上所述,当列描述中已经有NOT NULL时,您不需要检查约束(!= NULL)。此外,NULL检查有点不同。快速说明:
SELECT (NULL = NULL);
SELECT (NULL != NULL);
SELECT (NULL IS NULL);
SELECT (NULL IS NOT NULL);
答案 2 :(得分:0)
错误的原因是您拥有无用的额外检查约束(<> null
):
运算符不存在:字符变化&lt;&gt;整数:
指的是两个检查约束中的条件USERNAME != NULL
。
(SQL中的&#34; not equals&#34;运算符为<>
,并且!=
被重写为){/ p>
所以你首先需要摆脱那些检查约束。该检查的默认生成名称为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 <> '');
如果由于某种原因生成的约束名称与我假设的约束名称不同,您可以使用以下命令找到名称:
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
正如jarlh已经评论过的那样,将列定义为NOT NULL
就足够了。没有必要添加另一个&#34; not null&#34;校验。另外:检查错了。您无法使用null
或=
将值与<>
进行比较。要测试非空值,您需要使用IS NOT NULL
。编写显式检查约束的正确方法是
username check (username is not null)