From varchar(36) to UNIQUEIDENTIFIER - sql

I am trying to cast an AuctionId that is a UNIQUEIDENTIFIER to an varchar(36) and then back to an UNIQUEIDENTIFIER. Please help me.
CAST((SUBSTRING(CAST([AuctionId] as VARCHAR(36)), 0, 35) + '1') AS UNIQUEIDENTIFIER)
But I keep getting this error:
Msg 8169, Level 16, State 2, Line 647
Conversion failed when converting from
a character string to
uniqueidentifier.
Thanks in advance

The '1' is not the problem. You are obviously trying to change the last character of the GUID to a 1. I don't know why, but that's your requirement.
Your issue is with substring. In TSQL the substring uses an index starting at 1 not 0 like in C or C#. This means your substring statement is actually returning a 34 character string (+1 more character makes 35, and you're being told a 35 character string is not a GUID, which is right).
Just change the ,0,35 to 1,35

Your error is due to your +'1' and your SUBSTRING. What do you have that in there for?
This will work fine
SELECT cast((cast(NEWID() as varchar(36))) as UNIQUEIDENTIFIER)
EDIT: Ok, so if you want to replace the last char with a '1' then this is the solution
SELECT CAST(SUBSTRING(CAST(NEWID() AS VARCHAR(36)), 1, 35) + '1' AS UNIQUEIDENTIFIER)
The only difference is that SUBSTRING in SQL starts at position 1, not position 0 as you had it.
P.S. This is dangerous code. The output is no longer a GUID as it will not conform to the algorithm that was used to generate the GUID. This could (although unlikely) result in a collision with GUIDs which could potentially cause all manner of problems.

As others have observed, it's not clear why you want to do what you're doing.
An alternative to SUBSTRING is the STUFF command:
SELECT stuff(cast([AuctionId] as varchar(36)),36,1,'1')

Related

sql convert error on view tables

SELECT logicalTime, traceValue, unitType, entName
FROM vwSimProjAgentTrace
WHERE valueType = 10
AND agentName ='AtisMesafesi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND logicalTime IN (
SELECT logicalTime
FROM vwSimProjAgentTrace
WHERE valueType = 10 AND agentName ='AtisIrtifasi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND CONVERT(FLOAT , traceValue) > 123
) ORDER BY simName, logicalTime
This is my sql command and table is a view table...
each time i put "convert(float...) part " i get
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to float.
this error...
One (or more) of the rows has data in the traceValue field that cannot be converted to a float.
Make sure you've used the right combination of dots and commas to signal floating point values, as well as making sure you don't have pure invalid data (text for instance) in that field.
You can try this SQL to find the invalid rows, but there might be cases it won't handle:
SELECT * FROM vwSimProjAgentTrace WHERE NOT ISNUMERIC(traceValue)
You can find the documentation of ISNUMERIC here.
If you look in BoL (books online) at the convert command, you see that a nvarchar conversion to float is an implicit conversion. This means that only "float"-able values can be converted into a float. So, every numeric value (that is within the float range) can be converted. A non-numeric value can not be converted, which is quite logical.
Probably you have some non numeric values in your column. You might see them when you run your query without the convert. Look for something like comma vs dot. In a test scenario a comma instead of a dot gave me some problems.
For an example of isnumeric, look at this sqlfiddle

Error converting data type varchar to float

Searched and searched on SO and can't figure it out
Tried CASTING each field as FLOAT to no avail, convert didn't get me any further
How can I get the below case clause to return the value stated in the THEN section?
Error:
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to float.
section of my SQL query that makes it error:
When cust_trendd_w_costsv.terms_code like '%[%]%' and (prod.dbo.BTYS2012.average_days_pay) - (substring(cust_trendd_w_costsv.terms_code,3,2)) <= 5 THEN prod.dbo.cust_trendd_w_costsv.terms_code
average_days_pay = float
terms_code = char
Cheers!
Try to use ISNUMERIC to handle strings which can't be converted:
When cust_trendd_w_costsv.terms_code like '%[%]%'
and (prod.dbo.BTYS2012.average_days_pay) -
(case when isnumeric(substring(cust_trendd_w_costsv.terms_code,3,2))=1
then cast(substring(cust_trendd_w_costsv.terms_code,3,2) as float)
else 0
end)
<= 5 THEN prod.dbo.cust_trendd_w_costsv.terms_code
The issue that you're having is that you're specifically searching for strings that contain a % character, and then converting them (implicitly or explicitly) to float.
But strings containing % signs can't be converted to float whilst they still have a % in them. This also produces an error:
select CONVERT(float,'12.5%')
If you're wanting to convert to float, you'll need to remove the % sign first, something like:
CONVERT(float,REPLACE(terms_code,'%',''))
will just eliminate it. I'm not sure if there are any other characters in your terms_code column that may also trip it up.
You also need to be aware that SQL Server can quite aggressively re-order operations and so may attempt the above conversion on other strings in terms_code, even those not containing %. If that's the source of your error, then you need to prevent this aggressive re-ordering. Provided there are no aggregates involved, a CASE expression can usually avoid the worst of the issues - make sure that all strings that you don't want to deal with are eliminated by earlier WHEN clauses before you attempt your conversion
If your are sure that Substring Part returns a numeric value, You can Cast The substring(....) to Float :
.....and (prod.dbo.BTYS2012.average_days_pay) - (CAST(substring(cust_trendd_w_costsv.terms_code,3,2)) as float ) <= 5 ....

