Как преодолеть разрыв

Однако, как это нередко бывает при обновлении программных продуктов, ради расширения возможностей пришлось пожертвовать некоторыми аспектами совместимости. В этой статье речь пойдет о внутренних особенностях реализации SQL Server, способных вызвать проблемы с преемственностью. Кроме того, мы подробно рассмотрим несколько ситуаций, в которые могут попасть разработчики при модернизации приложений.

К чему все эти перемены?

От каждого нового выпуска программного продукта пользователи всегда ждут каких-либо изменений. Версия SQL Server 7.0 оправдала эти ожидания полностью. По своей внутренней структуре SQL Server 7.0 является совершенно новым продуктом. Почему же вдруг произошли такие коренные перемены? Говоря попросту, в версии 6.5 архитектурная и программная основы достигли своих пределов. Добиться желанной проектной цели, реализовать ряд новых возможностей создаваемого продукта и при этом сохранить перспективы дальнейшего развития SQL Server, было возможно, лишь полностью переделав все его внутреннее устройство. За счет такого подхода разработчики сумели не только повысить эффективность оптимизатора запросов, добавив в него новые алгоритмы, но и добиться большего соответствия стандарту ANSI, введя новые конструкции языка Transact SQL (T-SQL). Именно эти два новшества могут послужить источниками конфликтов преемственности при переходе к версии SQL Server 7.0.

Давайте подробно разберем некоторые нововведения SQL Server 7.0 и попробуем понять, как они могут повлиять на преемственность. Рассмотрим три категории вопросов: совместимость на уровне системы, синтаксическая преемственность и аспекты поведения.

Совместимость на системном уровне

Понимая, насколько важна для клиентов преемственность версий продукта, в последнем выпуске SQL Server разработчики ввели концепцию уровней совместимости. В SQL Server 7.0 реализованы три уровня совместимости: 60 — для баз данных, использующих SQL Server 6.0; 65 — для SQL Server 6.5; и 70 — для баз данных под управлением SQL Server 7.0. Эти уровни позволяют наследуемым базам данных работать в среде 7.0 так, как если бы они управлялись более ранними версиями продукта.

Хранимая системная процедура sp_dbcmptlevel дает разработчикам возможность выяснять и изменять уровень совместимости их баз данных. К примеру, для того чтобы присвоить уровню совместимости базы данных Northwind значение 65, требуется выполнить следующую команду:

sp_dbcmptlevel [Northwind], 65

В SQL Server 7.0 база данных Master должна всегда иметь уровень совместимости, равный 70. Если в нее добавлены какие-либо объекты, определенные пользователем, необходимо провести тестирование и убедиться, что они корректно работают на уровне 70. Но другие пользовательские базы данных можно отнести к уровням совместимости 65 и 60. Подобная функциональность позволяет разработчикам провести миграцию существующих баз данных в среду SQL Server 7.0 поэтапно. Например, среда разработки может поддерживать один новый проект, использующий SQL Server 7.0, и одновременно два старых проекта, один из которых функционирует на уровне совместимости 65, а другой — на уровне 60.

Для баз данных, имеющих уровни совместимости 60 и 65, многие новые возможности SQL Server 7.0 остаются недоступными. Более того, хотя SQL Server 7.0 все еще поддерживает работу подобных унаследованных баз данных, в последующих версиях продукта такой возможности, скорее всего, уже не будет. В связи с этим мы настоятельно рекомендуем перевести все приложения и базы данных на уровень 70 как можно скорее.

Системные таблицы и представления информационной схемы. В Microsoft всегда косо смотрели на разработчиков, которые обращались непосредственно к внутренним системным таблицам SQL Server. В документации, сопровождающей каждую версию SQL Server, пользователей предупреждают о том, что к системным таблицам надлежит обращаться только через какой-либо из специально созданных интерфейсов: системные хранимые процедуры, распределенные объекты управления SQL (SQL-DMO) или T-SQL. Смысл этого предупреждения заключается в том, что формат системных таблиц зависит от внутренней архитектуры SQL Server и может меняться от одной версии к другой. Однако, поскольку до версии SQL Server 7.0 специалисты Microsoft вводили незначительные изменения в системные таблицы, многие разработчики встроили эти таблицы в свои приложения.

