在 MariaDB / MySQL 中将未经消毒的 varchar 从 Base64 转换为 Hex 的适当方法

问题描述 投票:0回答:1

我有一个表,其中有一列包含 varchar。 该列中的值应该是 Base64 编码的,但是我想将它们保存为十六进制。

列中包含的值有可能根本不是 Base64 编码的,但我也知道如果它们是 Base64 编码的,它们的长度将是 12 个字符。

根据 MariaDB 文档,如果要转换的 varchar 为 null 或无效的 Base64,FROM_BASE64 将返回 null。

知道我写了以下 SELECT 语句

SELECT column_name,
HEX(FROM_BASE64(column_name)) AS column_name_converted
FROM table_name tn 
WHERE CHAR_LENGTH(column_name) = 12 AND FROM_BASE64(column_name) IS NOT NULL

此 SELECT 按预期工作。

但是,当我尝试编写 UPDATE 语句时,收到错误“位置 8 处的 base64 数据错误” - 在本例中,位置 8 是 varchar 中的“#”,这不是有效的符号。

我想要实现的结果:仅将有效的 Base64 和 12 个字符长的值转换为十六进制。

例如:

UPDATE table_name
SET column_name =
    CASE
        WHEN FROM_BASE64(column_name) IS NOT NULL
        THEN HEX(FROM_BASE64(column_name))
        ELSE column_name
    END
WHERE CHARACTER_LENGTH(column_name) = 12 
UPDATE table_name 
SET column_name  =
HEX(FROM_BASE64(column_name))
WHERE CHAR_LENGTH(column_name) = 12 AND FROM_BASE64(column_name) IS NOT NULL

这些都不起作用。尽管 SELECT 工作完美,但 SQL 执行会因上述错误而中止。

无法在执行前清理数据。

-----潜在的解决方案-----

编辑: 似乎我设法通过使用正则表达式过滤无效结果来使其工作。有没有更干净的方法可以达到相同的结果?

UPDATE table_name
SET column_name =
    CASE
        WHEN column_name REGEXP '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$'
        THEN HEX(FROM_BASE64(column_name))
        ELSE column_name
    END
WHERE CHARACTER_LENGTH(column_name) = 12
sql mysql select mariadb sql-update
1个回答
0
投票
不幸的是,STRICT_TRANS_TABLES sql_mode(

应该尽可能使用)在插入/更新/等操作中会引发一些错误警告,即使您通过检查函数调用的结果来防范它。

您可以在更新之前暂时禁用它:

set session sql_mode=replace(@@sql_mode, 'STRICT_TRANS_TABLES', ''); update ... set session sql_mode=concat(@@sql_mode, ',STRICT_TRANS_TABLES');
但我更喜欢使用正则表达式(正如你所建议的)。

© www.soinside.com 2019 - 2024. All rights reserved.