У меня странная проблема: при выполнении агрегатной функции в столбце varchar типа cast я получаю «Msg 8114, уровень 16, состояние 5, строка 1. Ошибка преобразования типа данных nvarchar в bigint». Запросы, где предложение должно отфильтровывать нечисловые значения.MSSQL aggregate игнорирует where where
Структура таблицы аналогична следующим образом:
IF EXISTS (SELECT * FROM sys.all_objects ao WHERE ao.name = 'Identifier' AND ao.type = 'U') BEGIN DROP TABLE Identifier END
IF EXISTS (SELECT * FROM sys.all_objects ao WHERE ao.name = 'IdentifierType' AND ao.type = 'U') BEGIN DROP TABLE IdentifierType END
CREATE TABLE IdentifierType
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Style] [int] NULL,
CONSTRAINT [PK_IdentifierType_ID] PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY]
CREATE TABLE Identifier
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[IdentifierTypeID] [int] NOT NULL,
[Value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_Identifier_ID] PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY]
ALTER TABLE Identifier WITH CHECK ADD CONSTRAINT [FK_Identifier_IdentifierTypeID] FOREIGN KEY([IdentifierTypeID]) REFERENCES IdentifierType ([ID])
GO
Identifier.Value представляет собой столбец VARCHAR, она может и действительно содержит не-числовых данных. Фильтрация запроса в IdentifierType.Style = 0 должна означать, что 'Value' возвращает только строковые представления целых чисел. Ниже приведен запрос с ошибкой «Msg 8114, уровень 16, состояние 5, строка 1. Ошибка преобразования типа данных nvarchar в bigint».
SELECT
MAX(CAST(Value AS BIGINT))
FROM
Identifier i,
IdentifierType it
WHERE
i.IdentifierTypeID = it.ID AND
it.Style = 0
Если я продлить статью, где включить «И IsNumeric (i.Value) = 1» он возвращает максимальное целое значение. Это означает, что в моем результирующем наборе есть нечисловая строка. Тем не менее, я не получаю строк, возвращаемые из этого:
SELECT
*
FROM
Identifier i,
IdentifierType it
WHERE
i.IdentifierTypeID = it.ID AND
it.Style = 0 AND
ISNUMERIC(i.Value) <> 1
Я был не в состоянии идентичности строки (s), которые расцепление типа броска. Вышеприведенный запрос должен был раскрывать исключительные строки. Кроме того, нет ни пустых, ни чрезвычайно длинных строк (наибольшая строка имеет длину 6 символов)
Возможно ли, что MSSQL пытается выполнить CAST на всех строках, а не сначала фильтровать с помощью предложения WHERE?
Или кто-нибудь еще видел что-то подобное?
Существует вторая работа, которая создает экземпляр компонента запроса во временную таблицу, а затем выбирает значение MAX из этого.
SELECT
Value
INTO
IdentifierClone
FROM
Identifier i,
IdentifierType it
WHERE
i.IdentifierTypeID = it.ID AND
it.Style = 0
SELECT MAX(CAST(Value as BIGINT)) FROM IdentifierClone
Подзапрос не работает, однако.
Любая помощь или мысли будут оценены.
См [SQL Server не должен вызывать нелогичные ошибки] (https://connect.microsoft.com/SQLServer/feedback/details/537419/ sql-server-should-not-raise-notogical-errors) на сайте обратной связи Connect. SQL Server иногда перескакивает вперед и выполняет более ранние преобразования, которые вызывают ошибки, которые не будут, если бы он фактически обработал запрос в правильном логическом порядке. –
У меня была аналогичная проблема с isnumeric, пытаясь найти не числовые значения и не получить ожидаемый результат из-за самого isnumeric. Если это проблема заказа, попробуйте организовать с помощью подтаблицы, чтобы убедиться, что это лучше, сделайте предложение where в подтаблице, а затем сделайте свою актерскую съемку. Вы уверены, что он отфильтрован до этого. –
@MatheseF - если вы ссылаетесь на подзапрос, вы ошибаетесь в том, что «уверен, что он был отфильтрован до» - оптимизатор может и * будет * перегруппировать преобразования и фильтровать даже с подзапросами и все равно может произвести эти нелогичные ошибки. Единственный верный способ, который я знаю, чтобы предотвратить это, состоит в том, чтобы разделить запрос на два полностью отдельных запроса и первым запросом заполнить переменную temp table/table, которую затем выполняет второй запрос. –