How does one filter based on whether a field can be converted to a numeric?

I've got a report that has been in use quite a while - in fact, the company's invoice system rests in a large part upon this report (Disclaimer: I didn't write it). The filtering is based upon whether a field of type VarChar(50) falls between two numeric values passed in by the user.
The problem is that the field the data is being filtered on now not only has simple non-numeric values such as '/A', 'TEST' and a slew of other non-numeric data, but also has numeric values that seem to be defying any type of numeric conversion I can think of.
The following (simplified) test query demonstrates the failure:
Declare #StartSummary Int,
#EndSummary Int
Select #StartSummary = 166285,
#EndSummary = 166289
Select SummaryInvoice
From Invoice
Where IsNull(SummaryInvoice, '') <> ''
And IsNumeric(SummaryInvoice) = 1
And Convert(int, SummaryInvoice) Between #StartSummary And #EndSummary
I've also attempted conversions using bigint, real and float and all give me similar errors:
Msg 8115, Level 16, State 2, Line 7
Arithmetic overflow error converting
expression to data type int.
I've tried other larger numeric datatypes such as BigInt with the same error. I've also tried using sub-queries to sidestep the conversion issue by only extracting fields that have numeric data and then converting those in the wrapper query, but then I get other errors which are all variations on a theme indicating that the value stored in the SummaryInvoice field can't be converted to the relevant data type.
Short of extracting only those records with numeric SummaryInvoice fields to a temporary table and then querying against the temporary table, is there any one-step solution that would solve this problem?
Edit: Here's the field data that I suspect is causing the problem:
SummaryInvoice
11111111111111111111111111
IsNumeric states that this field is numeric - which it is. But attempting to convert it to BigInt causes an arithmetic overflow. Any ideas? It doesn't appear to be an isolated incident, there seems to have been a number of records populated with data that causes this issue.
It seems that you are gonna have problems with the ISNUMERIC function, since it returns 1 if can be cast to any number type (including ., ,, e0, etc). If you have numbers longer than 2^63-1, you can use DECIMAL or NUMERIC. I'm not sure if you can use PATINDEX to perform an regex look on SummaryInvoice, but if you can, then you should try this:
SELECT SummaryInvoice
FROM Invoice
WHERE ISNULL(SummaryInvoice, '') <> ''
AND CASE WHEN PATINDEX('%[^0-9]%',SummaryInvoice) > 0 THEN CONVERT(DECIMAL(30,0), SummaryInvoice) ELSE -1 END
BETWEEN #StartSummary And #EndSummary
You can't guarantee what order the WHERE clause filters will be applied.
One ugly option to decouple inner and outer.
SELECT
*
FROM
(
Select TOP 2000000000
SummaryInvoice
From Invoice
Where IsNull(SummaryInvoice, '') <> ''
And IsNumeric(SummaryInvoice) = 1
ORDER BY SummaryInvoice
) foo
WHERE
Convert(int, SummaryInvoice) Between #StartSummary And #EndSummary
Another using CASE
Select SummaryInvoice
From Invoice
Where IsNull(SummaryInvoice, '') <> ''
And
CASE WHEN IsNumeric(SummaryInvoice) = 1 THEN Convert(int, SummaryInvoice) ELSE -1 END
Between #StartSummary And #EndSummary
YMMV
Edit: after question update
use decimal(38,0) not int
Change ISNUMERIC(SummaryInvoice) to ISNUMERIC(SummaryInvoice + '0e0')
AND with IsNumeric(SummaryInvoice) = 1, will not short circuit in SQL Server.
But may be you can use
AND (CASE IsNumeric(SummaryInvoice) = 1 THEN Convert(int, SummaryInvoice) ELSE 0 END)
Between #StartSummary And #EndSummary
Your first issue is to fix your database structure so bad data cannot get into the field. You are putting a band-aid on a wound that needs stitches and wondering why it doesn't heal.
Database refactoring is not fun, but it needs to be done when there is a data integrity problem. I assume you aren't really invoicing someone for 11,111,111,111,111,111,111,111,111 or 'test'. So don't allow those values to ever get entered (if you can't change the structure to the correct data type, consider a trigger to prevent bad data from going in) and delete the ones you do have that are bad.

Converting data type varchar to numeric

Msg 8114, Level 16, State 5, Procedure spGetDetails, Line 88
Error converting data type varchar to numeric.
I have already converted this #mfr_id to int type then also getting the above error.
I'm getting error while executing stored procedure.
The line which I'm getting error is:
if(#mfr_id = 5)
Use:
if(#mfr_id = '5')
Value comparisons have to be the same data type, or there has to be implicit data type conversion. Explicit conversion -- which is when you use CAST/CONVERT -- is ideal for maintenance because the operation is obvious.
Depending on your needs, the ISNUMERIC function might help. And be careful to define a length to your [n]varchar variables.
Updated answer
So it seems that #mfr_id is a varchar. To avoid the syntactic issue use the answer in OMG Ponies post.
But you also say that it is storing the string "1 2, 3, 4.....". So semantically are you wanting the IF statement to be true if it contains the value '5'?
If so you might need something like this
set #mfr_id = REPLACE(#mfr_id, ' ','')
if ((#mfr_id LIKE '5,%') OR (#mfr_id LIKE '%,5,%') OR (#mfr_id LIKE '%,5'))
Original Answer - Obsolete
if(CONVERT(int, #mfr_id) = 5)
should do the trick hopefully. See http://msdn.microsoft.com/en-us/library/ms187928.aspx for details. Although actually I think it should be implicitly converted. What is the value of #mfr_id? It should tell you this in the error message I think.
This answer is written using Oracle's PL/SQL syntax and one of the Oracle regular expression routines. I don't know T-SQL well enough to transcribe it but I expect that similar capabilities are available:
FOR aRow IN
(WITH DATA AS (SELECT #mfg_id AS S FROM DUAL)
SELECT REGEXP_SUBSTR(S, '[^ ,]+', 1, LEVEL) AS NUM_STRING
FROM DATA
CONNECT BY LEVEL < LENGTH(S) - LENGTH(REGEXP_REPLACE(S, '[ ,]', '')))
LOOP
IF aRow.NUM_STRING = '5' THEN
NULL; -- do something appropriate here
END IF;
END LOOP;
Share and enjoy.

Convert HashBytes to VarChar

I want to get the MD5 Hash of a string value in SQL Server 2005. I do this with the following command:
SELECT HashBytes('MD5', 'HelloWorld')
However, this returns a VarBinary instead of a VarChar value. If I attempt to convert 0x68E109F0F40CA72A15E05CC22786F8E6 into a VarChar I get há ðô§*à\Â'†øæ instead of 68E109F0F40CA72A15E05CC22786F8E6.
Is there any SQL-based solution?
Yes
I have found the solution else where:
SELECT SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'HelloWorld')), 3, 32)
SELECT CONVERT(NVARCHAR(32),HashBytes('MD5', 'Hello World'),2)
Use master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', #input), 1, 0) instead of master.dbo.fn_varbintohexstr and then substringing the result.
In fact fn_varbintohexstr calls fn_varbintohexsubstring internally. The first argument of fn_varbintohexsubstring tells it to add 0xF as the prefix or not. fn_varbintohexstr calls fn_varbintohexsubstring with 1 as the first argument internaly.
Because you don't need 0xF, call fn_varbintohexsubstring directly.
Contrary to what David Knight says, these two alternatives return the same response in MS SQL 2008:
SELECT CONVERT(VARCHAR(32),HashBytes('MD5', 'Hello World'),2)
SELECT UPPER(master.dbo.fn_varbintohexsubstring(0, HashBytes('MD5', 'Hello World'), 1, 0))
So it looks like the first one is a better choice, starting from version 2008.
convert(varchar(34), HASHBYTES('MD5','Hello World'),1)
(1 for converting hexadecimal to string)
convert this to lower and remove 0x from the start of the string by substring:
substring(lower(convert(varchar(34), HASHBYTES('MD5','Hello World'),1)),3,32)
exactly the same as what we get in C# after converting bytes to string
With personal experience of using the following code within a Stored Procedure which Hashed a SP Variable I can confirm, although undocumented, this combination works 100% as per my example:
#var=SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA2_512', #SPvar)), 3, 128)
Changing the datatype to varbinary seems to work the best for me.