【问题标题】:SHA256 function behavior in PostgresPostgres 中的 SHA256 函数行为
【发布时间】:2021-04-23 09:58:18
【问题描述】:

当我在 Postgres 中调用 sha256('abc') 函数时,它会将传递值的散列返回为 bytea 作为该函数的结果。

SELECT sha256('abc'); -- Works as expected

但是,当我有一个自定义函数接受 text 作为输入参数并在该函数中执行完全相同的操作时:

CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS bytea
LANGUAGE plpgsql
AS
$$
DECLARE
  res bytea;
BEGIN
  SELECT sha256(input) INTO res;
  RETURN res;
END
$$

-- Executing the function above
SELECT hash_text('abc');

我收到以下异常:

SQL 错误 [42883]: 错误: 函数 sha256(text) 不存在 提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。 其中:PL/pgSQL 函数 hash_text(text) 第 5 行的 SQL 语句

我查看了官方docs,似乎sha256 正在接受bytea 作为输入参数。让我感到困惑的是,当我直接传递 'abc' 值时它有效,但当该值通过函数参数时它不起作用?让我感到困惑的第二件事是,为什么当我在该函数中转换 input::bytea 时会产生不同的结果?我在这里错过了什么?

我对 Postgres 有点陌生,所以我可能会遗漏一些明显的东西。

【问题讨论】:

    标签: postgresql sha256


    【解决方案1】:

    让我感到困惑的是,当我直接传递 'abc' 值时它可以工作,但当该值通过函数参数时它不起作用?

    文字'abc' 的类型未知。因此,它着眼于如何使用它来确定它到底是什么类型。因为它知道 sha256 接受 bytea 作为输入,所以它将'abc' 视为 bytea 类型。

    就您的函数而言,它不是未知类型。它被明确声明为文本类型。它不会将文本隐式转换为 bytea。

    让我困惑的第二件事是为什么当我在该函数中转换 input::bytea 时会产生不同的结果?

    它会产生什么不同的结果?在我的手中,你的显式转换函数给出的答案与直接调用时 sha256 的答案相同。

    【讨论】:

    • 感谢您的解释。当sha256 决定'abc' 的类型时,sha256 一直返回结果为bytea(正如您从问题中的屏幕截图中看到的那样),而当我从我将文本显式转换为bytea 的函数。我必须手动将文本转换为bytea(因为这是我想要和期望的行为,因为它在功能之外以这种方式工作),我自己对这个问题的回答显示了我是如何做到的。
    【解决方案2】:

    你需要输入类型转换

    CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS text
    LANGUAGE plpgsql
    AS
    $$
    DECLARE
      res text;
    BEGIN
      SELECT encode(sha256(input::bytea),  'escape') INTO res;
      RETURN res;
    END
    $$
    
    -- Executing the function above
    
    SELECT hash_text('abc');
    
    |哈希文本 | | :------------------------------------------------ ------------------------------ | | \272x\277\217\317\352AA@\336]\256"#\260a\243\226z\234\264\377a\362\000\255 |
    SELECT encode(sha256('abc'),  'escape')
    
    |编码 | | :------------------------------------------------ ------------------------------ | | \272x\277\217\317\352AA@\336]\256"#\260a\243\226z\234\264\377a\362\000\255 |

    db小提琴here

    【讨论】:

    • 是的,我试过了,但在调用 sha256('abc') 直接返回字节数组时,它似乎将值作为十六进制字符串返回。如何通过该函数实现使用硬编码文本值调用 sha256 的相同行为?我也对它为什么表现不同感兴趣?
    • 它给了 bach 相同的结果,dbfiddle.uk/… 你想要什么结果?
    • 这很有趣,我在我的机器上的 DBeaver 上运行同样的 sha256 函数,它返回 bytea
    • 我在我的机器上添加了该函数结果的屏幕截图,我希望通过该函数实现相同的行为。
    • 您可以像在更改答案中一样转换它
    【解决方案3】:

    我不确定是否有更简单的方法,但这种格式将其转换为我想看到的bytea 结果。感谢@nbk 引导我找到这个解决方案。

    CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS bytea
    LANGUAGE plpgsql
    AS
    $$
    DECLARE
      res bytea;
    BEGIN
      SELECT encode(sha256(input::bytea), 'escape')::bytea INTO res;
      RETURN res;
    END
    $$
    

    【讨论】:

      猜你喜欢
      • 2018-06-17
      • 1970-01-01
      • 2021-09-02
      • 2011-07-17
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多