md5()适用于文字,但不适用于列数据

Jer*_*nch 6 postgresql md5

在测试PostgreSQL的md5()功能时,我注意到了非常奇怪的行为:

按预期工作

SELECT md5('abc')
--"900150983cd24fb0d6963f7d28e17f72"
Run Code Online (Sandbox Code Playgroud)

但是在查询中使用md5()函数:

SELECT request_id, md5(request_id)
FROM Request
ORDER BY request_id
Run Code Online (Sandbox Code Playgroud)

导致此错误:

ERROR:  function md5(integer) does not exist
LINE 1: SELECT request_id, md5(request_id)
                           ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

********** Error **********

ERROR: function md5(integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 20
Run Code Online (Sandbox Code Playgroud)

如果它在第一个查询中有效,那么该函数怎么存在?我究竟做错了什么; md5()在SELECT查询中使用的正确方法是什么?

Clo*_*eto 11

该函数需要text作为参数.施展它:

SELECT request_id, md5(request_id::text)
FROM Request
ORDER BY request_id
Run Code Online (Sandbox Code Playgroud)

名为md5的函数接受整数参数不存在,但您可以创建它:

create function md5(integer)
returns text as $$

select md5($1::text);

$$ language sql immutable;
Run Code Online (Sandbox Code Playgroud)

那么md5将有3个签名:

=> \df md5
                          List of functions
   Schema   | Name | Result data type | Argument data types |  Type  
------------+------+------------------+---------------------+--------
 pg_catalog | md5  | text             | bytea               | normal
 pg_catalog | md5  | text             | text                | normal
 public     | md5  | text             | integer             | normal
Run Code Online (Sandbox Code Playgroud)

正如对此答案的评论中所指出的,整数文本表示的md5哈希可能不是您想要的.要使用二进制的哈希,bytea应使用接受参数的md5签名:

select md5(('\x' || right('0000000' || to_hex(200), 8))::bytea);
               md5                
----------------------------------
 b7b436d004c1cc0501bee9e296d2eaa4
Run Code Online (Sandbox Code Playgroud)

并替换以前创建的函数:

create or replace function md5(integer)
returns text as $$

select md5(('\x' || right('0000000' || to_hex($1), 8))::bytea);

$$ language sql immutable;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,将整数转换为文本意味着您将获取整数*的*文本表示的md5.在与其他系统通信时,这可能不是您想要的.如果你真的想要获取整数二进制表示的md5,你需要使用pl/perl,pl/python等过程语言来获取相应二进制表示的md5(带符号的32位小端,用于例). (2认同)