SQL: указанный сброс недействителен

Примечание. Я ищу, почему это происходит и как это исправить, я не ищу обходного пути. Это похоже на проблему с сервером (SQL Server или Connection string).

У меня есть программа, которая связана с базой данных sql 2008 (база данных A), и у меня есть встроенный sql, который работает с возвращаемыми ints и строками, и он работает нормально. Но меня попросили переключиться на другую базу данных 2008 года (база данных B), и теперь все возвращается как строка, и я получаю задание, которое недействительно из С#, когда я подключен к sql 2008 (база данных A) не сказал этого. Это встроенный оператор sql, поэтому оператор sql не изменяется, а схема таблицы базы данных одинакова. Это делается на int primary keys. У кого-нибудь есть идеи?

Первоначально я думал, что это вопрос с 2000 по 2008 год, но теперь у меня есть проблема и с 2008 годом. Обе базы данных находятся в одном экземпляре sql-сервера, это строки подключения

Строки подключения

  Server=Server01\instance;Database=Fraud_Micah; Trusted_Connection=yes <- Server 2008 (this one does not)
  Server=Server02\instance;Database=Fraud; Trusted_Connection=yes <- Server 2008 (this one works)

Обе базы данных находятся на уровне совместимости БД, равном 100

Оператор select

select *, delimeter, file_filetype.LocalPath, ArchiveDir, EmailList
from file_importtable 
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
where importsuccessdate is null and transferdate is not null
and remotediscoverdate is not null 
and OriginalFileName in ('Test987.xml.pgp')

fileTypeID, где его разрыв → InvalidCastException: Specified cast is not valid.

Код С# (Note reader - тип SQLDataReader)

if (!(reader.IsDBNull(reader.GetOrdinal("FileTypeID"))))
{
    file.FileTypeID = reader.GetInt32(reader.GetOrdinal("FileTypeID"));
}

Вот определение столбца: [FileTypeID] [int] NULL, в таблице нет нулевых значений.

Я не думаю, что код С# исходит из этого, его int? public int? FileTypeID { get; set; }

В режиме отладки: reader["FileTypeID"] → "1" это на самом деле строка, но почему, когда я подключаюсь к базе данных 2008 года, она вернет 1 instaed из "1"

2008 Таблица A Def

[ProcessSuccessDate] [datetime] NULL,
[ProcessSuccessUser] [datetime] NULL,
[FileTypeID] [int] NULL,
[HoldDate] [datetime] NULL,

2008 Таблица B Def

ProcessSuccessDate] [datetime] NULL,
[ProcessSuccessUser] [datetime] NULL,
[FileTypeID] [int] NULL,
[HoldDate] [datetime] NULL,

file.FileTypeID = (int)reader["FileTypeID"]; дает тот же результат.

Выполнение

     file.FileTypeID (int)reader.GetInt32(reader.GetOrdinal("FileTypeID"));

работает, но я не хочу этого делать для каждого столбца, который уже должен возвращаться как int, также записывающий sql, как этот

     select Convert(int, FileTypeID) as FileTypeId, delimeter, file_filetype.LocalPath, ArchiveDir, EmailList

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

Ответ 1

В схеме вещей я решил удалить таблицу и воссоздать ее с помощью

[script table as] → [create]

из той же таблицы, которая давала мне проблемы, а затем повторно вставляла все те же данные. Это решило проблему. Поэтому я не считаю, что DML таблицы изменился, и данные не изменились, но это то, что разрешило мою проблему.

Ответ 2

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

Я считаю, что таблица OTHER, в которой вы JOIN, имеет другой тип данных в одной базе данных.

Каков тип данных File_fileType.Id в обеих БД?

Ваш JOIN:

join file_filetype on file_importtable.FileTypeID = file_filetype.ID

Вызывает неявное преобразование.

enter image description here

В приведенной выше диаграмме показано, как SQL Server разрешает или выполняет преобразования типа данных.

