SQL Server 2008 R2: How to identify and update hexadecimal value - sql-server

I have the following table called as Hexa_Table which consists of only one column namely val.
Table: Hexa_Table
CREATE TABLE Hexa_Table
(
val VARCHAR(50)
);
Insertion:
INSERT INTO Hexa_Table VALUES('123456789101213');
INSERT INTO Hexa_Table VALUES('414F2D53594F545641');
INSERT INTO Hexa_Table VALUES('1234F6789A1213G');
INSERT INTO Hexa_Table VALUES('414F2D363530303035');
INSERT INTO Hexa_Table VALUES('12345678910');
Note: Now I want to update only those values which are Hexadecimal and want to update it to String, for which I need to identify which are the Hexadecimal values in the table.
For example I have record number 2 that is 414F2D53594F545641 if you convert it will get AO-SYOTVA. And in 4th record I have 414F2D363530303035 if you convert it will get AO-650005.
Converted by using : This
Questions:
1. How to identify hexadecimal values in the table?
2. How to update hexadecimal values to string?

You can use CONVERT with style 1. Something like this in your scenario.
You can use Filter NOT LIKE '%[^0-9a-f]%' to match exact hex pattern and LEN(val) %2 = 0 to check if it has exact number of required bytes for convert
SELECT val,
CAST(CONVERT(varbinary(4), '0x' + val, 1) As VARCHAR(100)) as charstring,
CONVERT(varbinary(4), '0x' + val, 1) as HexVal
FROM Hexa_Table
WHERE val NOT LIKE '%[^0-9a-f]%'
AND LEN(val) %2 = 0;
Output:
val charstring HexVal
414F2D53594F545641 AO-S 0x414F2D53
414F2D363530303035 AO-6 0x414F2D36
Reference
How can I convert a varchar with hexadecimal value to int?
MSDN Convert

You can find hexadecimal values in your table using this:
like '%' + CHAR(0x00) +'%'
However in your example which you have shown, the values are stored already as string so I am not sure what you mean to convert the values as string.
On a side note:
If you want to know how to convert the hex to varchar then you need to use CONVERT like this":
CONVERT(VARCHAR(MAX), 0x48656c70)

To find out hexadecimal values you can in following:
select val
from Hexa_Table
where val like '%' + CHAR(0x00) +'%'
It is already stored as VARCHAR, what and how do you want to update?

