Данные не фильтруются перед объединением - PullRequest
2 голосов
/ 04 декабря 2008

Головоломка от коллеги, которую я не могу понять ...

update  btd.dbo.tblpayroll
set     empname = ( select  b.Legal_Name
                    from    ( SELECT    Legal_Name,
                                        Employee_ID
                              FROM      Com.dbo.Workers
                              WHERE     isnumeric(Employee_ID) = 1
                            ) b
                    where   b.Employee_ID = empnum
                            and b.Legal_name is not NULL
                  )
where   empname is NULL

Сообщение 245, Уровень 16, Состояние 1, Строка 1 Ошибка преобразования при преобразовании значения varchar 'N0007' в тип данных int. Псевдоним таблицы b фактически будет представлением.

Значение «N0007» находится в таблице «Рабочие». Я не понимаю, почему это не фильтруется из результатов, которые объединяются.

EDIT:

Псевдоним действительно возвращает правильные строки, поэтому isNumeric выполняет свою работу.

Ответы [ 4 ]

2 голосов
/ 04 декабря 2008

Я подозреваю, что оптимизатор пытается применить условие where внешнего выбора перед внутренним выбором. Предположительно он думает, что сможет выполнить поиск индекса Employee_ID, что приведет к более быстрому запросу в этом случае. Попробуйте:

update  btd.dbo.tblpayroll
set     empname = ( select Legal_Name
                    from Com.dbo.Workers
                    where  isnumeric(Employee_ID) = 1
                           and convert(varchar,Employee_ID)
                             = convert(varchar,empnum) 
                           and Legal_name is not NULL)
where   empname is NULL

Преобразование их всех в varchar должно позаботиться об этом. Я не думаю, что он намного менее эффективен, чем вы изначально хотели, поскольку числовое значение, если бы оно было сделано первым, в любом случае вызвало бы сканирование таблицы.

0 голосов
/ 05 декабря 2008

Очевидная вещь состоит в том, чтобы принудительно упорядочить порядок сравнения, возможно, получая тогда имя из представления с только числовыми идентификаторами Employee_ID, а не полной таблицей Workers.

0 голосов
/ 04 декабря 2008

ISNUMERIC() совершенно ненадежен в том, что вы пытаетесь сделать. Вам понадобится альтернатива, которую я просил здесь как этот .

0 голосов
/ 04 декабря 2008

Может N считается символом валюты? Вы можете попробовать заменить IsNumeric на

LIKE REPLICATE('[0-9]',/*length of Employee_ID*/) 

или просто

LIKE '[0-9]%' 

если буква не может быть посередине

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...