7

Is there any way to convert varbinary to ASCII varchar string (base64, md5, sha1 - no matter) without master.dbo.fn_varbintohexstr function on MS SQL Server 2005? Because it can't be used inside of computed column.

CONVERT and CAST return non-ASCII strings.

Thank you,

Denis.

Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281
Denis
  • 3,653
  • 4
  • 30
  • 43

1 Answers1

4

For md5 and sha1 you can use hashbytes. To get base64 you can create a udf that does the conversion and use that in your computed column.

Function BinToBase64:

create function BinToBase64(@Bin varbinary(max)) returns varchar(max) as
begin
  return CAST(N'' AS XML).value('xs:base64Binary(xs:hexBinary(sql:variable("@Bin")))', 'VARCHAR(MAX)')
end

Function BinToHexString:

create function BinToHexString(@Bin varbinary(max)) returns varchar(max) as
begin
  return '0x' + cast('' as xml).value('xs:hexBinary(sql:variable("@Bin") )', 'varchar(max)'); 
end

Use like this:

create table TestTable 
(
  Col1 varbinary(max), 
  Col2 as dbo.BinToHexString(hashbytes('MD5', Col1)),
  Col3 as dbo.BinToHexString(hashbytes('SHA1', Col1)),
  Col4 as dbo.BinToBase64(Col1),
)
insert into TestTable values (12345)

select *
from TestTable

Unique constraint varbinary column using hashbytes and an uniqueidentifier column

create table TestTable 
(
  ID uniqueidentifier default(newid()),
  Col1 varbinary(max), 
  Col2 as coalesce(hashbytes('MD5', Col1), cast(ID as varbinary(8000))) persisted
)

create unique index IX_TestTable_Col2 on TestTable(Col2)
Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281
  • Your Col2 and Col3 contain 0x00 strings but when I tried to convert HashBytes output to varchar I received china hieroglyphs instead. Did I miss something? – Denis Jul 09 '11 at 20:59
  • @Denis - hashbytes returns a varbinary. Was not sure you wanted those as strings as well. Updated answer with a function to convert from varbinary to hex string. – Mikael Eriksson Jul 09 '11 at 21:12
  • Thank you! It works! But unfortunately it makes the column non-deterministic and can't be used inside of computed column as well. I'll try to find other architectural decision. – Denis Jul 09 '11 at 21:30
  • @Denis - Well, it can be used in a computed column. That is what I do in TestTable. It can not be a persisted computed column. – Mikael Eriksson Jul 09 '11 at 21:34
  • I'm trying to implement UNIQUE constraint for nullable column (that may contain NULL or unique value). I didn't find native method to do this. Only persisted computed column of hashes or UNIQUE index on single-column view. – Denis Jul 09 '11 at 21:47
  • @Denis - Ok. Then you could use hashbytes because that returns a varbinary(8000) and that can be a persisted computed column and used in a unique index. No need to convert to varchar. Added something I think should do the trick. – Mikael Eriksson Jul 09 '11 at 22:13
  • 2
    Final solution is: `isnull(CONVERT([uniqueidentifier],hashbytes('MD5',[Email]),(0)), CONVERT([uniqueidentifier],hashbytes('MD5',CONVERT([varchar](20),[Id],(0))),(0)))` – Denis Jul 10 '11 at 07:34