【问题标题】:Cast binary column to string in Azure SQL Data Warehouse在 Azure SQL 数据仓库中将二进制列转换为字符串
【发布时间】:2018-04-24 20:14:12
【问题描述】:

我目前在 Postgres 和 Redshift 中有函数,它们采用随机生成的字符串,对其进行哈希处理,然后使用部分哈希生成 0-99 之间的随机数。我正在尝试在 Azure SQL 数据仓库中复制此功能,以便在 SQL DW 中获得与在 Postgres 和 Redshift 中相同的值。

我遇到的问题是,当我将结果转换为 VARCHAR 或使用字符串函数时,结果是一个非常不同的字符串。我想将 md5 函数的结果作为相同的VARCHAR

为了说明,这里是 Azure SQL DW 中的一个查询:

SELECT
  'abc123' as random_string,
  HASHBYTES('md5', 'abc123') as md5,
  CAST(HASHBYTES('md5', 'abc123') AS VARCHAR) as md5_varchar,
  RIGHT(HASHBYTES('md5', 'abc123'), 5) as md5_right
;

这会产生

random_string,md5,md5_varchar
abc123,0xE99A18C428CB38D5F260853678922E03,éšÄ(Ë8Õò`…6x’.,6x’.

如您所见,生成的 varchar 与 md5 函数的输出有很大不同。有没有办法将md5的结果转换成相同的字符串?

在 Postgres 和 Redshift 中,md5 函数的结果是一个 VARCHAR,因此对其进行转换很简单。

以下是 Redshift 和 Postgres 中的查询:

-- Redshift
SELECT
  'abc123' as random_string,
  right(strtol(right(md5('abc123'), 3), 16), 2)::INT as tranche
;

-- Postgres
SELECT
  'abc123' as random_string,
  right(('x' || lpad(right(md5('abc123'), 3), 4, '0')) :: BIT(16) :: INT :: VARCHAR, 2) :: INT AS tranche
;

两个函数都返回值87

【问题讨论】:

    标签: sql sql-server azure-sql-database azure-sqldw sql-data-warehouse


    【解决方案1】:

    使用 convert 应该可以解决这个问题:

    CONVERT(VARCHAR(32),HashBytes('MD5', 'abc123'),2)

    这是因为您可以为我们转换 varbinary 值时需要的样式定义参数。这里描述: https://technet.microsoft.com/pl-pl/library/ms187928(v=sql.105).aspx

    这是该文档中关于使用 convert 进行二进制转换的备注部分:

    二进制样式当表达式为 binary(n)、varbinary(n)、char(n) 或 varchar(n), style 可以是下面显示的值之一 桌子。表中未列出的样式值会返回错误。

    0(默认)

    将 ASCII 字符转换为二进制字节或二进制 字节到 ASCII 字符。每个字符或字节都按 1:1 转换。如果 data_type 是二进制类型,字符 0x 被添加到 结果的左侧。

    1, 2

    如果 data_type 是二进制类型,则 表达式必须是字符表达式。表达式必须是 由偶数个十六进制数字(0、1、2、3、4、5、6、 7、8、9、A、B、C、D、E、F、a、b、c、d、e、f)。如果样式设置为 1 字符 0x 必须是表达式中的前两个字符。 如果表达式包含奇数个字符或任何一个 字符无效会引发错误。如果长度 转换后的表达式大于 data_type 的长度 结果将被截断。固定长度的 data_types 是 更大,则转换后的结果将在右侧添加零 结果。如果 data_type 是字符类型,则表达式必须 是一个二进制表达式。每个二进制字符转换为两个 十六进制字符。如果转换后的表达式的长度是 大于 data_type 长度,它将被截断。如果 data_type 是固定大小的字符类型, 转换后的结果小于其 data_type 的长度;空间是 添加到转换后的表达式的右侧以保持偶数 十六进制位数。字符 0x 将被添加到 样式 1 的转换结果左侧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 2014-11-07
      • 2021-02-24
      • 2015-12-15
      相关资源
      最近更新 更多