Using varchar(8000) column value in HashByte md5 function - sql-server

I want to create a hash using all the row values in SQL. In that table one of the column length is varchar(8000).I put a hashbyte function like below -
Hashbyte('MD5',column1+column2+....) -- column1 having varchar(8000) length and it contains string of length 8000.
Then it gives me same hashbyte where the rows having same value in column1 even if other columns contains different data
Then I converted column1 to varchar(max) in hashbyte function, I got different hashbyte for each row.
Hashbyte('MD5',convert(varchar(max),column1)+column2+....)
Why the hashbyte('MD5'...) wont take all column values?
If you want to try one more example of having varchar(8000) column issue-
try to calculate the length
create a table having column with varchar(8000) and calculate length of all column values. It will give you 8000 only. Next convert the varchar(8000) to varchar(max) it will give you correct result.
len(column1+column2...) --> 8000
len(convert(varchar(max),column1)+column2...) --> actual length
adding any string with varchar(8000) is such an issue?

You're under the misconception that a varchar(8000) concatenated to a varchar(8000) (or even any other length <= 8000) results in a varchar(MAX). This is not true. To get a MAX length you must define at least one of the values in the expression as a MAX.
This is confirmed in the remarks in + (String Concatenation) (Transact-SQL):
Remarks
...
If the result of the concatenation of strings exceeds the limit of 8,000 bytes, the result is truncated. However, if at least one of the strings concatenated is a large value type, truncation does not occur.
As a result you need to convert one of the values first to MAX and then the rest would implicitly be cast to a MAX as well. If you don't explicitly convert (at least) one of the expressions, then the value will be truncated, as the documentation states.
Obviously this applies to nvarchar as well, where truncation occurs at 4,000 characters (which is still 8,000 bytes).

Related

Converting varchar into a decimal

How do I turn the values below on the left into the values in brackets? (SQL Server 2012)
50 (000.050)
100 (000.100)
1000 (001.000)
9999 (009.999)
20000 (020.000)
This seems to be rather easy... What have you tried yourself?
First of all: If these values are (integer) numbers, you should not store them in a string column. Any code can break easily, if there are non-numeric values among them...
You can try this:
DECLARE #mockup TABLE(ID INT IDENTITY,YourValue VARCHAR(100))
INSERT INTO #mockup VALUES('50'),('100'),('1000'),('9999'),('20000');
SELECT *
,CAST(YourValue AS DECIMAL(10,3))/1000 AS NewValue
,FORMAT(CAST(YourValue AS DECIMAL(10,3))/1000,'000.000') AS Formatted
FROM #mockup
Casting a string like "1000" to DECIMAL will get a number back. This number can be divided by 1000 to get the value needed.
If you need the format as provided, you can use FORMAT() on SQL-Server 2012+, but this function is known as rather slow... If this is important for you, search for other ways to format a number. There are many examples here on SO...

Passing column/variable as binary value to convert function