Разработчики, не внявшие предупреждению Microsoft, рискуют однажды утром проснуться в холодном поту. Структуры многих системных таблиц претерпели существенные изменения. Помимо всего прочего, формат, в котором SQL Server хранит данные, — это непосредственно Unicode; следовательно, системные метаданные теперь используют новый формат данных Unicode. К примеру, все идентификаторы SQL Server 7.0 относятся к типу nvarchar(128). Во время бета-тестирования именно изменения системных таблиц вызвали больше всего проблем с обновлением приложений. Для обеспечения частичной совместимости SQL Server 7.0 предлагает на системном уровне представления, имитирующие системные таблицы версий 6.х. Несмотря на то что эти представления существуют на всех уровнях совместимости, они призваны всего лишь обеспечивать преемственность и поэтому не поддерживают многие новые возможности версии 7.0.

Манипулирование метаданными в SQL Server 7.0, как и ранее, осуществляется с помощью либо системных хранимых процедур, либо SQL. Помимо этих двух методов доступа SQL Server теперь поддерживает определение информационной схемы SQL-92. Информационная схема содержит последовательность представлений, доступных только для чтения, которые обеспечивают внутренний, не зависящий от системных таблиц интерфейс к метаданным SQL Server. Разработчики, которым необходимо обеспечить доступ к системной информации и переносимость баз данных, теперь могут применять эти представления вместо системных таблиц.

Синтаксическая совместимость

Множество изменений синтаксиса, введенных в версии 7.0 (например, появление нового ключевого слова ТОР, увеличение размеров типов данных и длины наименований объектов), затрагивает и добавление новых свойств. К счастью, эти изменения не оказывают сильного влияния на стратегию миграции. Однако о некоторых из них стоит упомянуть.

Оператор UPDATE и псевдонимы

Одно из существенных отличий SQL Server 7.0 от 6.5 состоит в использовании псевдонимов в операторе UPDATE. В том случае, когда оборот FROM содержит псевдоним, а оборот SET ссылается на него, в версии SQL Server 7.0 не разрешается ссылаться на имя таблицы в обороте UPDATE. Вместо этого в обороте UPDATE должен использоваться тот же самый псевдоним. В качестве примера в Листинге 1 приведен оператор SQL, который работает в версии SQL Server 6.5.

Листинг 1. Оператор UPDATE, который не будет работать с версией SQL Server 7.0.

use pubs
go
UPDATE Titles
	SET t.Price = t.Price + 100
— References the alias
	FROM Titles t
go
Но если запустить этот оператор в версии SQL Server 7.0, то компилятор выдаст сообщение об ошибке. В Листинге 2 приведен синтаксис аналогичного оператора, который будет работать при запуске как в среде SQL Server 6.5, так и в среде SQL Server 7.0.

Листинг 2. Оператор UPDATE, который будет работать как с версией SQL Server 6.5, так и с версией SQL Server 7.0.

use pubs
go

UPDATE t
	SET t.Price = t.Price + 100  
— References the alias.
	FROM Titles t
go


Можно также применить 
следующий оператор

UPDATE Titles
	SET Price = Price + 100     
 — The alias is not referenced.
	FROM Titles t
go

Внешние ключи

Типы данных в столбцах, используемых в качестве внешних ключей, должны быть одинаковыми в разных таблицах. До версии SQL Server 7.0 это требование распространялось только на числовые столбцы, в то время как для символьных ключевых столбцов возможны были комбинации типов char и varchar. В Листинге 3 приведен пример объявления внешнего ключа, который считается вполне корректным в версии SQL Server 6.5, но не может применяться в версии SQL Server 7.0 (если только база данных не функционирует на уровне совместимости 65).

Листинг 3. Определение внешнего ключа, которое не работает в версии SQL Server 7.0.

use tempdb
go
create table sample 
(col1 char(10) not null primary key)
go
create table another (col1 varchar(10) 
not null foreign key (col1) 
references sample(col1))
go
drop table another
go
drop table sample
go
В SQL Server 6.5 в таком случае проводилось неявное преобразование этих двух типов данных. В SQL Server 7.0 типы данных должны строго совпадать. В Листинге 4 показаны обновленные варианты операторов создания баз данных.

Листинг 4. Декларация внешнего ключа, которая работает как в SQL Server 6.5, так и в SQL Server 7.0.

use tempdb
go
create table sample (col1 char(10) 
not null primary key)
go
create table another (col1 char(10) 
not null foreign key (col1) 
references sample(col1))
go
drop table another
go
drop table sample
go

