Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Есть таблица, в которой хранятся имена людей.
Нужно выводить их на VB ASP.NET страницу в результате поиска.
Страница кодирует '%' если в поле ничего не выбрано и это просили не менять. Нужно просто сменить запрос в странице на вызов хранимой процедуры, которую я и должен написать.

Если сделать выборку

SELECT * FROM emp WHERE name LIKE LTRIM(RTRIM('Name1'))


то получаем скажем от 1 до N записей людей с этим именем.
Но есть в базе имена, при использовании которых не возвращается ни одной записи, хотя при запросе

SELECT * FROM emp WHERE name LIKE '%Name2%'


возвращается праильное число записей. Что это за имена такие?
На вид ничего особенного - ни символов с акцентами, ничего лишнего.
Скажем 'Tavares' или 'Garner' не работает, а 'Abushaqra', 'Noel' или 'McDowell' работают.

По понятным причинам я не могу добавлять по обеим сторонам имени еще по одному %.
Придется делать условие, проверять параметры на равенство '%' и исправлять их или есть какое-то объяснение?
Единственное чем необычна эта база, это тем, что ее импортировали из MS Access при помощи SSIS data transfer компонентов в MS SQL 2008 R2.

Примеры:

SELECT NAME FROM EMP WHERE  NAME LIKE 'Tavares'
SELECT NAME FROM EMP WHERE  NAME LIKE 'Garner'
SELECT NAME FROM EMP WHERE  NAME LIKE 'Noel'
SELECT NAME FROM EMP WHERE  NAME LIKE 'McDowell'

NAME
----------------------------------------

(0 row(s) affected)

NAME
----------------------------------------

(0 row(s) affected)

NAME
----------------------------------------
Noel
Noel
Noel

(3 row(s) affected)

NAME
----------------------------------------
McDowell

(1 row(s) affected)



SELECT NAME FROM EMP WHERE  NAME LIKE '%Tavares%'
SELECT NAME FROM EMP WHERE  NAME LIKE '%Garner%'

NAME
----------------------------------------
Tavares 

(1 row(s) affected)

NAME
----------------------------------------
Garner 

(1 row(s) affected)
20 сен 13, 01:42    [14862058]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
Gobzo Kobler
то получаем скажем от 1 до N записей людей с этим именем.
Но есть в базе имена, при использовании которых не возвращается ни одной записи, хотя при запросе
SELECT * FROM emp WHERE name LIKE '%Name2%'

