Encrypt password in insert statement in postgresql throws an error (Need to add explicit type cast)

寵の児 提交于 2020-01-04 05:50:07

问题


New to postgresql. It might be very simple; but am not getting it.

I've this in mysql:

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

After referring postgresql documentations on password encryption/hashing and various similar questions on Stackoverflow;

I tried it's equivalent in postgresql as:

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

But; it throws me an error at function gen_salt():

No function matches the given name and argument types. You might need to add explicit type casts.

(The datatype of column(field) password is character varying.)

I read various manuals on type casting in postgresql and tried casting the function.

But; no use. I came across various similar errors.

Can I know what exactly am missing? or what is the exact way of type casting? Or do I need to add chkpass module (extension) for this?

I already have pgcrypto extension and am using postgresql 9.6.


回答1:


It is not the answer actually but a brief explanation how to find the source of the error.

First of all lets find the pgcrypto extension:

select e.extname, n.nspname
from pg_catalog.pg_extension e left join pg_catalog.pg_namespace n on n.oid = e.extnamespace;

It should return something like:

╔════════════════════╤════════════╗
║      extname       │  nspname   ║
╠════════════════════╪════════════╣
║ plpgsql            │ pg_catalog ║
║ adminpack          │ pg_catalog ║
║ plpythonu          │ pg_catalog ║
║ pg_stat_statements │ public     ║
║ plpython3u         │ pg_catalog ║
║ hstore             │ public     ║
║ uuid-ossp          │ public     ║
║ pg_trgm            │ public     ║
║ ltree              │ public     ║
║ tablefunc          │ public     ║
║ unaccent           │ public     ║
║ pgcrypto           │ nd         ║
╚════════════════════╧════════════╝

So the pgcrypto installed in the schema nd in the my database.

Next lets look to the search_path parameter which provide the information where to search DB objects:

show search_path;
╔═════════════════╗
║   search_path   ║
╠═════════════════╣
║ "$user", public ║
╚═════════════════╝

It means that the objects will be searched in the schema with name of the current user and, if nothing found, in the schema public.

Finally lets check the current user:

select current_user;
╔══════════════╗
║ current_user ║
╠══════════════╣
║ postgres     ║
╚══════════════╝

So as you can see the extension installed in the schema nd can not be found using the search_path which actually is postgres, public and we got the error:

select gen_salt('md5');
ERROR:  function gen_salt(unknown) does not exist
LINE 1: select gen_salt('md5');
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

There are several ways how to fix it depending of the actual values for your DB mentioned above.

You can move the extension to another schema like:

alter extension pgcrypto set schema public;

You can change the search_path option like:

set search_path to '"$user", public'; -- for the active session only
alter database your_db_name set search_path to '"$user", public'; -- permanently for the database

Finally you could to explicitly specify the schema in the SQL statement:

select schema_where_it_installed.gen_salt('md5');
-- For my example:
select nd.gen_salt('md5');


来源:https://stackoverflow.com/questions/40255677/encrypt-password-in-insert-statement-in-postgresql-throws-an-error-need-to-add

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!