bri*_*ray 7 sql postgresql md5 plpgsql
我想创建一个sql查询(或plpgsql),md5()所有给定的行,无论类型如何.但是,在下面,如果一个为null,则哈希值为null:
UPDATE thetable
SET hash = md5(accountid || accounttype || createdby || editedby);
Run Code Online (Sandbox Code Playgroud)
我稍后使用哈希比较唯一性,因此空哈希不适用于此用例.
问题是它处理连接空值的方式.例如:
thedatabase=# SELECT accountid || accounttype || createdby || editedby
FROM thetable LIMIT 5;
1Type113225
<NULL>
2Type11751222
3Type10651010
4Type10651
Run Code Online (Sandbox Code Playgroud)
如果我知道类型,我可以使用coalesce或CASE语句; 但是,我有很多表,我不会提前知道每一列的类型.
mvp*_*mvp 29
对此有更优雅的解决方案.
在Postgres中,SELECT
允许使用表名,并且它具有类型ROW
.如果将其强制转换为type TEXT
,它会将所有列连接在一起,实际上是JSON的字符串.
有了这个,您可以获得md5
如下所有列:
SELECT md5(mytable::TEXT)
FROM mytable
Run Code Online (Sandbox Code Playgroud)
如果您只想使用某些列,请使用ROW
构造函数并将其强制转换为TEXT
:
SELECT md5(ROW(col1, col2, col3)::TEXT)
FROM mytable
Run Code Online (Sandbox Code Playgroud)
关于这个解决方案的另一个不错的特性是对于空字符串md5
将是不同的NULL
.
强制性的SQLFiddle.
小智 5
您还可以使用类似于 mvp 解决方案的其他方法。而不是使用 Amazon Redshift 不支持的 ROW() 函数......
无效操作:目标列表中不支持隐式或显式的 ROW 表达式;
我的提议是使用 NVL2 和 CAST 函数将不同类型的列转换为 CHAR,只要根据文档,这种类型与所有 Redshift 数据类型兼容。下面是如何在 Redshift 中实现空证明MD5的示例。
SELECT md5(NVL2(col1,col1::char,''),
NVL2(col2,col2::char,''),
NVL2(col3,col3::char,''))
FROM mytable
Run Code Online (Sandbox Code Playgroud)
这可能会在不将第二个 NVL2 函数参数转换为 char 的情况下工作,但如果您尝试从具有空值的日期列中获取 md5,它肯定会失败。我希望这对某人有帮助。