SQL Server string to varbinary conversion - sql

Ok, the problem is that there's a merger or join that needs to be done on 2 tables. One has file content stored as an [image] type or varbinary(max), the other has the file content stored as a hex string. if I upload the same content into both tables
the content as string (bytearray to string) would look like like this...
'application/vnd.xfdl;content-encoding="base64-gzip"
H4sIAAAAAAAAC+y9e1fjONI4/H9/Cg173idwFgIJl+5m6MzPJAayE+KsnXQPs8+cHJMY8HZi57ET
aObMh3918UW2Jcdyrmbg7E7HtqpUpSqVSqWSdPHLj/EIPBuOa9rWl51K+WgHGNbAHprW45edpqYc
fPp0+vmgsvNL7cPFb1eNFoDlLffLztN0Ojk/PHx5eSl3Zo4hDx+N8sAeH6Iyh2fl0x1S8Hwwc6f2'
...
the content as image looks like (and this is ultimately what I want it to look like)
0x6170706C69636174696F6E
if I do select convert(varbinary(MAX), #contentAsString) I get 0x6100700070006C00690063006100740069006F006E
it appears as though the conversion is on target but putting two zeros (00) between each, I'll call it a byte for lack of better words.
I've tried all sorts of more complicated methods posted across forums but to no avail.
Any help would be appreciated.

From MSDN
In SQL Server 2008, these conversions are even more easier since we
added support directly in the CONVERT built-in function. The code
samples below show how to perform the conversion(s):
declare #hexstring varchar(max);
set #hexstring = '0xabcedf012439';
select CONVERT(varbinary(max), #hexstring, 1);
set #hexstring = 'abcedf012439';
select CONVERT(varbinary(max), #hexstring, 2);
go
declare #hexbin varbinary(max);
set #hexbin = 0xabcedf012439;
select
CONVERT(varchar(max), #hexbin, 1),
CONVERT(varchar(max), #hexbin, 2);
go

Ok, so the padded 00 has been answered.
DECLARE #hexStringNVar nvarchar(max)
DECLARE #hexStringVAR varchar(max)
SET #hexStringNVar = '{my hex string as described above}'
SET #hexStringVAR = '{my hex string as described above}'
select CONVERT(varbinary(MAX), #hexStringNVar)) = 0x6100700070006C00690063...
select CONVERT(varbinary(MAX), #hexStringVAR)) = 0x6170706C6963...
The 00 padding is because of Unicode or NVARCHAR as opposed to VARCHAR.
So, since the stored data is in nvarchar(max), the solution is this:
select CAST(cast(#hexStringNVar as varchar(max)) as varbinary(max)) = 0x6170706C6963...
I'm sure that convert would work just as well but my target SQL Server is 2005.

Related

Reverse substring

I am trying to extract some characters from a string.
For Example in (316409953_ND_02142022_000001.pdf) I need the characters after the last underscore _ and before the "."
Answer: 000001
#test = 316409953_ND_02142022_000001.pdf
I have tried:
REVERSE(SUBSTRING(REVERSE(test),CHARINDEX('.',REVERSE(test))+1,CHARINDEX('_',REVERSE(test)+1)))
I need help with the last part of substring. First error I am getting is "Conversion failed when converting the varchar value 'fdp.100000_22024120_DN_359904613' to data type int."
Secondly I need it to pick only after the last "_"
Please guide or let me know if there's another way to do this.
This looks like SQL Server.
On that assumption, and using the single example value, you can try the follolwing:
declare #test varchar(50) = '316409953_ND_02142022_000001.pdf'
select #test OriginalValue,
ParseName(Right(#test, CharIndex('_',Reverse(#test))-1),2) ExtractedValue;
it isn't pretty but it does the job ;P
declare #str varchar(200) = '316409953_ND_02142022_000001.pdf'
declare #tempStr varchar(200)= (select SUBSTRING(#str,LEN(#str) + 2 - CHARINDEX('_',REVERSE(#str)),LEN(#str)))
set #tempStr = SUBSTRING(#tempStr,1,CHARINDEX('.',#tempStr) - 1)
select #tempStr

How to replace non-standard Unicode with Space or Tab using SQL

I have a SQL2008 R2 database with several fields having the data type [IMAGE] the values in the field are actually BLOBs representing varied formats of mostly text. The Binary Data is created by HP’s Service Manager where they are used internally to populate tables and arrays in the GUI. I am using BIRT (4.2) the Eclipse-based reporting tool, to harvest data and create reports.
While it is possible to convert the IMAGE to table arrays, performance issues, preclude that in many cases. I am trying to create a fully SQL based solution to translate and dissect the IMAGE to readable, usable text. The Binary characters I care about are mostly in the first 127 Unicode set, and all in the first 255 Unicode. There is a bunch of garbage outside of this range that is presumably used for formatting in the GUI.
I am looking for a SQL solution that replaces values outside of basic Unicode (127 or 255) with a space or tab. My attempts to use replace() failed as it only seems to recognize the basic Unicode characters. My best solution would replace blocks of garbage outside of a given Unicode range with a single tab (and be as simple as existing solutions below).
I have one solution the converts it to a string with some garbage left in it.
select
-- Raw is an image, limited options for cast, so cast it as varbinary
-- Default characters converted is 30 so set to (8000)
-- then cast varbinary to varchar (so a person can read it)
-- substring ignores the first 9 characters after casting
substring (cast (cast (Table.a as varbinary (8000))as varchar(8000)), 9, 7991)as 'SubstringCastCast'
from dbo.Table
I have a screen shot of the data preview, but insufficient reputation to post it, It does not transfer well via copy and paste.
I have another solution where I find and extract the one piece that I need (i.e. IM0012001234)
select
-- Extract the 12 digit ticket number
substring (CastCast,
-- Find start of Ticket number
charindex('IM',CastCast)
, 12) as 'ETicket'
--Create data set with string that contains ticket, so I can extract it above
from(
select
-- use cast to get a small data set with the ticket number in it
cast (cast (Table.a as varbinary (200))as varchar(200)) as 'CastCast'
from dbo.Table
)InnerQ
I have written a function that strips out anything other than A-Z a-z 0-9... maybe this can help (tweak to suit your needs, you can put in ELSE ' ' to put in a space where the characters are unrecognised):
CREATE FUNCTION [dbo].[StripPunctuation]
(
#String VARCHAR(255)
)
RETURNS VARCHAR(255) AS
/*
$ Description: Strips out all non alpha-numeric
$ characters from a string
$
*/
BEGIN
DECLARE #i INT
DECLARE #Char CHAR(1)
DECLARE #Wk VARCHAR(255)
-- Only copy 0-9, a-z, A-Z.
SET #Wk = ''
SET #i = 1
WHILE #i <= LEN(#String)
BEGIN
SET #Char = SUBSTRING(#String, #i, 1)
IF (ASCII(#Char) > 47) AND (ASCII(#Char) < 58)
SET #Wk = #Wk + #Char
IF (ASCII(#Char) > 64) AND (ASCII(#Char) < 91)
SET #Wk = #Wk + #Char
IF (ASCII(#Char) > 96) AND (ASCII(#Char) < 123)
SET #Wk = #Wk + #Char
SET #i = #i +1
END
RETURN #Wk
END

SQL Server converting varbinary to string

I want to do conversion in T-SQL from a varbinary type to string type
Here is an example :
First I got this varbinary
0x21232F297A57A5A743894A0E4A801FC3
And then I want to convert it to
21232f297a57a5a743894a0e4a801fc3
How to do this?
Try:
DECLARE #varbinaryField varbinary(max);
SET #varbinaryField = 0x21232F297A57A5A743894A0E4A801FC3;
SELECT CONVERT(varchar(max),#varbinaryField,2),
#varbinaryField
UPDATED:
For SQL Server 2008
I know this is an old question, but here is an alternative approach that I have found more useful in some situations. I believe the master.dbo.fn_varbintohexstr function has been available in SQL Server at least since SQL2K. Adding it here just for completeness. Some readers may also find it instructive to look at the source code of this function.
declare #source varbinary(max);
set #source = 0x21232F297A57A5A743894A0E4A801FC3;
select varbin_source = #source
,string_result = master.dbo.fn_varbintohexstr (#source)
If you want to convert a single VARBINARY value into VARCHAR (STRING) you can do by declaring a variable like this:
DECLARE #var VARBINARY(MAX)
SET #var = 0x21232F297A57A5A743894A0E4A801FC3
SELECT CAST(#var AS VARCHAR(MAX))
If you are trying to select from table column then you can do like this:
SELECT CAST(myBinaryCol AS VARCHAR(MAX))
FROM myTable
This works in both SQL 2005 and 2008:
declare #source varbinary(max);
set #source = 0x21232F297A57A5A743894A0E4A801FC3;
select cast('' as xml).value('xs:hexBinary(sql:variable("#source"))', 'varchar(max)');
I looked everywhere for an answer and finally this worked for me:
SELECT Lower(Substring(MASTER.dbo.Fn_varbintohexstr(0x21232F297A57A5A743894A0E4A801FC3), 3, 8000))
Outputs to (string):
21232f297a57a5a743894a0e4a801fc3
You can use it in your WHERE or JOIN conditions as well in case you want to compare/match varbinary records with strings
Here is a simple example I wrote to convert and convert back using the 2 convert methods, I also checked it with a fixed string
declare #VB1 VARBINARY(500),#VB2 VARBINARY(500),#VB3 VARBINARY(500)
declare #S1 VARCHAR(500)
SET #VB1=HASHBYTES('SHA1','Test')
SET #S1=CONVERT(varchar(500),#VB1,2)
SET #VB2=CONVERT(varbinary(500),#S1,2)
SET #VB3=CONVERT(varbinary(500),'640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA',2)
SELECT #VB1,#S1,#VB2,#VB3
IF #VB1=#VB2 PRINT 'They Match(2)'
IF #VB1=#VB3 PRINT 'They Match(3)'
PRINT str(Len(#VB1))
PRINT str(Len(#S1))
PRINT str(Len(#VB2))
SET #VB1=HASHBYTES('SHA1','Test')
SET #S1=CONVERT(varchar(500),#VB1,1)
SET #VB2=CONVERT(varbinary(500),#S1,1)
SELECT #VB1,#S1,#VB2
IF #VB1=#VB2 PRINT 'They Match(1)'
PRINT str(Len(#VB1))
PRINT str(Len(#S1))
PRINT str(Len(#VB2))
and the output
|||
0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA|640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA|0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA|0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA
(1 row(s) affected)
They Match(2)
They Match(3)
20
40
20
||
0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA|0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA|0x640AB2BAE07BEDC4C163F679A746F7AB7FB5D1FA
(1 row(s) affected)
They Match(1)
20
42
20

varbinary to string on SQL Server

How to convert a column value from varbinary(max) to varchar in human-readable form?
The following expression worked for me:
SELECT CONVERT(VARCHAR(1000), varbinary_value, 2);
Here are more details on the choice of style (the third parameter).
"Converting a varbinary to a varchar" can mean different things.
If the varbinary is the binary representation of a string in SQL Server (for example returned by casting to varbinary directly or from the DecryptByPassPhrase or DECOMPRESS functions) you can just CAST it
declare #b varbinary(max)
set #b = 0x5468697320697320612074657374
select cast(#b as varchar(max)) /*Returns "This is a test"*/
This is the equivalent of using CONVERT with a style parameter of 0.
CONVERT(varchar(max), #b, 0)
Other style parameters are available with CONVERT for different requirements as noted in other answers.
Actually the best answer is
SELECT CONVERT(VARCHAR(1000), varbinary_value, 1);
using "2" cuts off the "0x" at the start of the varbinary.
Try this
SELECT CONVERT(varchar(5000), yourvarbincolumn, 0)
I tried this, it worked for me:
declare #b2 VARBINARY(MAX)
set #b2 = 0x54006800690073002000690073002000610020007400650073007400
SELECT CONVERT(nVARCHAR(1000), #b2, 0);
For a VARBINARY(MAX) column, I had to use NVARCHAR(MAX):
cast(Content as nvarchar(max))
Or
CONVERT(NVARCHAR(MAX), Content, 0)
VARCHAR(MAX) didn't show the entire value
Have a go at the below as I was struggling to
bcp "SELECT CAST(BINARYCOL AS VARCHAR(MAX)) FROM OLTP_TABLE WHERE ID=123123 AND COMPANYID=123"
queryout "C:\Users\USER\Documents\ps_scripts\res.txt" -c -S myserver.db.com -U admin -P password
Reference: original post

Is there any simple way to format decimals in T-SQL?

I know it could be done trivially in a non-SQL environment [post-data processing, frontend, what have you], but that's not possible at the moment. Is there a way to take a decimal(5,2) and convert it to a varchar without the trailing zeroes/decimal points? For example:
declare #number decimal(5,2)
set #number = 123.00
select cast(#number as varchar) as FormattedNumber
And the result is '123.00'. Is there a (simple) way to get '123' instead? And likewise, instead of '123.30', '123.3'? Could do it by figuring out whether or not the hundredths/tenths places were 0 and manually trimming characters, but I wanted to know if there was a more elegant solution.
What about:
SELECT CAST(CAST(#number AS float) AS varchar(10))
However you may want to test this carefully with your raw data first.
This way is pretty simple:
DECLARE #Number DECIMAL(5,2)
SELECT #Number = 123.65
SELECT FormattedNumber = CAST(CAST(#Number AS DECIMAL(3,0)) AS VARCHAR(4))
Returns '124'.
The only thing to consider is whether you want to round up/down, or just strip the zeroes and decimal points without rounding; you'd cast the DECIMAL as an INT in the second case.
For controlled formatting of numbers in T-SQL you should use the FORMAT() function. For example:
DECLARE #number DECIMAL(9,2); SET #number = 1234567.12;
DECLARE #formatted VARCHAR(MAX); SET #formatted = FORMAT(#number, 'N0', 'en-AU');
PRINT #formatted;
The result will be:
1,234,567
The arguments to the FORMAT() function are:
FORMAT(value, format [, culture])
The value argument is your number. The format argument is a CLR type formatting string (in this example, I specified "normal number, zero precision"). The optional culture argument allows you to override the server culture setting to format the number as per a desired culture.
See also the MSDN ref page for FORMAT().
The Convert function may do what you want to do.
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/a87d0850-c670-4720-9ad5-6f5a22343ea8.htm
Let me try this again....
CREATE FUNCTION saneDecimal(#input decimal(5,2)) returns varchar(10)
AS
BEGIN
DECLARE #output varchar(10)
SET #output = CAST(#input AS varchar(10))
DECLARE #trimmable table (trimval char(1))
INSERT #trimmable VALUES ('0')
INSERT #trimmable VALUES ('.')
WHILE EXISTS (SELECT * FROM #trimmable WHERE trimval = CAST(SUBSTRING(#output, LEN(#output), 1) AS char(1)))
SET #output = LEFT(#output, LEN(#output) - 1)
RETURN #output
END
GO
SELECT dbo.saneDecimal(1.00)
You could strip the trailing zeroes in a while loop:
declare #number decimal(5,2)
declare #str varchar(100)
set #number = 123.00
set #str = #number
while substring(#str,len(#str),1) in ('0','.',',')
set #str = substring(#str,1,len(#str)-1)
But as AdaTheDev commented, this is more easily done client-side.
Simple and elegant? Not so much...but that's T-SQL for you:
DECLARE #number decimal(5,2) = 123.00
DECLARE #formatted varchar(5) = CAST(#number as varchar)
SELECT
LEFT(
#formatted,
LEN(#formatted)
- PATINDEX('%[^0.]%', REVERSE(#formatted))
+ 1
)
Use the Format(value,format string,culture) function in SQL Server 2012+
If you have SQL Server 2012 or Greater you can use the format function like this:
select format(#number,'0') as FormattedNumber
Of course the format function will return an nvarchar, and not a varchar. You can cast to get a specific type.
Also, take a look at the T-SQL STR function in Books Online; this can be used for formatting floats and might work for your case. For some reason it doesn't come up in Google searches relating to this problem.