Compare Varchar and UniqueIdentifier - sql-server

Due to a rather brilliant oversight in my current project, we have some guids getting stored in a varchar column in one table, which need to be compared to a uniqueidentifier column in another.
How can I do this? SQL server simply says it cannot convert from a character string to a uniqueidentifier.

If SQL complains it cannot cast it means not only you stored the uniqueidentifier as varchar, you used a different format than SQL Server (eg. you added the '{' and '}'). SQL is perfectly capable of casting string to uniqueidentifier when properly formatted:
declare #u uniqueidentifier;
declare #s varchar(64);
select #u = NEWID();
select #s = CAST(#u as varchar(64));
select CAST(#s as uniqueidentifier), #u, #s;
Depending on how you actualy stored the uniqueidentifier, you will most likely have tomodify the data and your code to match the SQL format (no {}).

Convert the uniqueidentifier to varchar:
CAST( uniqueidentifier_col_name as varchar)

I just worked up the following test script:
DECLARE
#Foo Uniqueidentifier
,#Foo2 varchar(50)
SET #Foo = newid()
SET #Foo2 = newId()
print #Foo
print #Foo2
if #Foo = #Foo2
print 'Yes'
else
print 'No'
set #Foo = #Foo2
if #Foo = #Foo2
print 'Yes'
else
print 'No'
Run in an SSMS window or via slqcmd -i file, the results are the same -- SQL (2005) does implicit conversion. This supports what I recall from SQL 2000 when I had a similar problem years ago.
The key thing is that the varchar string has to match the guid pattern:
8 hex digits
dash
4 hex digits
dash
4 hex digits
dash
4 hex digits
dash
12 hex digits

You'll have to cast the other uniqueidentifier to varchar.
SQL Server is probably tryng to cast things like "bob" to uniqueidentifier and it fails.
According to CAST/CONVERT it's allowed, so it must be the values in the varchar column.

Related

String or binary data would be truncated from SQL Server to PostgreSQL linked server

I am trying to migrate some data from SQL Server to PostgreSQL.
There is a string column which causes an error:
String or binary data would be truncated
In SQL Server, my column type is nvarchar(max), in PostgreSQL the type of the column is text.
My query looks something like this:
INSERT INTO PGLINKED.MYPGDB.MYTARGETTABLE
SELECT
MyColumn
FROM
MYSRCTABLE
However when I try cast MyColumn as nvarchar(4000) in select statement
INSERT INTO PGLINKED.MYPGDB.MYTARGETTABLE
SELECT
MyColumn = CAST(MyColumn AS NVARCHAR(4000))
FROM
MYSRCTABLE
it works fine. But the string was truncated.
How can I fix this?
nvarchar(max) is not the same as nvarchar(4000). When you cast it to a lesser length, in this case from max down to 4000, you will truncate data.
Here is an example in SQL Server:
DECLARE # varchar(100) = REPLICATE('A', 100)
SELECT # AS uncasted, CAST(# AS VARCHAR(4)) AS casted
Try casting it to nvarchar(max) on your insert.

Cannot update varchar column with special characters

Originally i thought that this issue is related to C# TransactionScope or Dapper.NET. But since i have tested the sql in SSMS and the issue remains i assume that it's a pure sql issue.
This is the (simplified) update which should update a varchar(40) column. I don't get any errors and row-count is 1. The old SparePartDescription is EC801/¦USB/Exch Acc/JP/PE bag:
declare #rowCount int
UPDATE [tabSparePart] SET
[SparePartDescription] = 'EC801/╡USB/Exch Acc/JP/PE bag'
WHERE ([idSparePart] = 13912)
set #rowCount = ##ROWCOUNT
select #rowCount
So the only difference are these special characters: ╡ and ¦.
Maybe you have an idea why i cannot update this column.
Well, the special character you are using:
╡
Is not supported in ASCII. See:
DECLARE #x VARCHAR(32) = 'EC801/╡USB/Exch Acc/JP/PE bag';
SELECT #x;
Result:
EC801/¦USB/Exch Acc/JP/PE bag
So the update is working fine, technically, it's just not doing what you want, because in order to fit into the ASCII space, it has to substitute your character for one that is valid.
In order to support that character, you'll have to use Unicode for your column (and maybe a specific collation, I'm not sure). This works fine:
DECLARE #x NVARCHAR(32) = N'EC801/╡USB/Exch Acc/JP/PE bag';
SELECT #x;
Result:
EC801/╡USB/Exch Acc/JP/PE bag
It will be important to specify the N prefix on string literals that contain such characters...