возвращается праильное число записей. Что это за имена такие?
Скорее всего в ваших "необычных именах" просто стоят концевые пробелы. К тому же, Вы сами зачем-то их обрезаете в условии с помощью LTRIM(RTRIM. Чудес не бывает. Проверьте, есть ли там пробелы, и если их нет, то тогда приведите здесь тип данных этого поля и коллэйшен.
Gobzo Kobler
По понятным причинам я не могу добавлять по обеим сторонам имени еще по одному %.
Мне эти причины совсем не понятны. Если Вы боитесь, что будут выводиться записи с '%', то это не так:
declare @t table(p varchar(100))

insert into @t values ('Tavares'),('%')

select p
from @t
where p like '%Tavares%' 
20 сен 13, 04:40    [14862119]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Это было бы слишком просто.

select *
from EMP
where NAME <> LTRIM(RTRIM(NAME))

NAME
----------------------------------------

(0 row(s) affected)
20 сен 13, 18:16    [14865427]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
А вот это уже интересно:

select NAME, DATALENGTH(NAME) AS dl_s, DATALENGTH(LTRIM(RTRIM(NAME))) AS dl_t
from EMP
where DATALENGTH(NAME) <> DATALENGTH(LTRIM(RTRIM(NAME))) AND NAME IN ('Garner', 'Tavares')
ORDER BY NAME

ED_SURNAME                               dl_s        dl_t
---------------------------------------- ----------- -----------
Garner                                   14          12
Tavares                                  16          14

(2 row(s) affected)
20 сен 13, 18:21    [14865437]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31962
Gobzo Kobler
Придется делать условие, проверять параметры на равенство '%' и исправлять их или есть какое-то объяснение?
SELECT '*' + NAME + '*' FROM EMP WHERE  NAME LIKE 'Tavares'
20 сен 13, 18:25    [14865451]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31962
alexeyvg
Gobzo Kobler
Придется делать условие, проверять параметры на равенство '%' и исправлять их или есть какое-то объяснение?
SELECT '*' + NAME + '*' FROM EMP WHERE  NAME LIKE 'Tavares'
То есть конечно LIKE '%Tavares%', а не LIKE 'Tavares'
20 сен 13, 18:26    [14865455]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Gobzo Kobler
Это было бы слишком просто.

select *
from EMP
where NAME <> LTRIM(RTRIM(NAME))

NAME
----------------------------------------

(0 row(s) affected)

В SQL Server две строки считаются равными, если они отличаются только наличием/количеством конечных пробелов. К сравнению по LIKE это не относится.

IF 'test' = 'test   '
   PRINT 'Они равны!'
ELSE
   PRINT 'Не равны!';

IF 'test' LIKE 'test   '
   PRINT 'Они LIKE!'
ELSE
   PRINT 'Они не LIKE!';

IF 'test   ' LIKE 'test'
   PRINT 'Они LIKE!'
ELSE
   PRINT 'Они не LIKE!';


Gobzo Kobler
DATALENGTH

Функция DATALENGTH возвращает длину строки (в байтах) с учётом конечных пробелов. В отличие от функции LEN, которая конечные пробелы не учитывает.
20 сен 13, 18:29    [14865470]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Ruuu
Скорее всего в ваших "необычных именах" просто стоят концевые пробелы. К тому же, Вы сами зачем-то их обрезаете в условии с помощью LTRIM(RTRIM. Чудес не бывает. Проверьте, есть ли там пробелы, и если их нет, то тогда приведите здесь тип данных этого поля и коллэйшен.


Обрезать ввод необходимо - это пользовательский ввод в поля поиска, а не значения из базы.
А ведь Вы правы. Это именно концевые пробелы, которые не проявляются при выводе и в условиях = но проявляются в Like.

select NAME, DATALENGTH(NAME) AS dl_s, DATALENGTH(LTRIM(RTRIM(NAME))) AS dl_t
from EMP
where RIGHT(NAME, 1) = ' ' AND NAME IN ('Garner', 'Tavares')
ORDER BY NAME

ED_SURNAME                               dl_s        dl_t
---------------------------------------- ----------- -----------
Garner                                   14          12
Tavares                                  16          14

(2 row(s) affected)


Впервые сталкиваюсь с таким. Это штучки 2008 сервера?
20 сен 13, 18:31    [14865476]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Gobzo Kobler
Это штучки 2008 сервера?

Это стандартное поведение как минимум с 2000 версии (с более старыми не доводилось работать).
20 сен 13, 18:35    [14865484]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31962
Гость333
Gobzo Kobler
Это штучки 2008 сервера?

Это стандартное поведение как минимум с 2000 версии (с более старыми не доводилось работать).
В более старых так же.
Это унаследованно от сайбеса.
20 сен 13, 18:37    [14865493]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Всем большое спасибо за refresher.
Клиент разрешил добавить % после критерия Like. Это все решает.
20 сен 13, 18:41    [14865508]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Gobzo Kobler,

Кстати, судя по результатам DATALENGTH, у вас столбцы типа nvarchar. А для этого типа данных поведение LIKE отличается от varchar:
IF 'test   ' LIKE 'test'
   PRINT 'varchar LIKE!'
ELSE
   PRINT 'varchar NOT LIKE!';

IF N'test   ' LIKE N'test'
   PRINT 'nvarchar LIKE!'
ELSE
   PRINT 'nvarchar NOT LIKE!';

----
varchar LIKE!
nvarchar NOT LIKE!
20 сен 13, 18:41    [14865513]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Gobzo Kobler
Member

Откуда: у людей такая фантазия?
Сообщений: 387
Гость333
Gobzo Kobler,

Кстати, судя по результатам DATALENGTH, у вас столбцы типа nvarchar. А для этого типа данных поведение LIKE отличается от varchar:


В точку! Это NVARCHAR, а в исходной базе откуда слили Access - VARCHAR.
21 сен 13, 01:03    [14866508]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
Gobzo Kobler
В точку! Это NVARCHAR, а в исходной базе откуда слили Access - VARCHAR.
Если вам не нужен UNICODE, то сделайте ALTER COLUMN на VARCHAR, тогда значения в поле будут занимать в два раза меньше места.
21 сен 13, 07:48    [14866659]     Ответить | Цитировать Сообщить модератору
 Re: Like, находящий почти все строки, но не все  [new]
qwerty112
Guest
Gobzo Kobler
В точку! Это NVARCHAR, а в исходной базе откуда слили Access - VARCHAR.

VARCHAR в Акцессе (если это >A97) - юникодовый, т.е. и есть аналог МС СКЛ-ного NVARCHAR
так что, из этого "открытия" - нет никаких следствий
21 сен 13, 11:22    [14866840]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить