Странная проблема преобразования типов в SQL Server - PullRequest
1 голос
/ 01 августа 2011

У меня сегодня странная проблема. Один из моих проектов работает под управлением .NET + SQL Server 2005 Express. Есть один запрос, который я использую для некоторой фильтрации.

SELECT *
  FROM [myTable]
  where UI = 2011040773395012950010370
GO

SELECT *
  FROM [myTable]
  where UI = '2011040773395012950010370'
GO

Столбец пользовательского интерфейса равен nvarchar(256), а значение пользовательского интерфейса, переданное в фильтр, всегда составляет 25 цифр.

В моей среде DEV - оба запроса возвращают одну и ту же строку и не содержат ошибок. Однако после нескольких месяцев работы у моих клиентов первая версия начала возвращать ошибку преобразования типов.

Есть идеи почему?

Я не ищу решения - Я ищу объяснение, почему в одной среде это работает, а в другой - нет, и почему внезапно оно начало возвращать ошибки вместо результатов . Я использую одни и те же инструменты на обоих (SQL Server Management Studio Express и 2 разных клиента .NET)

Среды более или менее одинаковы (W2k3 + SQL Server 2005 Express)

1 Ответ

5 голосов
/ 01 августа 2011

Это полностью предсказуемо и ожидаемо из-за приоритета типа данных

. Для этого столбец пользовательского интерфейса изменится на десятичный (25,0)

where UI = 2011040773395012950010370

Это почти правильно.Правая часть - varchar и заменяется на nvarchar

where UI = '2011040773395012950010370'

Это правильная версия действительно , в которой оба типа совпадают

where UI = N'2011040773395012950010370'

Ошибки будут иметьначал, потому что столбец пользовательского интерфейса теперь содержит значение, которое не будет CAST до десятичного (25,0).

Некоторые несвязанные заметки:

  • , если у вас есть индекс на столбец пользовательского интерфейсаэто будет проигнорировано в первой версии из-за неявного CAST, необходимого
  • Вам нужен Unicode для хранения числовых цифр?Существует серьезных накладных расходов с типами данных Юникода в хранилище и производительности
  • , почему бы не использовать char(25) или nchar(25), если значения всегда имеют фиксированную длину?В ваших запросах используется слишком много памяти, поскольку оптимизатор предполагает среднюю длину 128 символов на основе nvarchar(256)

Правка после комментария

Не предполагать«почему это работает иногда», когда вы не знаете , что это работает

Примеры:

  • Значение могло быть удалено, а затем добавлено позже
  • Предложение TOP или SET ROWCOUNT может означать, что неверное значение не достигнуто
  • Запрос никогда не выполнялся, поэтому он не мог завершиться
  • Ошибка игнорируется некоторыми другими пользователями.код?

Изменить 2 для большей ясности

Чат

gbn:

Когда вы запускаете WHERE UI= 2011040773395012950010370, вы не знаете порядок доступа к строкам.Поэтому, если в одном ряду есть «велосипед», вы можете или не можете попасть в этот ряд.

Случайно:

Так что проблема может быть не в том ряду, в котором я былпытаться получить доступ, но к другому с поврежденным значением?

gbn

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

правильный

и даже четные.Такого рода вещи

Как Дао упоминает , важно понимать, что другой не связанный может нарушить запрос, даже если с этим все в порядке.

Приоритет типа данных может привести к преобразованию ВСЕХ данных в этом столбце до вычисления предложения where

...