SQL 2008r2 Hex 2 ascii issue - sql

I have an issue converting the following hex string to ascii in tsql:
'd520088000000000000000004000000200000000000003770001c7cc5353482d322e302d4f70656e5353485f352e3570312044656269616e2d347562756e7475340d0a0000034c0614403d6544c243e7535320dc7ab5c3c8de0000007e6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d7368613235362c6469666669652d68656c6c6d616e2d67726f75702d65786368616e67652d736861312c6469666669652d68656c6c6d616e2d67726f757031342d736861312c6469666669652d68656c6c6d616e2d67726f7570312d73686131000000497373682d7273612d636572742d763030406f70656e7373682e636f6d2c7373682d6473732d636572742d763030406f70656e7373682e636f6d2c7373682d7273612c7373682d6473730000009d6165733132382d6374722c6165733139322d6374722c6165733235362d6374722c617263666f75723235362c617263666f75723132382c6165733132382d6362632c336465732d6362632c626c6f77666973682d6362632c636173743132382d6362632c6165733139322d6362632c6165733235362d6362632c617263666f75722c72696a6e6461656c2d636263406c797361746f722e6c69752e73650000009d6165733132382d6374722c6165733139322d6374722c6165733235362d6374722c617263666f75723235362c617263666f75723132382c6165733132382d6362632c336465732d6362632c626c6f77666973682d6362632c636173743132382d6362632c6165733139322d6362632c6165733235362d6362632c617263666f75722c72696a6e6461656c2d636263406c797361746f722e6c69752e736500000069686d61632d6d64352c686d61632d736861312c756d61632d3634406f70656e7373682e636f6d2c686d61632d726970656d643136302c686d61632d726970656d64313630406f70656e7373682e636f6d2c686d61632d736861312d39362c686d61632d6d64352d393600000069686d61632d6d64352c686d61632d736861312c756d61632d3634406f70656e7373682e636f6d2c686d61632d726970656d643136302c686d61632d726970656d64313630406f70656e7373682e636f6d2c686d61632d736861312d39362c686d61632d6d64352d39360000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000001a6e6f6e652c7a6c6962406f70656e7373682e636f6d2c7a6c69620000000000000000000000000000000000000000'
It should convert to
'? ??????????#??????????w????SSH-2.0-OpenSSH_5.5p1
Debian-4ubuntu4?????L??#=eD?C?SS
?z???????~diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1???Issh-rsa-cert-v00#openssh.com,ssh-dss-cert-v00#openssh.com,ssh-rsa,ssh-dss????aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc#lysator.liu.se????aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc#lysator.liu.se???ihmac-md5,hmac-sha1,umac-64#openssh.com,hmac-ripemd160,hmac-ripemd160#openssh.com,hmac-sha1-96,hmac-md5-96???ihmac-md5,hmac-sha1,umac-64#openssh.com,hmac-ripemd160,hmac-ripemd160#openssh.com,hmac-sha1-96,hmac-md5-96????none,zlib#openssh.com,zlib????none,zlib#openssh.com,zlib????????????????????'
Any ideas? I tried using cast and convert but no success.
Any help is much appreciated.
I am using the below function no outside code - tables are populated by an external application
*
declare #hexstring VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
begin
declare #char1 char(1), #char2 char(1), #strlen int, #currpos int, #result varchar(8000)
set #strlen=len(#hexstring)
set #currpos=1
set #result=''
while #currpos<#strlen
begin
set #char1=substring(#hexstring,#currpos,1)
set #char2=substring(#hexstring,#currpos+1,1)
if (#char1 between '0' and '9' or #char1 between 'A' and 'F')
and (#char2 between '0' and '9' or #char2 between 'A' and 'F')
set #result=#result+
char((ascii(#char1)-case when #char1 between '0' and '9' then 48 else 55 end)*16+
ascii(#char2)-case when #char2 between '0' and '9' then 48 else 55 end)
set #currpos = #currpos+2
end
return #result
end
GO
*

Here is a SQL function that will convert a hex string:
BEGIN
DECLARE #hexstring AS VARCHAR(8000)
SET #hexstring = '4368726973204Ce4747461'
DECLARE #strlen AS INT;
SET #strlen = Len(#hexstring)
DECLARE #currpos AS INT
SET #currpos = 1
DECLARE #hexpos AS VARCHAR(16)
SET #hexpos = '0123456789abcdef'
DECLARE #result AS VARCHAR(8000)
SET #result = ''
DECLARE #ch AS INT
WHILE #currpos < #strlen
BEGIN
SET #ch = CONVERT( INT, 16 * (CHARINDEX( SUBSTRING( #hexstring, #currpos, 1), #hexpos, 1) - 1)
+ (CHARINDEX(SUBSTRING(#hexstring, #currpos+1, 1), #hexpos, 1) - 1))
SET #result = #result + CASE WHEN #ch >= 32 AND #ch < 128 THEN CHAR(#ch) ELSE '?' END
SET #currpos = #currpos + 2
END
SELECT #result
END
I added a short hex string to show the function works.
Your hex string didn't convert so well. It may be because of the nulls in it, so I added the #char >= 32 part to strip out control codes (only convert printable ASCII characters, otherwise insert a ?) and you get a string that looks like the one you are after.

The conversion can be done with a single statement. Since you were using a function I provided my answer as such. Note that this solution requires that the input #hexstring is not prefixed with 0x.
CREATE FUNCTION [dbo].[HexToAscii]
(
#hexstring VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), #hexstring, 2))
END

Related

SQL byte truncate

My input is a varchar payload (that is actually made of hexadecimal characters). I would like to convert it to bits, then truncate the result to decode it.
I already have a built-in function (hexstrtovarbin) that works correctly and that converts varchars into varbinaries.
For example, for an input "4d", I would like to convert it into bits (01001101) then truncate the first 6 digits, before converting them into an integer (and get eventually 19).
DECLARE #payload varchar(4), #binarypayload binary(1), #converted smallint;
SET #payload = '4d';
SET #binarypayload = hexstrtovarbin(#payload);
SET #converted = CAST(SUBSTRING(#binarypayload, 1, 6) AS int)
If I proceed like this, #converted takes 77 as value. This is because #binarypayload value is "TQ==" (and not actual bits), so the substring does not truncate it.
I have tried to use bit data type, but could not store more than 1 of them.
Would anyone know how to get the actual bits in order to truncate them?
it can be messy but this is my answer, according to your data in the question:
declare #intvalue int
set #intvalue= CONVERT(int, CONVERT(varbinary(max), '4d', 2) )
declare #vsresult varchar(16)
declare #inti int
select #inti = 16, #vsresult = ''
declare #Input varchar(16)
--translating ex string in binary digits
while #inti>0
begin
select #vsresult=convert(char(1), #intvalue % 2)+#vsresult
select #intvalue = convert(int, (#intvalue / 2)), #inti=#inti-1
end
set #Input= left(#vsresult,LEN(#vsresult)-2) -- here your input string without last two digits, 00000000010011
--now return integer value
DECLARE #Cnt tinyint = 1
DECLARE #Len tinyint = LEN(#Input)
DECLARE #Output bigint = CAST(SUBSTRING(#Input, #Len, 1) AS bigint)
WHILE(#Cnt < #Len) BEGIN
SET #Output = #Output + POWER(CAST(SUBSTRING(#Input, #Len - #Cnt, 1) * 2 AS bigint), #Cnt)
SET #Cnt = #Cnt + 1
END
select #Output

SQL REPLACE special characters with value from another table

All,
I am trying to replace the special characters in a string with the URL
encoding values to which they correspond. Below is some example code I have
been working with.
Thanks for the help.
create table #url_encoding_lookup(character varchar(10), code varchar (20))
insert into #url_encoding_lookup (character, code)
values
('!', '%21'),
('"', '%22'),
('#', '%23'),
('$', '%24'),
('%', '%25'),
('&', '%26'),
('''', '%27'),
('(', '%28'),
(')', '%29'),
('*', '%2A'),
('+', '%2B'),
(',', '%2C'),
('-', '%2D'),
('.', '%2E'),
('/', '%2F')
Create table #data
(string varchar (200))
insert into #data
values
('Jim (BoB)'),
('Will''s Place'),
('Auto-Mart')
select * from #data
select * from #url_encoding_lookup
desired results would be
Jim %28Bob%29
Will%27s Place
Auto%2DMart
Create procedure
BEGIN
DECLARE _end BOOLEAN DEFAULT FALSE;
DECLARE _result CHAR(200) DEFAULT str;
DECLARE _find VARCHAR(32);
DECLARE _replace VARCHAR(32);
DECLARE _cur CURSOR FOR SELECT _character, _code FROM url_encoding_lookup;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET _end = TRUE;
OPEN _cur;
_loop: LOOP
FETCH _cur INTO _find, _replace;
IF _end THEN
LEAVE _loop;
END IF;
SET _result = REPLACE(_result, _find, _replace);
END LOOP _loop;
CLOSE _cur;
RETURN _result;
END
Then
SELECT _replace_chars(name) FROM `data`
Result
Jim %28BoB%29
Will%27s Place
Auto%2DMart
ALTER FUNCTION [dbo].[udf_ReplaceYouCoded]
(
#the_string nvarchar(max)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
declare #temp_field nvarchar(max)
create table #url_encoding_lookup(character varchar(10), code varchar (20))
insert into #url_encoding_lookup (character, code)
values
('!', '%21'),
('"', '%22'),
('#', '%23'),
('$', '%24'),
('%', '%25'),
('&', '%26'),
('''', '%27'),
('(', '%28'),
(')', '%29'),
('*', '%2A'),
('+', '%2B'),
(',', '%2C'),
('-', '%2D'),
('.', '%2E'),
('/', '%2F')
declare #x as int
set #x = 1
--LOOP #the_string
while #i < len(#the_string)
if(substring(#the_string,x,1) = (select character from #url_encoding_lookup where character = substring(#the_string,x,1)))
begin
#temp_field = #temp_field + (select code from #url_encoding_lookup where character = substring(#the_string,x,1))
end
else
begin
#temp_field = #temp_field + substring(#the_string,x,1)
end
select #x = #x + 1
end
RETURN #temp_field
END
ALTER function [dbo].[udf_ReplaceSpecialChars]
(#s varchar(256))
returns varchar(256)
as
begin
-- declare #s varchar(256) set #s = 'Jim (P)' --test
if #s is null
return null
declare #s2 varchar(256)
set #s2 = '' --set variable to empty string. ready to recieve values
declare #l int
set #l = len(#s) --determin the number of characters in #s
declare #p int
set #p = 1 --set beginning string position
while #p <= #l begin
declare #c int
set #c = ascii(substring(#s, #p, 1)) --find the ascii number for 1st
character
declare #nc varchar(256)
set #nc = (select code from url_encoding_lookup where ascii_code = #c) --
get corresponding URL encoding string from lookup table
if #c between 33 and 47 or #c between 58 and 64 or #c between 91 and 96
or #c between 123 and 255 --when looping through each character, if special
character
set #s2 = #s2 + #nc --then use string from lookup table
else if #c = 32 or #c between 48 and 57 or #c between 65 and 90 or #c
between 97 and 122 --if character is not special
set #s2 = #s2 + char(#c) --then find char value of character
set #p = #p + 1 --set position to next charachter for loop to look at
end
if len(#s2) = 0
return null
return #s2 --return rebuilt string
end
You can replace the special characters using the following regular expression [\u0100-\uffff]
select regexp_replace(column, '[\u0100-\uffff]', '')

How to toggle case of Entire string in sql

I want to toggle case of entire string.
I am able to do for characters, not for string.
DECLARE #Char AS VARCHAR(1)
SET #Char='a'
IF ASCII(#Char)>=97 AND ASCII(#Char) <=122
PRINT UPPER(#Char)
IF ASCII(#Char)>=65 AND ASCII(#Char) <=90
PRINT LOWER(#Char)
How, I can change case for entire string?
For Ex. "AbCdE", I want to change it to "aBcDe".
You can do it by creating functions:
First make function for one character:
CREATE FUNCTION ToggleChar
(
#Char VARCHAR(1)
)
RETURNS VARCHAR(1)
AS
BEGIN
RETURN CHAR(ASCII(UPPER(#Char))+ASCII(LOWER(#Char))-ASCII(#Char))
END
Then, create function for string:
CREATE FUNCTION ToggleCase
(
#Str VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #ResultStr VARCHAR(MAX)
SET #ResultStr=''
WHILE ( #Str<>'')
BEGIN
SET #ResultStr=#ResultStr + [dbo].[ToggleChar](#Str)
SET #Str= SUBSTRING(#Str,2,LEN(#Str))
END
RETURN #ResultStr
END
Now, use this function to toggle string.
SELECT dbo.ToggleCase('AbCdE') AS ToggleString
Try this:
DECLARE #Name VARCHAR(10) = 'SaMplE'
DECLARE #Count INT = 1
WHILE #Count <= LEN(#Name)
BEGIN
SET #Name = STUFF(#Name, #Count, 1,
CASE
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 97 AND 122 THEN
UPPER(SUBSTRING(#Name,#Count,1))
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 65 AND 90 THEN
LOWER(SUBSTRING(#Name,#Count,1))
END)
SET #Count = #Count + 1
END
SELECT #Name

How to replace all nonnumeric values?

This is TERADATA (not SQL Server, not Oracle )
I have a column of phone numbers:
(312)9879878
(298)989-9878
430-394-2934
394s9048ds987
..........
I need to clean this column into
3129879878
2989899878
4303942934
3949048987
..........
So that only numbers should stay. All other letters, special characters, hyphens ... should be removed. How can I do this?
Which release of TD is running at your site?
If it's 14 or you got the oTranslate UDF installed you can simply do an old trick nesting Translate:
oTranslate(phonenum, oTranslate(phonenum, '0123456789', ''), '')
Answer :
DECLARE #Input varchar(1000)
SET #Input = '01 vishal 98-)6543'
DECLARE #pos INT
SET #Pos = PATINDEX('%[^0-9]%',#Input)
WHILE #Pos > 0
BEGIN
SET #Input = STUFF(#Input,#pos,1,'')
SET #Pos = PATINDEX('%[^0-9]%',#Input)
END
SELECT #Input
Thank You,
Vishal Patel
I have this function to pull numerics (0-9) from a string:
CREATE FUNCTION NumbersOnly(#STR VARCHAR(2000))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE #N INT
DECLARE #NN VARCHAR(1000)
SET #N = 0
SET #NN = ''
WHILE #N <= LEN(#STR)
BEGIN
IF SUBSTRING(#STR,#N,1) >= '0'
AND SUBSTRING(#STR,#N,1) <= '9'
BEGIN
SET #NN = #NN + SUBSTRING(#STR,#N,1)
END
SET #N = #N + 1
END
RETURN #NN
END

Convert integer to hex and hex to integer

So I have this query working (where signal_data is a column) in Sybase but it doesn't work in Microsoft SQL Server:
HEXTOINT(SUBSTRING((INTTOHEX(signal_data)),5,2)) as Signal
I also have it in Excel (where A1 contains the value):
=HEX2DEC(LEFT(DEC2HEX(A1),LEN(DEC2HEX(A1))-2))
Does anyone know how I would do this in SQL Server?
Convert INT to hex:
SELECT CONVERT(VARBINARY(8), 16777215)
Convert hex to INT:
SELECT CONVERT(INT, 0xFFFFFF)
Update 2015-03-16
The above example has the limitation that it only works when the HEX value is given as an integer literal. For completeness, if the value to convert is a hexadecimal string (such as found in a varchar column) use:
-- If the '0x' marker is present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '0x1FFFFF', 1))
-- If the '0x' marker is NOT present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '1FFFFF', 2))
Note: The string must contain an even number of hex digits. An odd number of digits will yield an error.
More details can be found in the "Binary Styles" section of CAST and CONVERT (Transact-SQL). I believe SQL Server 2008 or later is required.
Actually, the built-in function is named master.dbo.fn_varbintohexstr.
So, for example:
SELECT 100, master.dbo.fn_varbintohexstr(100)
Gives you
100 0x00000064
SQL Server equivalents to Excel's string-based DEC2HEX, HEX2DEC functions:
--Convert INT to hex string:
PRINT CONVERT(VARCHAR(8),CONVERT(VARBINARY(4), 16777215),2) --DEC2HEX
--Convert hex string to INT:
PRINT CONVERT(INT,CONVERT(VARBINARY(4),'00FFFFFF',2)) --HEX2DEC
It is possible using the function FORMAT available on SQL Server 2012 and above
select FORMAT(10,'x2')
Results in:
0a
Convert int to hex:
SELECT FORMAT(512+255,'X')
The traditonal 4 bit hex is pretty direct.
Hex String to Integer (Assuming value is stored in field called FHexString) :
CONVERT(BIGINT,CONVERT(varbinary(4),
(SELECT master.dbo.fn_cdc_hexstrtobin(
LEFT(FMEID_ESN,8)
))
))
Integer to Hex String (Assuming value is stored in field called FInteger):
(SELECT master.dbo.fn_varbintohexstr(CONVERT(varbinary,CONVERT(int,
FInteger
))))
Important to note is that when you begin to use bit sizes that cause register sharing, especially on an intel machine, your High and Low and Left and Rights in the registers will be swapped due to the little endian nature of Intel. For example, when using a varbinary(3), we're talking about a 6 character Hex. In this case, your bits are paired as the following indexes from right to left "54,32,10". In an intel system, you would expect "76,54,32,10". Since you are only using 6 of the 8, you need to remember to do the swaps yourself. "76,54" will qualify as your left and "32,10" will qualify as your right. The comma separates your high and low. Intel swaps the high and lows, then the left and rights. So to do a conversion...sigh, you got to swap them yourselves for example, the following converts the first 6 of an 8 character hex:
(SELECT master.dbo.fn_replvarbintoint(
CONVERT(varbinary(3),(SELECT master.dbo.fn_cdc_hexstrtobin(
--intel processors, registers are switched, so reverse them
----second half
RIGHT(FHex8,2)+ --0,1 (0 indexed)
LEFT(RIGHT(FHex8,4),2)+ -- 2,3 (oindex)
--first half
LEFT(RIGHT(FHex8,6),2) --4,5
)))
))
It's a bit complicated, so I would try to keep my conversions to 8 character hex's (varbinary(4)).
In summary, this should answer your question. Comprehensively.
Here is the function for SQL server which converts integer value into its hexadecimal representation as a varchar. It should be easy to adapt to other database types
For example:
SELECT dbo.ToHex(4095) --> FFF
SQL:
CREATE FUNCTION ToHex(#value int)
RETURNS varchar(50)
AS
BEGIN
DECLARE #seq char(16)
DECLARE #result varchar(50)
DECLARE #digit char(1)
SET #seq = '0123456789ABCDEF'
SET #result = SUBSTRING(#seq, (#value%16)+1, 1)
WHILE #value > 0
BEGIN
SET #digit = SUBSTRING(#seq, ((#value/16)%16)+1, 1)
SET #value = #value/16
IF #value <> 0 SET #result = #digit + #result
END
RETURN #result
END
GO
Use master.dbo.fnbintohexstr(16777215) to convert to a varchar representation.
Maksym Kozlenko has a nice solution, and others come close to unlocking it's full potential but then miss completely to realized that you can define any sequence of characters, and use it's length as the Base. Which is why I like this slightly modified version of his solution, because it can work for base 16, or base 17, and etc.
For example, what if you wanted letters and numbers, but don't like I's for looking like 1's and O's for looking like 0's. You can define any sequence this way. Below is a form of a "Base 36" that skips the I and O to create a "modified base 34". Un-comment the hex line instead to run as hex.
declare #value int = 1234567890
DECLARE #seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE #seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE #result varchar(50)
DECLARE #digit char(1)
DECLARE #baseSize int = len(#seq)
DECLARE #workingValue int = #value
SET #result = SUBSTRING(#seq, (#workingValue%#baseSize)+1, 1)
WHILE #workingValue > 0
BEGIN
SET #digit = SUBSTRING(#seq, ((#workingValue/#baseSize)%#baseSize)+1, 1)
SET #workingValue = #workingValue/#baseSize
IF #workingValue <> 0 SET #result = #digit + #result
END
select #value as Value, #baseSize as BaseSize, #result as Result
Value, BaseSize, Result
1234567890, 34, T5URAA
I also moved value over to a working value, and then work from the working value copy, as a personal preference.
Below is additional for reversing the transformation, for any sequence, with the base defined as the length of the sequence.
declare #value varchar(50) = 'T5URAA'
DECLARE #seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE #seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE #result int = 0
DECLARE #digit char(1)
DECLARE #baseSize int = len(#seq)
DECLARE #workingValue varchar(50) = #value
DECLARE #PositionMultiplier int = 1
DECLARE #digitPositionInSequence int = 0
WHILE len(#workingValue) > 0
BEGIN
SET #digit = right(#workingValue,1)
SET #digitPositionInSequence = CHARINDEX(#digit,#seq)
SET #result = #result + ( (#digitPositionInSequence -1) * #PositionMultiplier)
--select #digit, #digitPositionInSequence, #PositionMultiplier, #result
SET #workingValue = left(#workingValue,len(#workingValue)-1)
SET #PositionMultiplier = #PositionMultiplier * #baseSize
END
select #value as Value, #baseSize as BaseSize, #result as Result
Declare #Dato xml
Set #Dato = Convert(xml, '<dato>FF</dato>')
Select Cast( rw.value( 'xs:hexBinary( text()[1])' , 'varbinary(max)' ) as int ) From #Dato.nodes('dato') as T(rw)
The answer by Maksym Kozlenko is nice and can be slightly modified to handle encoding a numeric value to any code format. For example:
CREATE FUNCTION [dbo].[IntToAlpha](#Value int)
RETURNS varchar(30)
AS
BEGIN
DECLARE #CodeChars varchar(100)
SET #CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE #CodeLength int = 26
DECLARE #Result varchar(30) = ''
DECLARE #Digit char(1)
SET #Result = SUBSTRING(#CodeChars, (#Value % #CodeLength) + 1, 1)
WHILE #Value > 0
BEGIN
SET #Digit = SUBSTRING(#CodeChars, ((#Value / #CodeLength) % #CodeLength) + 1, 1)
SET #Value = #Value / #CodeLength
IF #Value <> 0 SET #Result = #Digit + #Result
END
RETURN #Result
END
So, a big number like 150 million, becomes only 6 characters (150,000,000 = "MQGJMU")
You could also use different characters in different sequences as an encrypting device. Or pass in the code characters and length of characters and use as a salting method for encrypting.
And the reverse:
CREATE FUNCTION [dbo].[AlphaToInt](#Value varchar(7))
RETURNS int
AS
BEGIN
DECLARE #CodeChars varchar(100)
SET #CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE #CodeLength int = 26
DECLARE #Digit char(1)
DECLARE #Result int = 0
DECLARE #DigitValue int
DECLARE #Index int = 0
DECLARE #Reverse varchar(7)
SET #Reverse = REVERSE(#Value)
WHILE #Index < LEN(#Value)
BEGIN
SET #Digit = SUBSTRING(#Reverse, #Index + 1, 1)
SET #DigitValue = (CHARINDEX(#Digit, #CodeChars) - 1) * POWER(#CodeLength, #Index)
SET #Result = #Result + #DigitValue
SET #Index = #Index + 1
END
RETURN #Result
Given:
declare #hexStr varchar(16), #intVal int
IntToHexStr:
select #hexStr = convert(varbinary, #intVal, 1)
HexStrToInt:
declare
#query varchar(100),
#parameters varchar(50)
select
#query = 'select #result = convert(int,' + #hb + ')',
#parameters = '#result int output'
exec master.dbo.Sp_executesql #query, #parameters, #intVal output
Below are two functions: dbo.HexToInt and dbo.IntToHex, I use them for such conversion:
if OBJECT_ID('dbo.HexToInt') is not null
drop function dbo.HexToInt
GO
create function dbo.HexToInt (#chars varchar(max))
returns int
begin
declare #char varchar(1), #len int, #i int, #r int, #tmp int, #pow int
set #chars = RTRIM(LTRIM(#chars))
set #len = LEN(#chars)
set #i = 1
set #r = 0
while #i <= #len
begin
set #pow = #len - #i
set #char = SUBSTRING(#chars, #i, 1)
if #char = '0'
set #tmp = 0
else if #char = '1'
set #tmp = 1
else if #char = '2'
set #tmp = 2
else if #char = '3'
set #tmp = 3
else if #char = '4'
set #tmp = 4
else if #char = '5'
set #tmp = 5
else if #char = '6'
set #tmp = 6
else if #char = '7'
set #tmp = 7
else if #char = '8'
set #tmp = 8
else if #char = '9'
set #tmp = 9
else if #char = 'A'
set #tmp = 10
else if #char = 'B'
set #tmp = 11
else if #char = 'C'
set #tmp = 12
else if #char = 'D'
set #tmp = 13
else if #char = 'E'
set #tmp = 14
else if #char = 'F'
set #tmp = 15
set #r = #r + #tmp * POWER(16,#pow)
set #i = #i + 1
end
return #r
end
And the second one:
if OBJECT_ID('dbo.IntToHex') is not null
drop function dbo.IntToHex
GO
create function dbo.IntToHex (#val int)
returns varchar(max)
begin
declare #r varchar(max), #tmp int, #v1 int, #v2 int, #char varchar(1)
set #tmp = #val
set #r = ''
while 1=1
begin
set #v1 = #tmp / 16
set #v2 = #tmp % 16
if #v2 = 0
set #char = '0'
else if #v2 = 1
set #char = '1'
else if #v2 = 2
set #char = '2'
else if #v2 = 3
set #char = '3'
else if #v2 = 4
set #char = '4'
else if #v2 = 5
set #char = '5'
else if #v2 = 6
set #char = '6'
else if #v2 = 7
set #char = '7'
else if #v2 = 8
set #char = '8'
else if #v2 = 9
set #char = '9'
else if #v2 = 10
set #char = 'A'
else if #v2 = 11
set #char = 'B'
else if #v2 = 12
set #char = 'C'
else if #v2 = 13
set #char = 'D'
else if #v2 = 14
set #char = 'E'
else if #v2 = 15
set #char = 'F'
set #tmp = #v1
set #r = #char + #r
if #tmp = 0
break
end
return #r
end
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))
Is working for me as an expression in font colour
To convert Hex strings to INT, I have used this in the past. It can be modified to convert any base to INT in fact (Octal, Binary, whatever)
Declare #Str varchar(200)
Set #str = 'F000BE1A'
Declare #ndx int
Set #ndx = Len(#str)
Declare #RunningTotal BigInt
Set #RunningTotal = 0
While #ndx > 0
Begin
Declare #Exponent BigInt
Set #Exponent = Len(#Str) - #ndx
Set #RunningTotal = #RunningTotal +
Power(16 * 1.0, #Exponent) *
Case Substring(#str, #ndx, 1)
When '0' then 0
When '1' then 1
When '2' then 2
When '3' then 3
When '4' then 4
When '5' then 5
When '6' then 6
When '7' then 7
When '8' then 8
When '9' then 9
When 'A' then 10
When 'B' then 11
When 'C' then 12
When 'D' then 13
When 'E' then 14
When 'F' then 15
End
Set #ndx = #ndx - 1
End
Print #RunningTotal