我有一个表,其中有一列包含 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
应该尽可能使用)在插入/更新/等操作中会引发一些错误警告,即使您通过检查函数调用的结果来防范它。
您可以在更新之前暂时禁用它:
set session sql_mode=replace(@@sql_mode, 'STRICT_TRANS_TABLES', '');
update ...
set session sql_mode=concat(@@sql_mode, ',STRICT_TRANS_TABLES');
但我更喜欢使用正则表达式(正如你所建议的)。