create table sample (col1 varchar(10) 
not null primary key)
go
create table another (col1 varchar(10) 
not null foreign key (col1) 
references sample(col1))
go
drop table another
go
drop table sample
go

Отложенное разрешение имен

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

Разработчики, использующие в своих хранимых процедурах и триггерах временные таблицы, считают, что давно пора было ввести эту возможность. Хотя данное новшество, безусловно, полезно, у него есть побочный эффект, на который многие разработчики наверняка не обратили внимания. Компилятор больше не проводит надежную проверку точности воспроизведения имен таблиц в процедуре. Да, теперь тестировать коды процедур придется самим. Возможно, поначалу это известие способно кого-то развеселить. Но тех, кто не знаком с отложенным разрешением имен, может неприятно удивить тот факт, что компилятор пропустил такую ошибку.

Внешние соединения

В ранних версиях SQL Server для задания условий левого и правого внешнего соединений в обороте WHERE применялись операторы *= и =*. В некоторых случаях такой синтаксис приводил к появлению неоднозначных запросов, которые могли принести совсем не те результаты, какие ожидалось получить. В качестве примера рассмотрим два оператора SELECT, приведенные в Листинге 5, и результаты их выполнения, представленные на Рисунке. 1.

РИСУНОК 1. Результаты обработки запроса с соединением по стандарту ANSI и запроса с соединением *=.

Листинг 5. Синтаксис соединения в соответствии с ANSI.

use tempdb
go

create table Department
     ( DepartmentId int not null
     , Description  varchar(50) 
not null )
go

create table Employment
     ( DepartmentId int not null
     , EmployeeId int null )
go

insert into Department values 
(1, ?Sales?)
insert into Department values 
(2, ?Marketing?)
insert into Department values 
(3, ?Information Services?)
go

insert into Employment values (1, 99)
insert into Employment values (2, 88)
go

PRINT ??
PRINT ?Old Style Join = Incorrect 
results!!?
PRINT ??

select d.DepartmentId
            , d.Description
            , e.DepartmentId
     from Department d
            , Employment e
 where d.DepartmentId *= e.DepartmentId
     and d.DepartmentId <> 2
        or e.DepartmentId is null
go

PRINT ??
PRINT ?ANSI Join = Correct results!!?
PRINT ??

select d.DepartmentId
     , d.Description
     , e.DepartmentId
  from Department d
  LEFT OUTER JOIN Employment e 
ON d.DepartmentId = e.DepartmentId
 where d.DepartmentId <> 2
    or e.DepartmentId is null
go

drop table Department, Employment
go
Хотя эти операторы, казалось бы, идентичны, их выполнение дает различные наборы данных. Неоднозначность появляется как следствие старого синтаксиса, поскольку оптимизатор не всегда может отличить условие соединения от критерия выборки. SQL Server 7.0 поддерживает совместимые с SQL-92 внешние соединения, используя расширения LEFT OUTER JOIN и RIGHT OUTER JOIN в обороте FROM, тем самым устраняя отмеченную неоднозначность. Для преемственности SQL Server 7.0 продолжает поддерживать старый синтаксис. Однако представители Microsoft уже объявили, что в будущих выпусках SQL Server сохранится только синтаксис SQL-92. Поэтому мы настоятельно рекомендуем преобразовать все имеющиеся запросы в форму, совместимую со стандартом SQL-92.

Преемственность поведения

Категория поведения несколько изменена с точки зрения совместимости с ранними версиями, которые сложнее всего идентифицировать. Вообще, эти трудно уловимые изменения порождают проблемы только на этапе исполнения. Еще больше запутывает ситуацию тот факт, что при возникновении подобных конфликтов система ведет себя по-разному: в одних случаях она диагностирует ошибку и выдает предупреждающее сообщение, а в других не замечает конфликта. В конце концов, это может привести к несогласованности данных. Рассмотрим ряд некоторых наиболее распространенных проблем совместимости, с которыми сталкиваются разработчики.

Оптимизатор запросов

Добавление нескольких новых алгоритмов обработки оператора соединения в оптимизатор запросов SQL Server 7.0 в наибольшей степени влияет на преемственность версий. Прежде применялся только один алгоритм — вложенные итерации. Каждый раз при исполнении запроса результирующий набор всегда возвращался в одном и том же порядке. В SQL Server 7.0 у оптимизатора имеется несколько вариантов: соединение хэшированием (рекурсивное), соединение слиянием и вложенные итерации. Каждый из них обеспечивает получение корректного результата, но они возвращают данные в различном порядке.

