I have a table in sql server 2012, where one column is nvarchar. It contains Romanian characters. We've noticed that only some of the letters 'Ș' do not show in reports at all, so I found that it depends of the keyboard settings.
There are two different keyboard settings for Romanian - Standard and Legacy. Letter 'Ș' - inserted from Rom(Standard) keyboard have ASCII code 63, from Legacy it's 170.
Letter 'Ş' with CHAR(170) - shows in reports, but CHAR(63) - doesn't - even though it's the same letter (should be).
It would be simple if I could replace char(63) with char(170), but I cannot detect rows with character 63. The next select doesn't return rows:
select * from table1 where columnname like '%'+CHAR(63)+'%'
even though if I do select ASCII(SUBSTRING(columnname , 1, 1)) it returns me '63'.
even select charindex(char(63), columnname) - returns me 0
I also tried to do collation:
select * from table1 where columnname COLLATE Latin1_general_CI_AI like N'%s%'
it doesn't help - it returns only rows with 's' and char(170).
Please help me find these rows with wrong 'Ş'
So firstly from my comments, CHAR(63) is misleading as it represents a character that sql server is unable to display:
Unable to replace Char(63) by SQL query
The issue is possibly down to your selected collation, as if I run this sample I get the 2 rows containing the special characters:
CREATE TABLE #temp ( val NVARCHAR(50) )
INSERT INTO #temp
( val )
VALUES ( N'Șome val 1' ),
( N'some val 2' ),
( N'șome other val 3' )
SELECT *
FROM #temp
WHERE val COLLATE Latin1_General_BIN LIKE N'%ș%'
OR val COLLATE Latin1_General_BIN LIKE N'%Ș%'
DROP TABLE #temp
Output
val
=================
Șome val 1
șome other val 3
The specified collation is: Latin1_General_BIN, as found in this post:
replace only matches the beginning of the string
WHERE columnname LIKE N'%'+NCHAR(536)+'%'
This should help you find the character even if it was inserted as an unknown character as in the first insert below.
DECLARE #Table TABLE (text nvarchar(50))
INSERT INTO #Table(text)
SELECT 'Ș'
UNION ALL
SELECT N'Ș'
SELECT UNICODE(text) UNICODE
FROM #Table
Results:
UNICODE
63
536
'Ș' is NCHAR(536) and 'ș' is NCHAR(537).
If you then do:
SELECT * FROM #Table WHERE text LIKE N'%'+NCHAR(536)+'%'
Results:
text
?
Ș
Related
I have a conundrum....
There is a table with one NVARCHAR(50) Float column that has many rows with many numbers of various decimal lengths:
'3304.063'
'3304.0625'
'39.53'
'39.2'
I need to write a query to find only numbers with decimal places >= 4
First the query I wrote was:
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9]%'
The above code finds all numbers with decimal places >= 2:
'3304.063'
'3304.0625'
'39.53'
Perfect! Now, I just need to increase the [0-9] by 2...
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9][0-9][0-9]%'
this returned nothing! What?
Does anyone have an explanation as to what went wrong as well and/or a possible solution? I'm kind of stumped and my hunch is that it is some sort of 'LIKE' limitation..
Any help would be appreciated!
Thanks.
After your edit, you stated you are using FLOAT which is an approximate value stored as 4 or 8 bytes, or 7 or 15 digits of precision. The documents explicitly state that not all values in the data type range can be represented exactly. It also states you can use the STR() function when converting it which you'll need to get your formatting right. Here is how:
declare #table table (columnName float)
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
--see the conversion
select * , str(columnName,20,4)
from #table
--now use it in a where clause.
--Return all values where the last digit isn't 0 from STR() the conversion
select *
from #table
where right(str(columnName,20,4),1) != 0
OLD ANSWER
Your LIKE statement would do it, and here is another way just to show they both work.
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
select *
from #table
where len(right(columnName,len(columnName) - charindex('.',columnName))) >= 4
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
One thing that could be causing this is a space in the number somewhere... since you said the column type was VARCHAR this is a possibility, and could be avoided by storing the value as DECIMAL
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304. 0625'), --notice the space here
('39.53'),
('39.2')
--this would return nothing
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
How to find out if this is the case?
select *
from #table
where columnName like '% %'
Or, anything but numbers and decimals:
select *
from #table
where columnName like '%[^.0-9]%'
The following is working fine for me:
declare #tab table (val varchar(50))
insert into #tab
select '3304.063'
union select '3304.0625'
union select '39.53'
union select '39.2'
select * from #tab
where val like '%.[0-9][0-9][0-9][0-9]%'
Assuming your table only has numerical data, you can cast them to decimal and then compare:
SELECT COLUMN
FROM tablename
WHERE CAST(COLUMN AS DECIMAL(19,4)) <> CAST(COLUMN AS DECIMAL(19,3))
You'd want to test the performance of this against using the character data type solutions that others have already suggested.
You can use REVERSE:
declare #vals table ([Val] nvarchar(50))
insert into #vals values ('3304.063'), ('3304.0625'), ('39.53'), ('39.2')
select [Val]
from #Vals
where charindex('.',reverse([Val]))>4
in my database I have this char �. I want to locate them with a query
Select *
from Sometable
where somecolumn like '%�%'
this gets me no result.
I think it is ANSI encoding
use N like below
where col like N'%�%'
why do you think ,you need N prefix:
Prefix Unicode character string constants with the letter N. Without the N prefix, the string is converted to the default code page of the database. This default code page may not recognize certain characters.
Thanks to Martin Smith,Earlier i tested only with one character earlier and it worked,but as Martin pointed out, it returns all characters..
Below query works and returns only intended
select * from #demo where id like N'%�%'
COLLATE Latin1_General_100_BIN
Demo:
create table #demo
(
id nvarchar(max)
)
insert into #demo
values
(N'ﬗ'),
( N'�')
to know more about unicode,please see below links
http://kunststube.net/encoding/
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/
This is the Unicode replacement character symbol.
It could match any of 2,048 invalid code points in the UCS-2 encoding (or the single character U+FFFD for the symbol itself).
You can use a range and a binary collate clause to match them all (demo).
WITH T(N)
AS
(
SELECT TOP 65536 NCHAR(ROW_NUMBER() OVER (ORDER BY ##SPID))
FROM master..spt_values v1,
master..spt_values v2
)
SELECT N
FROM T
WHERE N LIKE '%[' + NCHAR(65533) + NCHAR(55296) + '-' + NCHAR(57343) + ']%' COLLATE Latin1_General_100_BIN
You can use ASCII to find out the ascii code for that char
Select ascii('�')
And use CHAR to retrieve the char from that code and combine it in a LIKE expression
Select * from Sometable
where somecolumn like '%'+CHAR(63)+'%'
Note the collation you use can affect the result. Also it depends on the encoding used by your application to feed your data (UTF-8, UNICODE, etc). also how you store it VARCHAR, or NVARCHAR has a last say on what you see.
There's more here in this similar question
EDIT
#Mark
try this simple test:
create table sometable(somecolumn nvarchar(100) not null)
GO
insert into sometable
values
('12345')
,('123�45')
,('12345')
GO
select * from sometable
where somecolumn like '%'+CHAR(63)+'%'
GO
This only means that character was stored win the as a "?" in this test.
When you see a � it means the app where you are seeing isn't quite sure what to print out.
It also mean OP probably needs to find out what char is that using a query.
Also note it means a string outputted like ��� can be 3 formed by different characters.
CHAR(63) was just an example, but you are right this in the ASCII table will be a standard interrogation.
EDIT
#Bridge
Not with time right now to deep dig in it but the below test don't worked
Select ascii('�'), CHAR(ascii('�')), UNICODE(N'�'), CHAR(UNICODE(N'�'))
GO
create table sometable(somecolumn nvarchar(100) not null)
GO
insert into sometable
values
('12345')
,('123�45')
,('12345')
,('12'+NCHAR(UNICODE(N'�'))+'345')
GO
select * from sometable
where somecolumn like '%'+CHAR(63)+'%'
select * from sometable
where somecolumn like '%'+NCHAR(UNICODE(N'�'))+'%'
GO
In SQL Server 2014, i want to select a row which contains a word that is not present inside any of the angled brackets <>.
Sample Data:
Row 1 --> <div class="highlight"><b>Maddy</b></div>
Row 2 --> <div><b>This is highlighting an feature.</b></div>"
Here i want to filter only second row. So i used a query like
select * from table where column like '%<%>[a-zA-z0-9]*'+'highlight'+'%<%>%'"
I believe this is what you need:
LIKE 'T%[a-z]%[a-z]%'
Now would be a good time to familiarize yourself with what you can and cannot do with the LIKE operator.
Attempt:
select * from table_name where column_name like 'T[a-z]%'
select * from table_name where column_name like '[T]%'
You've nearly had the answer yourself Mathan.
The only problem that I can see with your code is that you were treating the LIKE expression as a dynamic expression.
If you are searching for a specific value in the middle of a substring then you need to wrap it in wildcards, even if you are joining search expressions together, e.g. LIKE '%highlight% + '%<%>%'
DECLARE #table table ( [column] varchar(100));
insert into #table ([column])
SELECT * FROM
(
VALUES
('<div class="highlight"><b>Maddy</b></div>'),
('<div><b>This is highlighting an feature.</b></div>')
) as [table] ([column]);
--SELECT * FROM #table;
select
[text_value] = PATINDEX('%<div>%', [column]) + LEN('<div>'),
SUBSTRING(
[column] -- what you're searching
, PATINDEX('%<div>%', [column]) + LEN('<div>') -- after the '<div>',
-- need to add the length of the 'div' as PATINDEX returns the starting location
, PATINDEX('%</div>%', [column]) - LEN('</div>') -- until the '</div>'
)
, *
from #table
where [column] like
'%<%>[a-zA-z0-9]%' -- you need to end these with the wildcard
+'%highlight%' -- or SQL-Server thinks it's the end of the sentence
+'%<%>%';
EDIT:
Adding in the PATINDEX can be used to remove the '<>' from the string. Example above removes the <div></div> but you can use that to remove any others as necessary e.g. <b></b>
I have a column (XID) that contains a varchar(20) sequence in the following format: xxxzzzzzz Where X is any letter or a dash and zzzzz is a number.
I want to write a query that will strip the xxx and evaluate and return which is the highest number in the table column.
For example:
aaa1234
bac8123
g-2391
After, I would get the result of 8123
Thanks!
A bit painful in SQL Server, but possible. Here is one method that assumes that only digits appear after the first digit (which you actually specify as being the case):
select max(cast(stuff(col, 1, patindex('%[0-9]%', col) - 1, '') as float))
from t;
Note: if the last four characters are always the number you are looking for, this is probably easier to do with right():
select max(right(col, 4))
Using Numbers table
declare #string varchar(max)
set #string='abc1234'
select top 1 substring(#string,n,len(#string))
from
numbers
where n<=len(#string)
and isnumeric(substring(#string,n,1))=1
order by n
Output:1234
Using PATINDEX you can achieve it, like this -
DECLARE #test table
(
id INT,
player varchar(100)
)
INSERT #test
VALUES (1,'aaa1234'),
(2,'bac8123'),
(3,'g-2391')
SELECT
MAX(CONVERT(INT, LTRIM(SUBSTRING(player, PATINDEX('%[0-9]%', player), LEN(player)))))
FROM #test
Try:
Select MAX(RIGHT(XID,17))
from table
You can also use this method
CREATE TABLE #Tmp
(
XID VARCHAR(20)
)
INSERT INTO #Tmp(XID)
VALUES ('aaa1234'), ('bac8123'), ('g-2391')
SELECT MAX(RIGHT(XID, LEN(XID) - 3))
FROM #Tmp
I have a table like this:
DECLARE #T TABLE
(note VARCHAR (50))
INSERT #T
SELECT 'Amplifier'
UNION ALL SELECT ';'
UNION ALL SELECT 'Regulator'
How can I replace the semicolon (';') with blank ('').
Expected Output:
Amplifier
'' -- here semicolon replace with blank
Regulator
If you want to replace ALL semicolons from any outputted cell you can use REPLACE like this:
SELECT REPLACE(note,';','') AS [note] FROM #T
Fetching from the given table, use a CASE statement:
SELECT CASE WHEN note = ';' THEN '' ELSE note END AS note FROM #T;
replace() would replace all occurrences of the character. Doesn't seem like you'd want that. This expression only replaces exact matches of the whole string.
It looks like you need to REPLACE all your semicolons:
DECLARE #T TABLE
(note VARCHAR (50))
INSERT INTO #T
SELECT REPLACE(SourceColumn, ';', '')
FROM SourceTable
SQL Server 2017 introduced the function TRANSLATE where you can specifiy a list of characters to be replaced
SELECT TRANSLATE('MAX(0,MIN(h-36,8))', '(,-)', ' ') -->'MAX 0 MIN h 36 8 '