How do I force nvarchar input width in SQL Server?

I’ve got a script that I’ve created for our production line where the user enters some variables into the script before executing. The Problem is that the variables are NVARCHAR(9) and if the user inputs a 10 character sting the last character is cut off (as expected) what I want to know is how can I have SQL throw an error if they enter a value that is too long? This issue stems from users fat fingering their inputs.
Example:
Valid input -
DECLARE #ClientCode NVARCHAR(9)
SET #ClientCode = N'ABCDEFGHI'
SELECT #ClientCode
Results
ABCDEFGHI
Invalid input –
DECLARE #ClientCode NVARCHAR(9)
SET #ClientCode = 'ABCDDEFGHI'
SELECT #ClientCode
Results
ABCDDEFGH
What I’m hoping for is a setting that will have SSMS raise an error. What I’m hoping to avoid is something like -
DECLARE #ClientCode NVARCHAR(50)
...
IF LEN(#ClientCode) > 9
RAISERROR('Too long dummy.',16,1)
Thanks for you help
Please see SQL Server silently truncates varchar's in stored procedures - SQL Server cannot be set to automatically raise truncation errors for inserts inside of a stored procedure, so you have to perform the check yourself. You can do this in the stored procedure (the code you listed as "hoping to avoid") or you can validate beforehand in the client application.
I've also been looking at the question Scott Chapman references in his answer, however, I found igorp's answer midway down interesting, I had to hack it a bit to fix the SQL but it can work:
declare #p1 varchar(max), #p2 varchar(max)
select #p1 = 'abcd'
declare #p1Int varchar(2), #p2Int varchar(3)
declare #test table (p1 varchar(2), p2 varchar(3))
insert into #test (p1,p2) values (#p1, #p2)
select #p1Int=p1, #p2Int=p2 from #test

Store such characters in SQL Server 2008 R2

I'm storing encrypted passwords in the database, It worked perfect so far on MachineA. Now that I moved to MachineB it seems like the results gets corrupted in the table.
For example: ù9qÆæ\2 Ý-³Å¼]ó will change to ?9q??\2 ?-³?¼]? in the table.
That's the query I use:
ALTER PROC [Employees].[pRegister](#UserName NVARCHAR(50),#Password VARCHAR(150))
AS
BEGIN
DECLARE #Id UNIQUEIDENTIFIER
SET #Id = NEWID()
SET #password = HashBytes('MD5', #password + CONVERT(VARCHAR(50),#Id))
SELECT #Password
INSERT INTO Employees.Registry (Id,[Name],[Password]) VALUES (#Id, #UserName,#Password)
END
Collation: SQL_Latin1_General_CP1_CI_AS
ProductVersion: 10.50.1600.1
Thanks
You are mixing 2 datatypes:
password need to be nvarchar to support non-Western European characters
literals need N prefix
Demo:
DECLARE #pwdgood nvarchar(150), #pwdbad varchar(150)
SET #pwdgood = N'ù9qÆæ\2 Ý-³Å¼]ó'
SET #pwdbad = N'?9q??\2 ?-³?¼]?'
SELECT #pwdgood, #pwdbad
HashBytes gives varbinary(8000) so you need this in the table
Note: I'd also consider salting the stored password with something other than ID column for that row
If you want to store such characters, you need to:
use NVARCHAR as the datatype for your columns and parameters (#Password isn't NVARCHAR and the CAST you're using to assign the password in the database table isn't using NVARCHAR either, in your sample ...)
use the N'....' syntax for indicating Unicode string literals
With those two in place, you should absolutely be able to store and retrieve any valid Unicode character

string manipulation in sql server 2005

RCPT10-66631 IS A varchar value retrieved from database.
How to add 1 in it. that is i want to take next value
i.e RCPT10-66632.
you can split the string but i think that is not better solution
declare #s varchar(50)
set #s = 'RCPT10-66631'
select cast(cast(right(#s, len(#s)-charindex('-', #s, 0)) as int)+1 as varchar(50))

Resources