Тем пользователям, которые обычно полагались на неявное упорядочение своих данных, теперь следует быть особенно внимательными. Изменение особенно наглядно проявляется при использовании оборота GROUP BY. Включение оборота GROUP BY в оператор SELECT не подразумевает никакого упорядочения результирующего набора данных. До выхода в свет версии SQL Server 7.0 многие разработчики полагали, что данные будут возвращены в том порядке, в каком перечислены столбцы в обороте GROUP BY. Поэтому они опускали оборот ORDER BY. Подобно стандарту ANSI, SQL Server 7.0 не гарантирует, что такое упорядочение будет произведено. Если нужно получить упорядоченные данные, следует добавить оборот ORDER BY.

Кроме того, в результате введения новых алгоритмов соединения таблиц и ряда других внутренних изменений (появления низкоуровневых блокировок, увеличения размера страниц, усовершенствования оптимизатора и ввода/вывода) оптимизатор больше не нуждается в подсказках. Следует подумать о том, чтобы убрать их из запросов, если только оптимизатор SQL Server 7.0 сам не обратится за ними. В более ранних версиях SQL Server механизм обработки запросов оставлял желать лучшего, и поэтому для составления оптимального плана обработки больших запросов требовались подсказки программиста. Множество усовершенствований SQL Server 7.0 коренным образом изменили ситуацию. Для того чтобы запросы исполнялись максимально эффективно, позвольте оптимизатору самому заняться составлением плана обработки запроса и прибегайте к подсказкам только в крайнем случае.

Сравнение неопределенных значений

Разработчикам всегда было трудно иметь дело с логикой, в которой используются три состояния (истина, ложь и неопределенное). При обработке запросов приходится учитывать не только равенство атрибутов, но и наличие у них значений в тех случаях, когда атрибуты допускают неопределенные значения. Когда атрибут не определен, его значение неизвестно. Поэтому логическое сравнение с другим значением невозможно. Для решения этой проблемы в ранних версиях SQL Server использовалось расширение T-SQL, которое позволяет сравнивать неопределенные значения. Например, выражение value = null всегда было истинным, когда значение не было определено. В SQL Server все иначе. Строго придерживаясь стандарта ANSI, SQL Server 7.0 вводит опцию SET_ANSI_NULLS для управления сравнением неопределенных значений. В состоянии ON (оно берется по умолчанию) выражение value = null получает статус «неизвестно», а не «истинно» или «ложно». Для выявления неопределенных значений теперь следует применять обороты IS NULL и IS NOT NULL. Рассмотрим оператор SELECT из Листинга 6.

Листинг 6. Сравнение неопределенных значений.

use tempdb
go

create table sample
     ( col1 char(10) not null
     , col2 tinyint null )
go

insert into sample values («AA», 1)
insert into sample values («BB», NULL)
go

Верно для версии 6.5, но неверно 
для версии 7.0

select * from sample
 where col2 = null
go


Верно и для версии 6.5, и для версии 7.0

select * from sample
 where col2 IS null
go

drop table sample
go
Под управлением SQL Server 6.х первый оператор возвратит строку «ВВ», под управлением SQL Server 7.0 он не возвратит ни одной строки. Второй оператор SELECT возвращает строку «ВВ» под управлением как SQL Server 6.х, так и SQL Server 7.0.

Агрегирование и неопределенные значения

Еще одной областью, которая может иметь неопределенные значения и требует специально написанных программ для обработки связанных с ними ситуаций, является агрегирование. Когда SQL Server 6.5 встречает неопределенное значение при выполнении какой-либо функции агрегирования (например, AVG, MIN или MAX), он просто перескакивает через эту строку, не генерируя никакого предупреждения или сообщения об ошибке. В SQL Server 7.0 процесс протекает аналогично, но при этом выдается предупреждающее сообщение о том, что при агрегировании исключено неопределенное значение (Warning: Null value eliminated from aggregate). Если, к примеру, пользователь создает таблицу, как показано на Листинге 7, то при выполнении первого оператора UPDATE система сгенерирует предупреждение.

Листинг 7. Агрегирование и неопределенные значения.

use tempdb
go

create table sample
     ( col1 char(10) not null
     , col2 int null )
go