Try this code:
BEGIN TRAN
SELECT * FROM Hexa_Table
WHERE val = #value_insert
IF (##ROWCOUNT = 0)
INSERT Hexa_Table
SELECT CONVERT(VARCHAR(50), #value_insert)
COMMIT

Related

How do you write a SQL query to find all the rows that has a float currency value like $15.34 in a nvarchar field

How do you write a SQL query to find only the rows that has a float currency value like $15.34 and NOT round currency value like 15 in a nvarchar field.
Assuming you have a mix of numeric and non-numeric, this should work to return all decimal values that are not whole dollar amounts:
Select * from tablename
where colname like '%.%' --Has a decimal (as in original query)
and colname not like '%.00' --Does not end with 00
It is as simple as
Select * from tablename where columnname = '15.34'
I would strip the $ out, and check if it evaluates to a numeric or not, and use a modulo to be sure a remainder remains when divided by 1.
DECLARE #TEST TABLE (columnname NVARCHAR(15))
INSERT INTO #TEST
SELECT '$15.34' UNION
SELECT 'ZERO' UNION
SELECT '$123.00'
SELECT *, CONVERT(MONEY,REPLACE(columnname,'$',''))
FROM #TEST
WHERE ISNUMERIC(REPLACE(columnname,'$',''))=1
AND CONVERT(MONEY,REPLACE(columnname,'$','')) % 1 != 0
You can use like
Select * from Yourtablename where Yourcolumnname like '$15.%'
Two things:
First, you want to find the rows having the $ in them.
WHERE LOCATE('$',columname) <> 0
Second, you want to find the rows where the rest of the value in the column is a floating point number.
AND CONVERT(REPLACE(columnname,'$',''),DECIMAL(10,2)) <> 0
That CONVERT() <>0 pattern works because MySQL silently returns zero when you try to convert a nonnumeric value to a number.

Convert nvarchar data to decimal

I have data stored in a nvarchar(10) column that I need to convert to decimal(10,3). Each record is a full 10 characters with leading zeros. The last three numbers represent decimals. How do I convert the following example?
col1
----------
0000100001
0002507630
0090078607
0258736000
Expected Output
col1 col2
-------------------------------
0000100001 100.001
0002507630 2507.630
0090078607 90078.607
0258736000 258736.000
I tried using
Cast(covert(decimal(10, 3), col1) as Decimal(10, 3)) as col2
The output I receive is
Arithmetic overflow error converting nvarchar to data type numeric.
How do do properly convert this data?
DECLARE #t AS TABLE (a NVARCHAR(10));
INSERT INTO #t VALUES ('0000100001'),('0002507630'),('0090078607'),('0258736000');
SELECT a,CAST(CAST(a AS INT)/1000.000 AS DECIMAL(10,3))
FROM #t;
Try this:
SELECT CAST (LEFT(col1, 7) + '.' + RIGHT(col1,3) AS DECIMAL(10,3))
SQL Fiddle demo

Short guid in SQL Server / converting from a character string to uniqueidentifier

I need to create a column witch will contain short guid. So I found out something like this:
alter table [dbo].[Table]
add InC UNIQUEIDENTIFIER not null default LEFT(NEWID(),6)
But I get the error:
Conversion failed when converting from a character string to uniqueidentifier.
I've been trying
LEFT(CONVERT(varchar(36),NEWID()),6)
and
CONVERT(UNIQUEIDENTIFIER,LEFT(CONVERT(varchar(36),NEWID()),6))
But I am still getting the same error.
There is no such thing as "short guid". Guid, or uniqueidentifier is a 16 byte data type. You can read about it in MSDN. It means that the length must always be 16 bytes and you cannot use 6 characters as you are trying to do.
In the same MSDN article you can find description how you can initialize this type:
A column or local variable of uniqueidentifier data type can be
initialized to a value in the following ways:
By using the NEWID function.
By converting from a string constant in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, in which each x is a
hexadecimal digit in the range 0-9 or a-f. For example,
6F9619FF-8B86-D011-B42D-00C04FC964FF is a valid uniqueidentifier
value.
In your case you are trying to convert only 6 characters to uniqueidentifier which obviously fails.
If you want to use just 6 characters, just use varchar(6):
alter table [dbo].[Table]
add InC varchar(6) not null default LEFT(NEWID(),6)
Keep in mind that in this case this guid is not guaranteed to be unique.
Using CRYPT_GEN_RANDOM instead of NEWID can improve random distribution of the string.
SELECT LEFT(CAST(CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER) AS VARCHAR(50)), 6)
I just made this one since I couldn't find a good answer on the internet.
Please keep in mind this is a 64 bit representation of a 128bit value, so it has twice the collision possibilities that a real GUID would have. Does not handle 0.
Function takes a NEWID value: 6A10A273-4561-40D8-8D36-4D3B37E4A19C
and shortens it to : 7341xIlZseT
DECLARE #myid uniqueidentifier= NEWID()
select #myid
DECLARE #bigintdata BIGINT = cast(cast(reverse(NEWID()) as varbinary(max)) as bigint)
DECLARE #charSet VARCHAR(70) = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE #cBase int = LEN(#charSet)
DECLARE #sUID varchar(22) = ''
DECLARE #x int
WHILE (#bigintdata <> 0)
BEGIN
SET #x = CAST(#bigintdata % #cBase as INT) + 1
SET #bigintdata = #bigintdata / #cBase
SET #sUID = SUBSTRING(#charSet, #x, 1) + #sUID;
END
SELECT #sUID

querying binary column using like in sql server

I'm using SQL Server 2008. In my table I have a column called TestData of type binary.
Sample data in TestData column are
1. 0x0001DC780C0030373156635D0C00B8840301009A0600AC
2. 0x0301DC780C0030373156385D0C006499C401009A0600AC
Wrote below two queries to get the rows where TestData starts with "0x0001". But none of them are working.
SELECT *
FROM T_TRANSACTION
WHERE CAST(Indicium AS nvarchar(MAX)) LIKE '0x0001%'
----No results found
SELECT *
FROM T_TRANSACTION
WHERE CAST(Indicium AS nvarchar(MAX)) LIKE '0x0001%'
----Returns all the rows
Please correct the query to get the expected results
Don't convert it, but treat is as a range (like you would datetime values)
DECLARE #foo TABLE (TestData varbinary(100) NOT NULL);
INSERT #foo (TestData) VALUES
(0x0001DC780C0030373156635D0C00B8840301009A0600AC),
(0x0001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA),
(0x0001AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
(0x0301DC780C0030373156385D0C006499C401009A0600AC),
(0x0301FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
(0x0302000000000000000000000000000000000000000000);
SELECT *
FROM #foo
WHERE TestData >= 0x0001 AND TestData < 0x0002;
-- added more digit for clarity of what actually happens
SELECT *
FROM #foo
WHERE TestData >= 0x00010000 AND TestData < 0x00020000;
SELECT *
FROM #foo
WHERE TestData >= 0x0001AA AND TestData < 0x0001AB;
SELECT *
FROM #foo
WHERE TestData >= 0x0301 AND TestData < 0x0302;
This has the bonus of being able to use an index on TestData
Edit, you just specify as many digits as you need
For a leading prefix LIKE comparison, gbn's answer will do. For a real LIKE equivalence of string searches, you can use LIKE as follows:
(borrowing schema and sample data from #gbn)
DECLARE #foo TABLE (TestData varbinary(100) NOT NULL);
INSERT #foo (TestData) VALUES
(0x0001DC780C0030373156635D0C00B8),
(0x0001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA),
(0x0001AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
(0x0301DC780C0030373156385D0C006499C401009A0600AC),
(0x0301FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF),
(0x0302000000000000000000000000000000000000000000);
SELECT *
FROM #foo
WHERE CAST(TestData AS VARCHAR(MAX)) LIKE '%'+CAST(0xDC78 AS VARCHAR(MAX))+'%';
When you cast a binary value to VARCHAR, all it does is treat the raw bits as a string stream. It does not magically convert it into the string representation. Consider the example below:
select cast(0x41 as varchar(10)); -- Result: A
select cast(0x414263 as varchar(10)); -- Result: ABc
Because the byte 0x41 or ordinal 65 is 'A' in the standard Latin codepage.
Don't use the byte array as string, use it like a number.
all you need to do is:
SELECT * FROM T_TRANSACTION WHERE Indicium >= 0x0001
or if you want to get a scpecific one:
SELECT * FROM T_TRANSACTION WHERE Indicium >=0x0001DC780C0030373156635D0C00B8840301009A0600AC

Getting 'Error converting data type varchar to numeric.'

I have a table called testTable with two columns, id that is auto incremented and someValue.
The data contained in the someValue column are: 12, 1.2, .4, 1d4, +, -, .
Data type for someValue is varchar(50).
Why are the following queries throwing
Error converting data type varchar to numeric.
select ID, someValue
from testTable
where ISNUMERIC(someValue + 'd0') = 1 and CAST(someValue as decimal(8,2)) > 0.1;
select tt.ID,tt.someValue
from (select ID, someValue
from testTable
where ISNUMERIC(someValue + 'd0') = 1) as tt
where CAST(tt.someValue as decimal(8,2)) > 0.1;
You have a few problems; CAST does not work on non-decimal input, and ISNUMERIC accepts strings that can convert to monetary amounts, including non-decimal values like '-', '.', or 'US$100'.
The right way to solve this is to add a Decimal column to your database, have whatever populates someValue to populate the Decimal column with the value you want to compare against, and only compare against the Decimal column.
If, for some reason, you cannot do that, you can use ISNUMERIC and only include non-monetary decimal amounts, and use Convert instead of CAST:
select ID, someValue
from testTable
where ID IN
(select ID from testTable where ISNUMERIC(someValue) = 1
AND Patindex('%[^0-9-+.]%', someValue) = 0
AND someValue NOT IN ('-', '+', '.')
)
and Convert(decimal, someValue) > 0.1
In your first statement you take directly from testTable and attempt:
CAST(someValue as decimal(8,2))
This will throw an error as you have not filtered out non-numerical values.

Resources