I am manipulating a large value containing rows and columns values separated with ASCII row and column separators. The result is tabular data which I am inserting in SQL table.
Simple example to get the idea:
George|20;Ivan|15;Peter|10;
is transform to:
George 20
Ivan 15
Peter 10
and inserted in Users ([name], [age]) table.
Before insert, each value is converted to its column type using TRY_CONVERT function. The issue is this does not work as expected with VARBINARY data. For example (the second output is correct):
DECLARE #A NVARCHAR(1024) = '0xFE520676B1A1D93DABAB2319EEA03674F3632EAEEB163D1E88244F5EB1DE10EB';
SELECT TRY_CONVERT(VARBINARY(255), #A)
-- 0x300078004600450035003200300036003700360042003100410031004400390033004400410042004100420032003300310039004500450041003000330036003700340046003300360033003200450041004500450042003100360033004400310045003800380032003400340046003500450042003100440045003100300045004200
SELECT TRY_CONVERT(VARBINARY(255), 0xFE520676B1A1D93DABAB2319EEA03674F3632EAEEB163D1E88244F5EB1DE10EB)
-- 0xFE520676B1A1D93DABAB2319EEA03674F3632EAEEB163D1E88244F5EB1DE10EB
When the VARBINARY data is passed as string, the string is converting itself to VARBINARY. I need to pass the data without quotes, but how to do this when a column/variable of type string is passed?
I needed to use the style option of the TRY_CONVERT function.
DECLARE #A NVARCHAR(1024) = '0xFE520676B1A1D93DABAB2319EEA03674F3632EAEEB163D1E88244F5EB1DE10EB';
-- using style option 1
SELECT TRY_CONVERT(VARBINARY(255), #A, 1)
SELECT TRY_CONVERT(VARBINARY(255), 0xFE520676B1A1D93DABAB2319EEA03674F3632EAEEB163D1E88244F5EB1DE10EB)

Calculating MD5 HashBytes for Nvarchar(max) column is possible in SQL?

I have a table with a column data type nvarchar(max), the column will have data more than 8000 characters.
mytext navarchar(max)
I want to calculate hash value of that column, I am using the following code in MS SQL 2008/R2
select HASHBYTES('md5',column_name)
But I am getting error as,
String or binary data would be truncated.
Is that possible to calculate hash value in nvarchar(max) field in sql query.
Or is there any other ways to do it.
Thanks in advance.
Allowed input values are limited to 8000 bytes as was mentioned.
Try:
select master.sys.fn_repl_hash_binary(cast(column_name as varbinary(max)))
For this operation you have to disable FIPS validated cryptographic algorithms:
http://blog.aggregatedintelligence.com/2007/10/fips-validated-cryptographic-algorithms.html

Handling more than 8000 chars in stored proc parameter

I have a SQL Stored procedure that sends a mail. It's signature looks like this:
CREATE PROCEDURE SendMail
#From varchar(40),
#To varchar(255),
#Subject varchar(255),
#Body varchar(max),
#CC varchar(255) = null,
#BCC varchar(255) = null
AS...
When the message is for example 5000 characters it work. When it is 12 000, I get an error that [ODBC SQL Server Driver]String data, right truncation.
According to the help files varchar(max) can handle 2^31-1 bytes / characters.
So I tried changing #Body varchar(max) to #Body varchar(30000) and I get an error that
The size (30000) given to the type 'varchar' exceeds the maximum allowed for any data type (8000).
So the max is 8000 and not 2^31-1 bytes?
How can I handle more than 8000 characters?
You need to use nvarchar(max), instead of varchar(4000) or varchar(max). This can store up to 2 GB of text, which will solve your problem...
For more information see http://technet.microsoft.com/en-us/library/ms186939.aspx
Text fields cannot be larger than 8060 Bytes (8K) due to SQL Server Page Size which is 8K...
varchar has a maximum #of chars of 8000
nvarchar has a maximum #of chars of 4000 (each char-->2 bytes)
You cannot declare a parameter varchar(30000)
You should use varchar(max) or nvarchar(max)
the first has 2^31 chars (approx 2billions), the latter has 2^30 chars (approx 1billion)
Also, please note that SQL Server has a Stored Proc Named sp_send_dbmail that you can use to sen emails...
Try using NVARCHAR(MAX) instead of VARCHAR(MAX).
Use the BLOB data type. I use it occasionally for very long fields but it cannot be compared. I do not believe there is a max length on BLOB.
Max. capacity is 2 GByte of space - so you're looking at just over 1 billion 2-byte characters that will fit into a NVARCHAR(MAX) field.
Using the other answer's more detailed numbers, you should be able to store
(2 ^ 31 - 1) / 2 = 1'037'741'823 double-byte characters
1 billion, 37 million, 741 thousand and 823 characters to be precise
in your NVARCHAR(MAX) column (unfortunately, that last half character is wasted...)
SOURCE
REPLICATE returns the input type irrespective of later assignment. It's annoying, but to avoid silent truncation, try this example:
declare #x varchar(max) set #x = replicate (cast('a' as varchar(max)),
10000) select #x, len(#x)
This is because SQL Server performs the REPLICATE operation before it considers what you're assigning it to or how many characters you're trying to expand it to. It only cares about the input expression to determine what it should return, and if the input is not a max type, it assumes it is meant to fit within 8,000 bytes.

Conversion failed when converting the nvarchar value to data type int

I have a table of data with a primary key which generally takes the format of $$$$#####$$, although there a couple of exceptions to this where there is no number. I want to extract the number part of the key and then use it so I can generate unique primary keys.
I therefore created a view which contained a column showing only the numeric value and ignored any items which could not convert to numbers.
When I wrote a query to select a specific item from the view I get
Conversion failed when converting the nvarchar value to data type
int.
and it would appear that although I specifically ignored the exceptions in the view they are still being references some how.
Any help would greatly be appreciated.
Matt
I want to extract the number part of the key and then use it so I can
generate unique primary keys.
Use this Fastest way to remove non-numeric characters from a VARCHAR in SQL Server :
CREATE Function [fnRemoveNonNumericCharacters](#strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', #strText) > 0
BEGIN
SET #strText = STUFF(#strText, PATINDEX('%[^0-9]%', #strText), 1, '')
END
RETURN #strText
END
Pass your column value to the function and then cast it to the integer. You can create another function that convert this checking that whether column value contain any numeric value after applying the above function.
Another Reference.
Hope this help

Resources