insert into sample values (?AA?, 1)
insert into sample values (?AA?, 1)
insert into sample values (?AA?, 1)
insert into sample values (?AA?, null)
go


Данный оператор вызовет появление 
предупреждения:

  select col1, sum(col2)
    from sample
group by col1
go


Хорошо, корректно написанный оператор:

  select col1, sum(IsNull(col2, 0))
    from sample
group by col1
go

drop table sample
go
Второй оператор UPDATE корректно учитывает возможность наличия неопределенных значений в столбце 2, и поэтому именно его предпочтительнее использовать в любой версии SQL Server.

Усечение строк SQL Server не позволяет более производить неявное усечение строк. В качестве примера рассмотрим код, приведенный в Листинге 8. SQL Server 6.5 не генерирует никаких сообщений об ошибке при исполнении этого кода. Но результирующий набор данных для оператора SELECT включает две строки, каждая из которых содержит значение 0123456789.

Листинг 8: Усечение строк.

use tempdb
go
create table sample (col1 
varchar(10) not null)
go
insert into sample values 
(«0123456789»)
insert into sample values 
(«01234567890123456789»)
go
select * from sample
go
drop table sample
go
При исполнении того же кода SQL под управлением SQL Server 7.0 после второго оператора INSERT появится сообщение об ошибке, которая состоит в том, что строка или бинарные данные усечены (String or binary data would be truncated), и, как следствие, этот оператор будет проигнорирован. В результирующий набор данных войдет только одна строка. Итак, неявное усечение данных исключается. Однако теперь при перемещении данных разработчикам и проектировщикам следует быть внимательнее к размерам полей. Отметим, что, даже работая в режиме преемственности на уровне 65, SQL Server 7.0 не дублирует поведение версий 6.х.

Арифметическое переполнение

Если при выполнении операторов UPDATE и INSERT под управлением SQL Server 6.5 происходит арифметическое переполнение, то либо соответствующему полю присваивается неопределенное значение, либо (в случае запрета на неопределенные значения) пропускается вся строка. Но под управлением SQL Server 7.0 действия заканчиваются, и никакие модификации не выполняются. Например, при выполнении кода SQL, приведенного в Листинге 9, под управлением SQL Server 6.5 генерируется предупреждение о том, что произошло арифметическое переполнение (Arithmetic overflow occurred), но тем не менее вставляется строка, у которой поле имеет неопределенное значение.

Листинг 9. Арифметическое переполнение.

use tempdb
go

create table sample
     ( col1 char(10) not null
     , col2 tinyint null )
go

insert into sample values 
(«AA», power(200, 4))
go

select * from sample
go

drop table sample
go
Под управлением SQL Server 7.0 тот же оператор SQL вызовет появление сообщения о том, что произошла ошибка в связи с переполнением типа данных значением 1 600 000 000 (Arithmetic overflow error for data type tinyint, Value = 1600000000). При этом строка не вставляется. Как и в случае усечения строк, проектировщики и разработчики должны знать об этом изменении и либо привести в порядок все типы данных, либо соответствующим образом изменить вычисления.

Пустые строки

Еще одна особенность SQL Server 7.0 состоит в том, что в ней предусмотрена возможность обработки пустых строк. Более ранние версии интерпретировали пустую строку или как неопределенное значение, или как единичный символ пробела. В SQL Server 7.0 пустые строки воспринимаются именно как незаполненные. Это изменение затрагивает все функции, связанные со строками. Некоторые примеры приведены ниже; полный список всех причастных функций можно найти в серии книг по SQL Server 7.0 Books Online (BOL).

Метки времени

Первоначально тип данных «метки времени» был введен с целью поддержки алгоритмов восстановления. Каждый раз, когда кто-нибудь изменял страницу, SQL Server ставил текущую метку @@DBTS и увеличивал значение @@DBTS на единицу. Этого было достаточно для определения относительной последовательности модификаций страницы при восстановлении, хотя значения меток времени не имели ничего общего с реальным временем. В SQL Server 7.0 единственной областью применения данных типа «метки времени» остается отслеживание параллелизма, поскольку значения @@DBTS увеличиваются только для использования в столбцах временных меток. Если таблица содержит такой столбец, то каждый раз, когда оператор INSERT, UPDATE или DELETE модифицирует строку, значение метки времени в ней устанавливается равным текущему значению @@DBTS, а @@DBTS снова увеличивается на единицу.

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

Тестирование