Можете ли вы показать DDL для обеих версий обеих таблиц в приведенном выше JOIN?

Ответ 3

Мне кажется, что есть какая-то странная настройка конфигурации, которую трудно найти. Существует инструмент, который называется Redgate SQL Compare, который выполняет удивительное задание при обнаружении различий между схемами базы данных.

У них 14-дневная пробная версия. Я бы попытался загрузить его и выполнить сравнение между вашими базами данных.

Ответ 4

Соответствует ли сортировка SQL? Если вы испытываете различное поведение между базами данных, это может быть вашей проблемой. Щелкните правой кнопкой мыши по каждой базе данных и выберите свойства, сопоставление должно быть указано как что-то вроде * Latin1_General_CI_AS * Если они разные, определенно что-то исключить.

Ответ 5

Вам нужно будет вывести из строки.

file.FileTypeID = int.Parse((string)reader["FileTypeID"]);

EDIT: если вы хотите обходной путь, который должен работать для SQL Server 2000 и 2000

file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]);

Ответ 6

Visual studio (версия Premium и Ultimate в соответствии с this) поставляется с инструментом сравнения базы данных - вы выбираете две базы данных, она показывает вам diff и дает вам набор сценариев, которые перемещают один в состояние другого. Начните с нее и попробуйте переопределить конфигурацию, которая отличается (как я ожидаю, это проблема конфигурации). Проверьте Сравнение данных\Схемы и Data\Data Compare в Visual Studio.

Ответ 7

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

Первая проверка должна быть в обеих базах данных с использованием INFORMATION_SCHEMA.COLUMNS(этого более чем достаточно для требуемого уровня), чтобы убедиться, что схемы идентичны. Вы можете узнать больше о INFORMATION_SCHEMA.COLUMNS на http://msdn.microsoft.com/en-us/library/aa933218(v=sql.80).aspx (SQL 2000) или http://msdn.microsoft.com/en-us/library/ms188348 (SQL 2008). Та же информация из разных источников.

Пример:

SELECT * FROM INFORMATION_SCHEMA.COLUMNS;

Если схемы идентичны, тогда может быть ошибка в коде, который не отображается в представленных вами частях. Для того, чтобы все было правильно с полным кодом, выполните простую проверку, изменив инструкцию select следующим образом:

select CAST(fileTypeID as int), ..., file_filetype.LocalPath, ArchiveDir, EmailList
from file_importtable 
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
where importsuccessdate is null and transferdate is not null
and remotediscoverdate is not null 
and OriginalFileName in ('Test987.xml.pgp')

Если это не удается, запустите в режиме отладки пошаговый тест, используя точку останова и F11. (Иногда возвращение к корням может помочь нам увидеть то, что невидимо перед нашими глазами - в этом случае маловероятно).

Следуя приведенному выше, вы найдете причину (надеюсь).

Последний совет (который может быть первым шагом перед тем, как делать что-либо еще): убедитесь, что ваши серверы sql исправлены с последними пакетами обновлений.

Ответ 8

Увидев, что вы не решили это, попробуйте вместо этого метод GetSqlInt32.

file.FileTypeID = reader.GetSqlInt32((fieldTypeIDOrdinal).ToNullableInt32();

Примечание Я не включил проверку IsDBNull, так как сочетание SqlInt32 с ToNullableInt32 справляется с этим.

Где ToNullableInt32 - метод расширения.

public static int? ToNullableInt32(this SqlInt32 value)
{
    return value.IsNull ? (int?) null : value.Value;
}

В качестве дополнительной заметки вы упомянули, что это приложение с приоритетом производительности, и в этом случае вам может потребоваться прекомпопировать ваши порядковые значения, а не иметь этот reader.GetOrdinal("FileTypeID") каждый цикл вашего reader.Read()

Ответ 9

file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]); вместо file.FileTypeID = (int)reader["FileTypeID"];