SQL Server 2019 LIKE script with wildcard is not working while MySQL is OK - sql

I'm using SQL Server 2019 with graph tables. My script returns only Id9 while the same script under MySQL returns ID4,8,9 (which is the expected result). I don't know why the '%' used as prefix is not working on SQL Server.
Here's the script:
CREATE TABLE Test([Id] int IDENTITY(1,1) NOT NULL,
[FullName] nvarchar(128) NULL,
CONSTRAINT [PK_Test_Id] PRIMARY KEY CLUSTERED (Id ASC));
INSERT INTO Test (FullName) VALUES
(N'F''Sheree Jones II' ),
(N'Cybèle' ),
(N'T''Junior' ),
(N'Urane Of Watson Lake' ),
(N'J''Sirène De Dan Jourdain' ),
(N'Goodson des loups de l''antarctique'),
(N'F''Sheree Jones Of Dawson City' ),
(N'Pénélope Of Watson Lake' ),
(N'Liubov''s Siren' ),
(N'Siréna' );
select * from Test where FullName like '%siren%'

#NolmëInformatique, this is the variant with table-valued function usage:
create function schema_name.function_name (#name nvarchar(100))
returns table
as
return
(
select FullName from Test
WHERE FullName COLLATE Latin1_general_CI_AI Like '%'+#name+'%'
COLLATE Latin1_general_CI_AI
);
The function can be called via this query:
select * from schema_name.function_name ('siren');

Because a letter with accent is not the same letter without one. And you should consider uppercase letters. Try this code:
select * from Test WHERE upper(FullName) COLLATE Latin1_general_CI_AI Like '%CAFE%' COLLATE Latin1_general_CI_AI

This is in addition to #Vad1m's answer above.
The 'Siren' in your table has a Capitalized 'S'.
Check if server is case insensitive or not. Run this query:
SELECT SERVERPROPERTY('COLLATION')
If result is:
SQL_Latin1_General_CP1_CI_AS
CI means case insensitive.
If not, you will need to use lower() function in your where clause.

Related

How to remove extended ASCII chars from SQL Server

So trying to remove all the extended ascii characters and used collation SQL_Latin1_General_CP1253_CI_AI in the ddl but still getting ascii characters. Is there any suggestion ?
I have a value stored in the sql as 'àccõrd' and i want it to be stored as accord. When i try select àccõrd collate SQL_Latin1_General_CP1253_CI_AI it works but when i load it still gets loaded as àccõrd
Here are two ways to achieve what you're trying to do...
First method: define the column with a specific collation, e.g.:
create table dbo.Foo (
FooName varchar(50) collate SQL_Latin1_General_CP1253_CI_AI
);
insert dbo.Foo (FooName) values ('àccõrd');
select FooName from dbo.Foo;
Which yields:
FooName
-------
accord
Second method: collate the text when inserting it into your table:
-- Display the SQL Server instance's "default collation," configured during setup.
-- e.g.: SQL_Latin1_General_CP1_CI_AS
select serverproperty('collation') as ServerCollation;
-- Display the current database's "default collation," configured in CREATE DATABASE.
-- e.g.: SQL_Latin1_General_CP1_CI_AS
select collation_name
from sys.databases
where [name]=db_name();
create table dbo.Bar (
BarName varchar(50) --database default: collate SQL_Latin1_General_CP1_CI_AS
);
insert dbo.Bar (BarName) values ('àccõrd' collate SQL_Latin1_General_CP1253_CI_AI);
select BarName from dbo.Bar;
Which yields:
BarName
-------
accord
NOTE: These collation tricks only work with char and varchar data types.

case sensitive sql search in vb.net

So I've been using the query builder in visual studio (visual basic) to search a local mdb file. I have a button that is clicked to make a prompt for a search, and it works fine except that is is not case sensitive. Here is what I have so far:
SELECT ID, LastName, FirstName, FullTime, HireDate, Salary
FROM SalesStaff
WHERE LastName like ? + '%'
My professor wants us to use the InStr fuction, but how do I get that to work with a prompt?
(InputBox in my vb form code). Furthermore, it doesn't seem to have case sensitivity either. This is the first time I am using SQL, so I hardly know what I'm doing.
Thanks in advance!
You can amend the collation settings of your database/table.
Alternatively if you just want a case sensitive comparison on this one statement you can use the collate keyword, such as below:
select 1 where 'abc' = 'ABC'
select 1 where 'abc' collate Latin1_General_CS_AS = 'ABC' collate Latin1_General_CS_AS
select 1 where 'abc' collate Latin1_General_CI_AS = 'ABC' collate Latin1_General_CI_AS
select 1 where upper('abc') collate Latin1_General_CS_AS = 'ABC' collate Latin1_General_CS_AS
select 1 where upper('abc') collate Latin1_General_CI_AS = 'ABC' collate Latin1_General_CI_AS
CI stands for case insensitive.
CS stands for case sensitive.

Making a view case insensitive for a case sensitive table

Is is possible to make a view case insensitive if the table (or view) it is looking at is case sensitive?
I have view on a database that looks at a view on another server (that I can't alter) that is case sensitive, and stored in all caps. I want my view to be case insensitive, but I can't find a way to do it. Collate only works on the select statement, because I can't alter the view to add collation. The table's properties show that it's case insensitive, but it isn't.
The results of
exec sp_help 'dbo.myView'
shows that the collation is case sensitive. Is there a way to do this?
Just add COLLATE SQL_Latin1_General_CP1_CI_AS to the columns coming from the remote table.
CREATE VIEW [dbo].[myView] (
TextColumn1,
Column2,
TextColumn3)
AS
SELECT
t.TextColumn1 COLLATE SQL_Latin1_General_CP1_CI_AS,
t.Column2,
t.TextColumn3 COLLATE SQL_Latin1_General_CP1_CI_AS
FROM
RemoteServer.dbo.REMOTE_TABLE AS t
GO
Reference:
COLLATE (Transact-SQL)
CREATE TABLE tb_CollateTest (str varchar(max))
GO
INSERT tb_CollateTest VALUES
('Unique')
,('uNiQuE')
GO
CREATE VIEW vw_CollateTest AS
SELECT
str COLLATE SQL_Latin1_General_CP1_CS_AS AS str
FROM tb_CollateTest
GROUP BY str COLLATE SQL_Latin1_General_CP1_CS_AS
GO
SELECT * FROM vw_CollateTest
str
----------
Unique
uNiQuE
(2 row(s) affected)

compare s, t with ş, ţ in SQL Server

I followed this post How do I perform an accent insensitive compare (e with è, é, ê and ë) in SQL Server? but it doesn't help me with " ş ", " ţ " characters.
This doesn't return anything if the city name is " iaşi " :
SELECT *
FROM City
WHERE Name COLLATE Latin1_general_CI_AI LIKE '%iasi%' COLLATE Latin1_general_CI_AI
This also doesn't return anything if the city name is " iaşi " (notice the foreign ş in the LIKE pattern):
SELECT *
FROM City
WHERE Name COLLATE Latin1_general_CI_AI LIKE '%iaşi%' COLLATE Latin1_general_CI_AI
I'm using SQL Server Management Studio 2012.
My database and column collation is "Latin1_General_CI_AI", column type is nvarchar.
How can I make it work?
The characters you've specified aren't part of the Latin1 codepage, so they can't ever be compared in any other way than ordinal in Latin1_General_CI_AI. In fact, I assume that they don't really work at all in the given collation.
If you're only using one collation, simply use the correct collation (for example, if your data is turkish, use Turkish_CI_AI). If your data is from many different languages, you have to use unicode, and the proper collation.
However, there's an additional issue. In languages like Romanian or Turkish, ş is not an accented s, but rather a completely separate character - see http://collation-charts.org/mssql/mssql.0418.1250.Romanian_CI_AI.html. Contrast with eg. š which is an accented form of s.
If you really need ş to equal s, you have replace the original character manually.
Also, when you're using unicode columns (nvarchar and the bunch), make sure you're also using unicode literals, ie. use N'%iasi%' rather than '%iasi%'.
In SQL Server 2008 collations versioned 100 were introduced.
Collation Latin1_General_100_CI_AI seems to do what you want.
The following should work:
SELECT * FROM City WHERE Name LIKE '%iasi%' COLLATE Latin1_General_100_CI_AI
Not tidiest solution I guess, but if you know that it's just the "ş" and "ţ" characters that are the problem, would it be acceptable to do a replace?
SELECT *
FROM City
WHERE replace(replace(Name,'ş','s'),'ţ','t') LIKE COLLATE Latin1_general_CI_AI '%iasi%' COLLATE Latin1_general_CI_AI
You just need to change collation of name field before like operation. Check test code below
DECLARE #city TABLE ( NAME NVARCHAR(20) )
INSERT INTO #city
VALUES ( N'iaşi' )
SELECT *
FROM #city
WHERE name LIKE 'iasi'
--No return
SELECT *
FROM #city
WHERE name COLLATE Latin1_general_CI_AI LIKE '%iasi%'
--Return 1 row
This problem was haunting me for some time, until now, when I've finally figured it out.
Presuming your table or column is of SQL_Latin1_General_CP1_CI_AS collation, if you do:
update
set myCol = replace(myCol , N'ș', N's')
from MyTable
and
update
set myCol = replace(myCol,N'ț',N't')
from MyTable
the replace function will not find these characters, because the "ș" made from your keyboard (Romanian Standard keyboard) differs from the "ş" or "ţ" found in your database.
As a comparison: ţț and şș - you can see that they differ because the accents are closer to the "s" or "t" character.
Instead, you must do:
update
set myCol = replace(myCol , N'ş', N's')
from MyTable
and
update
set myCol = replace(myCol,N'ţ',N't')
from MyTable

sql server 2012 express do not understand Russian letters

I have DB which is working with Russian text however when i run queries it shows me this. Database will used by Russians and it has to show Russian text properly!
Any ideas how to fix it? In the future it will located in Russia and work with Russian version SQL Server but right now I am working on English version SQL 2012 Express.
Here is the table and insert statement:
Create table Employee
(
EmpID int not null IDENTITY (10, 1),
StrName nvarchar (25) not null,
Phone1 nvarchar (25) not null,
Phone2 nvarchar (25)
Primary Key (EmpID),
);
insert into Employee (LastName , FirstName,Phone1,Phone2)
values ('Иванов','111 111 11111','111 111 1111');
Are you sure the data has been stored in the database correctly? How do you know?
Make sure that the column has a proper collation, that it is defined as nvarchar and that inserts of string literals are prefixed with N. For example, these are not the same:
INSERT dbo.table(column) SELECT 'foo';
INSERT dbo.table(column) SELECT N'foo';
As an example:
USE tempdb;
GO
CREATE TABLE dbo.foo
(
ID INT PRIMARY KEY,
bar NVARCHAR(32) COLLATE SQL_Ukrainian_CP1251_CI_AS
);
INSERT dbo.foo SELECT 1,'АБВГДЕЖЅZЗИІКЛ';
INSERT dbo.foo SELECT 2,N'АБВГДЕЖЅZЗИІКЛ';
SELECT ID, bar FROM dbo.foo;
GO
DROP TABLE dbo.foo;
Results:
ID bar
---- --------------
1 ????????Z?????
2 АБВГДЕЖЅZЗИІКЛ
And to show how this affects your insert statement, your string is missing the N prefix:
SELECT
CONVERT(NVARCHAR(32), 'Иванов'),
CONVERT(NVARCHAR(32), N'Иванов');
Results:
------ ------
?????? Иванов
So, prefix your Unicode strings with N'a prefix' or lose data.
While Aaron Bertrand gave a good explanation why do you getting such a results, I'd say there's a way not to prefix all you strings with russian letters with 'N'.
As far as I know, you have just set your server collation properly. So if you set your collation, for example, like Cyrillic_General_CI_AS, server could treat varchar with russian letters properly:
select
'español', '平成年月日', 'иван',
serverproperty('collation')
results:
espanol ????? иван Cyrillic_General_CI_AS
As you see, spanish and Chinese strings are not treated properly while russian strings are. So you can insert data into nvarchar columns without prefixing strings with 'N'
That said, I'm using nvarchar data type in our database as default strings, nvarchar parameters in stored procedures. I very rarely use russian strings in code (only when I want to test something), and I've never used N'string' syntax.
While having correct default collation could be handy, there's problem with this solution - it's not easy to change default collation on installed SQL Server, so you have to be careful when installing SQL Server instance and choose collation properly.