ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я знаю, что этот вопрос задавали сотни раз раньше, но я просто хотел убедиться, что не было более простого решения, которое я мог бы пропустить, прежде чем я продолжу и написал / получил много кода для этого.
Наше программное обеспечение использует базу данных, которая изначально была разработана для SQL Server 7, и поэтому все сценарии, которые ее создают, не указывают явное сопоставление для каких-либо символьных столбцов. Вместо этого, когда база данных создается / восстанавливается до SQL Server 2000 или более поздней версии, каждый столбец наследует параметры сортировки базы данных (что оказывается SQL_Latin1_General_CP1_CI_AS
поскольку это был стандарт SQL Server 7 по умолчанию).
Теоретически это не имеет большого значения, поскольку, если наша база данных создается с нуля на сервере клиента, она наследует параметры сортировки сервера клиента (которые обычно являются современной установкой по умолчанию, Latin1_General_CP1_CI_AS
) и все просто работает. Однако этот сценарий не работает, когда они отправляют нам резервную копию базы данных, или мы отправляем им резервную копию базы данных, и либо мы, либо они получаем ужасную ошибку несоответствия сопоставления всякий раз, когда код пытается получить доступ к временным таблицам и т. Д.
Мы пытались научить клиентов устанавливать или перестраивать свои экземпляры SQL Server, чтобы использовать наши предпочтительные параметры сортировки, но, конечно, это не всегда происходит и не всегда возможно.
Решения, которые включают создание новой базы данных и копирование данных, для нас непрактичны, нам нужна «волшебная палочка», которой мы можем махнуть в действующей базе данных, чтобы исправить все столбцы на месте, не нарушая данных. Я подумываю написать для этого утилиту, но, поскольку это будет довольно большая работа, есть ли у кого-нибудь более простые предложения?
Один из вариантов - «защитить» код от несоответствия параметров сортировки.
Вы можете использовать специальное сопоставление «DATABASE_DEFAULT» для принуждения, не зная, что такое фактическое сопоставление. Вы используете его для столбцов типа char во временных таблицах, табличных переменных и системных таблицах, которые вам нужно использовать.
Пример:
CREATE TABLE #Currency (CCY CHAR(3))
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --error!
GO
-- in join too
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY COLLATE DATABASE_DEFAULT --no error
GO
DROP TABLE #Currency
GO
CREATE TABLE #Currency (CCY CHAR(3) COLLATE DATABASE_DEFAULT)
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --no error!
GO
DROP TABLE #Currency
GO
Это также означает, что когда ваши клиенты переносят свою БД на новый суперский сервер SQL Server с еще одним другим параметром сортировки, он тоже работает ...
Короткий ответ: нет простого пути. У меня была такая же проблема в прошлом.
Я бы сказал, что две вещи: во-первых, когда ваш клиент отправляет вам базу данных с неожиданным сопоставлением, установите новый экземпляр SQL с сопоставлением по умолчанию, которое соответствует их БД, и работайте с ним в этом.
Во-вторых, убедитесь, что ваше приложение будет работать с другими сопоставлениями, а не с параметрами по умолчанию (поскольку они могут измениться в будущем) и работать правильно, пока сопоставление на сервере SQL и БД совпадает. Тогда довольно легко попросить клиента установить SQL-сервер с сопоставлением, которое соответствует их БД, и тогда он будет работать.
Или напишите утилиту, которая обновит все таблицы и т. Д. В вашей базе данных, как вы сказали, но это может быть больше работы, чем вы хотите.
Если все столбцы в базе данных имеют одинаковую сортировку, это вызовет проблемы для вас только при выполнении запросов между базами данных (или ваше приложение чувствительно к порядку сортировки).
Проблема возникает, когда вы понимаете, что присоединение к временным таблицам осуществляется между базами данных, как и в tempdb. Это легко отсортировать - просто убедитесь, что любые текстовые столбцы во временных таблицах явно созданы с помощью COLLATE database_default
директива. Это означает, что столбец будет создан с использованием параметров сортировки по умолчанию для текущей базы данных вместо коллекции по умолчанию tempdb (которая будет такой же, как и для сервера по умолчанию).