I have a problem with a special character inserted in a table of SQL Server 2008 R2.
The point is that when i'm trying to insert a string with the character º (e.g. 3 ELBOW 90º LONG RADIUS) in the table this appears like this: 3 ELBOW 90� LONG RADIUS, and when i'm trying to select all the rows that contains the character � the result is null.
I tried to make the select with ASCII by making this:
select * from itemcode where description like '%'+char(63)+'%'
and make this to know that the ASCII of that symbol is 63:
select ASCII('�')
But that doesn't work.
What i must do to select all the rows that have that character and what should i do to make that SQL recognize the character º?
Thanks
The degree symbol
U+00B0 ° degree sign (HTML: ° °)
is not an ASCII character and generally requires an NVARCHAR column and a N'' string literal. (except for codepages etc that support the symbol)
63 is the code of the question mark, which is the fallback for your inverse question mark in ASCII:
select UNICODE('�') => 63
select UNICODE(N'�') => 65533
where 65533 is the Unicode Replacement Character used to display characters that could not be converted or displayed.
when I run this:
print ascii('º')
I get 186 as the ascii code value, so try:
select * from YourTable Where Description like '%'+char(186)+'%'
to see all the ascii codes run this:
;WITH AllNumbers AS
(
SELECT 1 AS Number
UNION ALL
SELECT Number+1
FROM AllNumbers
WHERE Number<255
)
SELECT Number,CHAR(Number) FROM AllNumbers
OPTION (MAXRECURSION 255)
EDIT op stated in a comment that they are using nvarchar columns.
forger about ascii, use NCHAR (Transact-SQL) to output a degree symbol:
print '32'+NCHAR(176)+'F' --to display it
select * from YourTable
Where Description like '%'+NCHAR(176)+'%' --to select based on it
and use UNICODE (Transact-SQL) to get the value:
print UNICODE('°')
returns:
176
select top 10 * from table_name
where tbl_colmn like N'%'+ NCHAR(65533) + N'%'
the function NCHAR(65533) will return the character your're looking for.
In addition to making sure that it is an NVARCHAR, I would use something like this
select (N'�')
How to display special characters in SQL server 2008?
I know this is old, but recently faced the same problem, and found solution here
"The best way I know of to find it or get rid of it in SQL is to check for it using a binary collation. For example"
Declare #Foo Table(PK int primary key identity, MyData nvarchar(20));
Insert #Foo(MyData) Values (N'abc'), (N'ab�c'), (N'abc�')
Select * From #Foo Where MyData Like N'%�%'
-- Find rows with the character
Select * From #Foo
Where CharIndex(nchar(65533) COLLATE Latin1_General_BIN2, MyData) > 0
-- Update rows replacing character with a !
Update #Foo
set MyData = Replace(MyData, nchar(65533) COLLATE Latin1_General_BIN2, '!')
Select * From #Foo
Related
I have values as string format below,
Values :
-24,52
-22,74
-13,08
303,75
When i convert above string values as money all values displays as below
-2452,00
-2274,00
-1308,00
30375,00
All values have more "0" number problem.How can i convert string values to exact money format ?
You can try to remove the 00 like this:
select replace(convert(varchar,cast(yourNum as money),1), ',00','')
Or in SQL Server 2012 you can try to use FORMAT
SELECT Format(24.01, '##,##0')
select cast('-24,01' as money) / 100
For anything other than visual presentation its a good idea to avoid MONEY entirely.
try this query
WITH t
AS
(
SELECT -24.52 AS [val]
UNION
SELECT -22.74
UNION
SELECT -13.08
UNION
SELECT 303.75
)
SELECT CAST( ABS(t.val) AS decimal(10,2)) -- or decimal(10,0)
FROM t
i tried to replace the comma with a point and got lucky:
cast(replace('-12,23', ',', '.') as money)
the reason is, sql server treats ',' as thousend delimiter instead of decimal delimiter
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.
Running some pretty simple SQL here:
select *
from table
where columnA <> convert(int,columnB)
and isnumeric(columnB) = 1
Still getting this error every time:
Conversion failed when converting the nvarchar value 'XXX' to data type int.
If you're using SQL Server 2012 or more recent you could use TRY_PARSE which will return NULL when the parse fails.
SELECT TRY_PARSE('one' as int) -- NULL
, TRY_PARSE('1' as int) -- 1
, TRY_PARSE('0.1' as int) -- NULL
Returns the result of an expression, translated to the requested data type, or null if the cast fails in SQL Server. Use TRY_PARSE only for converting from string to date/time and number types.
Isnumeric has a lot of odd behavior. For example, it also considers currency signs such as $ or £, and even a hyphen (-) to be numeric.
I think you'd be better of using NOT columnB like '%[^0-9]%' to ONLY take numbers into account.
Check the comments at the bottom of the msdn page for isnumeric(), which you can find here: https://msdn.microsoft.com/en-us/library/ms186272.aspx
This may sound weird, but it breaks when do not put the ISNUMERIC check first. Try this out:
WITH [Table]
AS
(
SELECT columnA,columnB
FROM
(
VALUES (1,'2'),
(2,'XXX')
) A(columnA,columnB)
)
select *
from [Table]
where ISNUMERIC(columnB) = 1 --this works
AND columnA <> convert(int,columnB)
--where columnA <> convert(int,columnB) --this doesn't work
-- and isnumeric(columnB) = 1
I suggest you to reverse your checking like this:
SELECT *
FROM table
WHERE CONVERT(NVARCHAR, columnA) <> columnB
I got this using a combination of the answers and comments here. I used a CASE statement in my WHERE clause and also had to use LIKE instead of ISNUMERIC to account for illegal characters. I also had to use BIGINT because a few select samples were overflowing the INT column. Thanks for all of the suggestions everybody!
select * from patient
where PatientExternalID <>
(case when mrn not like '%[^0-9]%'
then convert(bigint, mrn)
else 0
end)
I am stuck on converting a varchar column UserID to INT. I know, please don't ask why this UserID column was not created as INT initially, long story.
So I tried this, but it doesn't work. and give me an error:
select CAST(userID AS int) from audit
Error:
Conversion failed when converting the varchar value
'1581............................................................................................................................' to data type int.
I did select len(userID) from audit and it returns 128 characters, which are not spaces.
I tried to detect ASCII characters for those trailing after the ID number and ASCII value = 0.
I have also tried LTRIM, RTRIM, and replace char(0) with '', but does not work.
The only way it works when I tell the fixed number of character like this below, but UserID is not always 4 characters.
select CAST(LEFT(userID, 4) AS int) from audit
You could try updating the table to get rid of these characters:
UPDATE dbo.[audit]
SET UserID = REPLACE(UserID, CHAR(0), '')
WHERE CHARINDEX(CHAR(0), UserID) > 0;
But then you'll also need to fix whatever is putting this bad data into the table in the first place. In the meantime perhaps try:
SELECT CONVERT(INT, REPLACE(UserID, CHAR(0), ''))
FROM dbo.[audit];
But that is not a long term solution. Fix the data (and the data type while you're at it). If you can't fix the data type immediately, then you can quickly find the culprit by adding a check constraint:
ALTER TABLE dbo.[audit]
ADD CONSTRAINT do_not_allow_stupid_data
CHECK (CHARINDEX(CHAR(0), UserID) = 0);
EDIT
Ok, so that is definitely a 4-digit integer followed by six instances of CHAR(0). And the workaround I posted definitely works for me:
DECLARE #foo TABLE(UserID VARCHAR(32));
INSERT #foo SELECT 0x31353831000000000000;
-- this succeeds:
SELECT CONVERT(INT, REPLACE(UserID, CHAR(0), '')) FROM #foo;
-- this fails:
SELECT CONVERT(INT, UserID) FROM #foo;
Please confirm that this code on its own (well, the first SELECT, anyway) works for you. If it does then the error you are getting is from a different non-numeric character in a different row (and if it doesn't then perhaps you have a build where a particular bug hasn't been fixed). To try and narrow it down you can take random values from the following query and then loop through the characters:
SELECT UserID, CONVERT(VARBINARY(32), UserID)
FROM dbo.[audit]
WHERE UserID LIKE '%[^0-9]%';
So take a random row, and then paste the output into a query like this:
DECLARE #x VARCHAR(32), #i INT;
SET #x = CONVERT(VARCHAR(32), 0x...); -- paste the value here
SET #i = 1;
WHILE #i <= LEN(#x)
BEGIN
PRINT RTRIM(#i) + ' = ' + RTRIM(ASCII(SUBSTRING(#x, #i, 1)))
SET #i = #i + 1;
END
This may take some trial and error before you encounter a row that fails for some other reason than CHAR(0) - since you can't really filter out the rows that contain CHAR(0) because they could contain CHAR(0) and CHAR(something else). For all we know you have values in the table like:
SELECT '15' + CHAR(9) + '23' + CHAR(0);
...which also can't be converted to an integer, whether you've replaced CHAR(0) or not.
I know you don't want to hear it, but I am really glad this is painful for people, because now they have more war stories to push back when people make very poor decisions about data types.
This question has got 91,000 views so perhaps many people are looking for a more generic solution to the issue in the title "error converting varchar to INT"
If you are on SQL Server 2012+ one way of handling this invalid data is to use TRY_CAST
SELECT TRY_CAST (userID AS INT)
FROM audit
On previous versions you could use
SELECT CASE
WHEN ISNUMERIC(RTRIM(userID) + '.0e0') = 1
AND LEN(userID) <= 11
THEN CAST(userID AS INT)
END
FROM audit
Both return NULL if the value cannot be cast.
In the specific case that you have in your question with known bad values I would use the following however.
CAST(REPLACE(userID COLLATE Latin1_General_Bin, CHAR(0),'') AS INT)
Trying to replace the null character is often problematic except if using a binary collation.
This is more for someone Searching for a result, than the original post-er. This worked for me...
declare #value varchar(max) = 'sad';
select sum(cast(iif(isnumeric(#value) = 1, #value, 0) as bigint));
returns 0
declare #value varchar(max) = '3';
select sum(cast(iif(isnumeric(#value) = 1, #value, 0) as bigint));
returns 3
I would try triming the number to see what you get:
select len(rtrim(ltrim(userid))) from audit
if that return the correct value then just do:
select convert(int, rtrim(ltrim(userid))) from audit
if that doesn't return the correct value then I would do a replace to remove the empty space:
select convert(int, replace(userid, char(0), '')) from audit
This is how I solved the problem in my case:
First of all I made sure the column I need to convert to integer doesn't contain any spaces:
update data set col1 = TRIM(col1)
I also checked whether the column only contains numeric digits.
You can check it by:
select * from data where col1 like '%[^0-9]%' order by col1
If any nonnumeric values are present, you can save them to another table and remove them from the table you are working on.
select * into nonnumeric_data from data where col1 like '%[^0-9]%'
delete from data where col1 like '%[^0-9]%'
Problems with my data were the cases above. So after fixing them, I created a bigint variable and set the values of the varchar column to the integer column I created.
alter table data add int_col1 bigint
update data set int_col1 = CAST(col1 AS VARCHAR)
This worked for me, hope you find it useful as well.
If I have the following nvarchar variable - BTA200, how can I extract just the BTA from it?
Also, if I have varying lengths such as BTA50, BTA030, how can I extract just the numeric part?
I would recommend a combination of PatIndex and Left. Carefully constructed, you can write a query that always works, no matter what your data looks like.
Ex:
Declare #Temp Table(Data VarChar(20))
Insert Into #Temp Values('BTA200')
Insert Into #Temp Values('BTA50')
Insert Into #Temp Values('BTA030')
Insert Into #Temp Values('BTA')
Insert Into #Temp Values('123')
Insert Into #Temp Values('X999')
Select Data, Left(Data, PatIndex('%[0-9]%', Data + '1') - 1)
From #Temp
PatIndex will look for the first character that falls in the range of 0-9, and return it's character position, which you can use with the LEFT function to extract the correct data. Note that PatIndex is actually using Data + '1'. This protects us from data where there are no numbers found. If there are no numbers, PatIndex would return 0. In this case, the LEFT function would error because we are using Left(Data, PatIndex - 1). When PatIndex returns 0, we would end up with Left(Data, -1) which returns an error.
There are still ways this can fail. For a full explanation, I encourage you to read:
Extracting numbers with SQL Server
That article shows how to get numbers out of a string. In your case, you want to get alpha characters instead. However, the process is similar enough that you can probably learn something useful out of it.
substring(field, 1,3) will work on your examples.
select substring(field, 1,3) from table
Also, if the alphabetic part is of variable length, you can do this to extract the alphabetic part:
select substring(field, 1, PATINDEX('%[1234567890]%', field) -1)
from table
where PATINDEX('%[1234567890]%', field) > 0
LEFT ('BTA200', 3) will work for the examples you have given, as in :
SELECT LEFT(MyField, 3)
FROM MyTable
To extract the numeric part, you can use this code
SELECT RIGHT(MyField, LEN(MyField) - 3)
FROM MyTable
WHERE MyField LIKE 'BTA%'
--Only have this test if your data does not always start with BTA.
declare #data as varchar(50)
set #data='ciao335'
--get text
Select Left(#Data, PatIndex('%[0-9]%', #Data + '1') - 1) ---->>ciao
--get numeric
Select right(#Data, len(#data) - (PatIndex('%[0-9]%', #Data )-1) ) ---->>335