postgresql中插入语句中的加密密码抛出错误(需要添加显式类型转换)

Cha*_*rvi 2 mysql encryption postgresql casting password-encryption

刚接触 postgresql。这可能很简单;但我不明白。

我在 mysql 中有这个:

insert into APP_USERS VALUES
(1, 'admin', 'adminemailid','', 'System', 'Administrator', 'SysAdmin', 'CompanyName',
sha('password123'), 'ADMIN', 2,'SCREEN',0);
Run Code Online (Sandbox Code Playgroud)

在参考了有关密码加密/散列的 postgresql 文档以及 Stackoverflow 上的各种类似问题之后;

我尝试过在 postgresql 中相当于:

insert into APP_USERS VALUES
(1, 'admin', 'adminemailid','', 'System', 'Administrator', 'SysAdmin', 'CompanyName',
crypt('password123',gen_salt('sha1')), 'ADMIN', 2,'SCREEN',0)
Run Code Online (Sandbox Code Playgroud)

但; 它在函数中向我抛出一个错误gen_salt()

没有函数与给定名称和参数类型匹配。您可能需要添加显式类型转换。

(列(字段)密码的数据类型是字符变化的。)

我阅读了有关 postgresql 中类型转换的各种手册,并尝试转换该函数。

但; 没有用。我遇到过各种类似的错误。

我能知道到底缺少什么吗?或者类型转换的确切方式是什么?或者我是否需要为此添加 chkpass 模块(扩展)?

我已经有了 pgcrypto 扩展并且正在使用 postgresql 9.6。

Abe*_*sto 5

它实际上并不是答案,而是如何找到错误根源的简要说明。

\n\n

首先让我们找到pgcrypto扩展名:

\n\n
select e.extname, n.nspname\nfrom pg_catalog.pg_extension e left join pg_catalog.pg_namespace n on n.oid = e.extnamespace;\n
Run Code Online (Sandbox Code Playgroud)\n\n

它应该返回类似以下内容:

\n\n
\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa4\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91      extname       \xe2\x94\x82  nspname   \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 plpgsql            \xe2\x94\x82 pg_catalog \xe2\x95\x91\n\xe2\x95\x91 adminpack          \xe2\x94\x82 pg_catalog \xe2\x95\x91\n\xe2\x95\x91 plpythonu          \xe2\x94\x82 pg_catalog \xe2\x95\x91\n\xe2\x95\x91 pg_stat_statements \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 plpython3u         \xe2\x94\x82 pg_catalog \xe2\x95\x91\n\xe2\x95\x91 hstore             \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 uuid-ossp          \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 pg_trgm            \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 ltree              \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 tablefunc          \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 unaccent           \xe2\x94\x82 public     \xe2\x95\x91\n\xe2\x95\x91 pgcrypto           \xe2\x94\x82 nd         \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa7\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此安装在我的数据库中的pgcrypto架构中。nd

\n\n

接下来让我们看看search_path提供在何处搜索数据库对象的信息的参数:

\n\n
show search_path;\n\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91   search_path   \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 "$user", public \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着将在具有当前用户名称的 schema 中搜索对象,如果没有找到,则在 schema 中搜索对象public

\n\n

最后让我们检查当前用户:

\n\n
select current_user;\n\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 current_user \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 postgres     \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,使用实际上nd无法找到架构中安装的扩展,我们收到了错误:search_pathpostgres, public

\n\n
select gen_salt(\'md5\');\nERROR:  function gen_salt(unknown) does not exist\nLINE 1: select gen_salt(\'md5\');\n               ^\nHINT:  No function matches the given name and argument types. You might need to add explicit type casts.\n
Run Code Online (Sandbox Code Playgroud)\n\n

有多种方法可以根据上述数据库的实际值来修复它。

\n\n

您可以将扩展移动到另一个架构,例如:

\n\n
alter extension pgcrypto set schema public;\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以更改该search_path选项,例如:

\n\n
set search_path to \'"$user", public\'; -- for the active session only\nalter database your_db_name set search_path to \'"$user", public\'; -- permanently for the database\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,您可以在 SQL 语句中显式指定模式:

\n\n
select schema_where_it_installed.gen_salt(\'md5\');\n-- For my example:\nselect nd.gen_salt(\'md5\');\n
Run Code Online (Sandbox Code Playgroud)\n