Любая база данных развертывается по-своему. Мы затронули лишь несколько проблем, с которыми читателям, может быть, придется столкнуться. Microsoft вложила средства в разработку множества ресурсов с одной целью — облегчить процесс перехода на новую версию. К числу таких ресурсов, которыми мы рекомендуем воспользоваться, принадлежат книги серии BOL. Они не только служат отличными справочниками по вопросам преемственности и совместимости, но и содержат сведения об ODBC или функциональных изменениях с точки зрения администрирования баз данных.

До версии 7.0В версии 7.0
DATALENGTH(??) = 1DATALENGTH(??) = 0
RTRIM(? ?) = NULLRTRIM(? ?) = ??

Как и в любом проекте, прежде чем приступать к этапу промышленной эксплуатации, следует тщательно протестировать функционирование приложений совместно с базой данных в среде SQL Server 7.0. Если разработчики обладают хорошим стилем программирования на SQL, то проблем будет не слишком много. Однако некоторые изменения проявятся только в процессе эксплуатации. Наконец, значительная часть конфликтов из-за несовместимости версий является прямым результатом более строгого, чем ранее, следования стандарту ANSI. Поэтому разрешение подобных конфликтов будет способствовать созданию более устойчивой, переносимой и стабильной базы данных. Выберите время и займитесь миграцией — SQL Server 7.0 того стоит.

Об авторах

Брайан Лотон (lawton@rdaconsultants.com). Работает консультантом в RDA Consultants Limited, имеет звания MCSE, MCDBA и MCSD.

Дон Эволт (awalt@rdaconsultants.com) Президент RDA Consultants Limited. Обладает сертификатами MCSE, MCSD, MCP+I.


Тонкости миграции

Ричард Веймайер

Переход от версии SQL Server 6.5 к версии 7.0 требует некоторой подготовки. В первую очередь необходимо убедиться, что имеющаяся система удовлетворяет следующим требованиям.

На диске С должно быть не менее 10 Мбайт свободной памяти для размещения временных файлов и журналов.

Размер tempdb в базе данных SQL Server 6.5 должен быть не менее 10 Мбайт.

База данных Master должна иметь 3 Мбайт свободного пространства. Для проверки этого условия следует выполнить команды:

USE Master EXEC sp_spaceused @updateusage = ?TRUE?

и убедиться в том, что нераспределенное пространство составляет не менее 3 Мбайт (или 3072 Кбайт).

Текст syscomments должен быть нетронутым у всех объектов, подлежащих миграции (т. е. у представлений, хранимых процедур, значений по умолчанию и правил). Если производится миграция базы данных под управлением SQL Server 6.5, расположенной на одном сервере, в размещенную на другом сервере базу данных, управляемую SQL Server 7.0, то оба компьютера должны входить в одну и ту же структуру административных доменов.

Значение параметра @servername не должно быть неопределенным. Если в ответ на запрос SELECT @@servername будет получено неопределенное значение, необходимо запустить процедуру sp_addserver ?myserver?, ?local? (конечно, вместо myserver надо подставить имя сервера).

До начала миграции следует:

1. сделать копию текущей установки SQL Server 6.5;

2. в первую очередь обновить сервер-распространитель, если используются репликации;

3. проверить наличие входных идентификаторов у каждого пользователя базы данных. В случае восстановления базы данных, размещавшейся на другом сервере, запустить для нее процедуру sp_change_users_login, дабы убедиться в том, что все пользователи имеют корректные идентификаторы входа в SQL Server;

4. убедиться, что не осталось нераспределенных транзакций. Для проверки следует запустить команду exec sp_repltrans для базы данных издателя. Если активность уже была остановлена, то в ответ не будет получено ни одной строки. После этого нужно запустить команду exec sp_MSDitribution_counter @publisher = ?publisher_servername? в распределенной базе данных для каждого поддерживаемого издателя. В сообщении о том, что в ответ не получено ни одной строки (No rows returned), значение столбца undelivered_jobs должно быть равным нулю.

Несколько дополнительных советов

Проводить миграцию должен человек, имеющий статус администратора базы данных как в SQL Server 6.5, так и в SQL Server 7.0. Не обновляются хранимые процедуры, которые модифицируют системные таблицы. Хранимая процедура sp_rename не изменяет имя объекта в syscomments. Поэтому любой объект, который был обновлен, сохранит свое прежнее имя, если только после запуска процедуры переименования sp_rename его не уничтожили или не создали новый.