2016-12-08 2 views
1

Я даже не думал о том, как записать это название. Это SQL Server 2005SSMS 2005 - Не сглаженная колонка, возвращающая разные результаты

Если я делаю тот же запрос с псевдонимом в столбце, а без него, я получаю совершенно разные результаты. Это не двусмысленно.

Пример запроса:

UPDATE MyTable 
SET  Col1 = Col1 - 1 
FROM DB.dbo.MyTable M 
WHERE EXISTS (SELECT * 
       FROM DB.dbo.SecondTable B WITH (NOLOCK) 
       WHERE B.Col2 = 12345678 
         AND B.Col3 = 1 
         AND B.M-FK = M.M-PK) 
     AND M.Col1 > 0 
     AND M.Col4 = 87654321; 

Этот запрос я предполагал, все к столу сразу, и я получаю значительную отдачу.

Очень похожий запрос, но я не указываю таблица

UPDATE MyTable 
SET  Col1 = Col1 - 1 
FROM DB.dbo.MyTable M 
WHERE EXISTS (SELECT * 
       FROM DB.dbo.SecondTable B WITH (NOLOCK) 
       WHERE Col2 = 12345678 
         AND Col3 = 1 
         AND B.M-FK = M.M-PK) 
     AND Col1 > 0 
     AND Col4 = 87654321; 

2-й запрос возвращает 1.

только взаимная колонка между это B-ForeignKey => M.PrimaryKey

По моему опыту, я всегда назначал столбцы псевдониму, но когда кто-то задал мне вышеуказанный вопрос раньше, я был совершенно сбит с толку. Если бы они были неоднозначными, SSMS отверг бы это. Тем не менее, он действительно побежал.

Поэтому я подумал, что «возможно» он игнорирует эти столбцы - что странно. , но второй возвращает -1-строку, что добавляет больше путаницы.

Может ли кто-нибудь объяснить, почему изменяется запрос псевдонима или без псевдонима? И почему это вообще заканчивается, если это ошибка?

ответ

1

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

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

UPDATE m 
SET  m.Col1 = m.Col1 - 1 
FROM dbo.MyTable AS m 
WHERE EXISTS (SELECT * 
       FROM dbo.SecondTable AS b WITH (NOLOCK) 
       WHERE b.Col2 = 12345678 
         AND b.Col3 = 1 
         AND b.M-FK = m.M-PK) 
     AND m.Col1 > 0 
     AND m.Col4 = 87654321; 

AS oppossed к ...

UPDATE dbo.MyTable 
SET  Col1 = Col1 - 1 
WHERE EXISTS (SELECT * 
       FROM dbo.SecondTable AS b WITH (NOLOCK) 
       WHERE b.Col2 = 12345678 
         AND b.Col3 = 1 
         AND b.M-FK = M-PK) 
     AND Col1 > 0 
     AND Col4 = 87654321; 

Проблема с Вторая версия SQL может запутаться между двумя таблицами, если две таблицы имеют одно или несколько одинаковых определений столбцов. На самом деле он может даже не работать из-за этих ошибок! Поэтому почему с Aliasing я знаю, к какой таблице я обращаюсь, и он обновляет только столбцы и таблицу, которые я хочу.

Вот подсказка:

Придумайте UPDATE как «чайник горшок крышкой», где благость «горшка» (ЗЕЬЕСТ) находится внутри горшка!

т.е.

UPDATE a 
SET a.col1 = @value1, a.col2 = @value2, etc 
FROM dbo.myTable1 AS a 
    INNER JOIN dbo.myTable2 as b ON b.col3 = a.col3 
    INNER JOIN ...etc.. 
WHERE ..etc.. 

Обратите внимание, что из ЕКА это так же, как SELECT. И вам не нужно ОБНОВИТЬ первую таблицу в своем запросе. Вы можете ОБНОВИТЬ b или UPDATE c и т. Д., Не затрагивая логику в предложении FROM запроса.

Итак, мой совет - написать запрос SELECT, чтобы сначала получить нужные данные, заставить его работать, а затем заменить SELECT на UPDATE & SET в зависимости от того, какие столбцы вы хотите изменить. Таким образом, я никогда не смущаюсь с точки зрения данных, которые я меняю.

Мне удалось создать массовые инструкции UPDATE SQL таким образом и заставить их работать почти в первый раз.

Приветствия

+1

Хорошее объяснение. Я всегда придерживаюсь псевдонима, это был мой сотрудник, который задал мне этот вопрос, когда он сравнивал свой сценарий с моим и разницу в результатах. Не имея реального ответа для него, и мы оба просто «принимаем» SQL игнорировали его WHERE из-за столбцов, не имеющих конкретной таблицы, но я все еще пытался выяснить «точный» ответ. Похоже, что SSMS игнорирует эти поля. По-прежнему не знаю, как его запрос получил хотя бы один результат, но да. Я согласен с вашим ответом. – DNorthrup

+0

Спасибо за комментарий. Если бы вы могли проголосовать за мой ответ, это также было бы оценено @DNorthrup – Fandango68

0

Если какая-либо ссылка на столбцы была неоднозначной, вы получили бы ошибку. Эти запросы выглядят одинаково для меня, но предикат Col1 > 0 потенциально отфильтровывает разные строки после каждого выполнения, так как вы уменьшаете его. Кроме того, B.M-FK Я предполагаю, что это артефакт вашей обфускации, поскольку это будет интерпретировано как B.M - B.FK. Я предполагаю, что вы имеете в виду что-то вроде B.[M-FK] или B.M_FK.

Я также вижу (NOLOCK). Если данные находятся в потоке в B, которые могут внести свой вклад.

+0

Эй Бен, они точно так же для 3 строки не ссылки на таблицу alias'd исключением. Я использовал имена заполнителей в моих предыдущих запросах. Это не настоящие имена. B.M-FK означает B. [B] -ограниченный ключ, а M.M-PK означает M. [M] -прим. Ключ. Просто ссылаясь на то, что будет отражать UID. – DNorthrup

Смежные вопросы