Миграция баз данных Oracle в базы данных Microsoft SQL Server 7.0


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

Этот документ предназначен только для информационных целей. MICROSOFT НЕ ДАЕТ ЭТИМ ДОКУМЕНТОМ НИКАКИХ ГАРАНТИЙ, ЯВНЫХ ИЛИ КОСВЕННЫХ..

©1999 Microsoft Corporation. Все права защищены.

Microsoft, логотип BackOffice, Developer Studio, Visual Basic, Visual Studio, Windows и Windows NT являются зарегистрированными торговыми марками или торговыми марками Microsoft Corporation в США и/или иных странах.

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

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

Содержание

Введение................................................................................................................................................................... 6

Ожидаемая аудитория................................................................................................................................... 6

Обзор.......................................................................................................................................................................... 7

Расширения языка SQL.................................................................................................................................. 7

ODBC.................................................................................................................................................................. 8

OLE DB............................................................................................................................................................... 8

Организация настоящего документа......................................................................................................... 9

Архитектура и технологии.............................................................................................................................. 10

Определение базы данных......................................................................................................................... 10

Системные каталоги баз данных............................................................................................................. 11

Физические и логические структуры хранилища............................................................................... 12

Расслоение данных...................................................................................................................................... 12

Журналы транзакций и автоматическое восстановление................................................................ 13

Резервное копирование и восстановление данных............................................................................. 14

Сети.................................................................................................................................................................. 15

Безопасность базы данных и роли.......................................................................................................... 16

Учетные записи имен входа.............................................................................................................. 16

Группы, роли и права.......................................................................................................................... 17

Пользователи базы данных и учетная запись guest................................................................... 17

Роль sysadmin........................................................................................................................................ 18

Роль db_owner........................................................................................................................................ 19

Установка и настройка Microsoft SQL Server......................................................................................... 20

Определение объектов базы данных.......................................................................................................... 22

Идентификаторы объектов баз данных................................................................................................. 23

Указание имен таблиц................................................................................................................................. 24

Создание таблиц........................................................................................................................................... 26

Параметры хранения таблиц и индексов.............................................................................................. 26

Создание таблиц с помощью инструкции SELECT............................................................................ 27

Представление данных............................................................................................................................... 27

Индексы........................................................................................................................................................... 29

Кластеризованные индексы.............................................................................................................. 29

Некластеризованные индексы.......................................................................................................... 31

Синтаксис и именование индексов.................................................................................................. 31

Параметры хранения данных индекса........................................................................................... 32

Игнорирование повторяющихся ключей....................................................................................... 33

Использование временных таблиц.......................................................................................................... 33

Типы данных.................................................................................................................................................. 34

Использование данных Unicode....................................................................................................... 34

Типы данных, заданные пользователем........................................................................................ 35

Колонки Microsoft timestamp............................................................................................................ 36

Права на уровне объектов......................................................................................................................... 36

Реализация целостности данных и бизнес-правил............................................................................... 38

Целостность сущностей.............................................................................................................................. 38

Именование ограничений................................................................................................................... 38

Первичные ключи и уникальные колонки..................................................................................... 38

Добавление и удаление ограничений............................................................................................. 39

Создание последовательных числовых значений...................................................................... 40

Целостность домена.................................................................................................................................... 41

Ограничения DEFAULT и CHECK................................................................................................... 42

Возможность принимать значения типа null................................................................................ 43

Целостность ссылок..................................................................................................................................... 43

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

Целостность по требованию пользователя........................................................................................... 45

Хранимые процедуры......................................................................................................................... 45

Отложенное выполнение хранимой процедуры.......................................................................... 46

Указание параметров в хранимой процедуре.............................................................................. 47

Триггеры.................................................................................................................................................. 47

Транзакции, блокировка и параллелизм.................................................................................................. 50

Транзакции..................................................................................................................................................... 50

Блокировка и изолирование транзакций............................................................................................... 52

Динамическая блокировка......................................................................................................................... 52

Изменение поведения блокировки по умолчанию.............................................................................. 53

SELECT…FOR UPDATE............................................................................................................................. 54

Явное затребование блокировки уровня таблицы.............................................................................. 55

Обработка взаимоблокировок.................................................................................................................. 55

Удаленные транзакции............................................................................................................................... 56

Распределенные транзакции..................................................................................................................... 56

Обработка двухфазной фиксации............................................................................................................ 57

Поддержка языка SQL...................................................................................................................................... 58

SELECT и инструкции управления данными....................................................................................... 58

Инструкции SELECT............................................................................................................................ 58

Инструкции INSERT............................................................................................................................ 59

Инструкции UPDATE........................................................................................................................... 60

Инструкции DELETE........................................................................................................................... 62

Инструкция TRUNCATE TABLE...................................................................................................... 62

Работа с данными в колонках Identity и timestamp.................................................................... 63

Блокировка запрошенных строк...................................................................................................... 63

Обобщения строк и пункт Compute................................................................................................. 64

Пункты Join............................................................................................................................................. 64

Использование инструкций вместо SELECT имен таблиц....................................................... 65

Чтение и изменение BLOB.................................................................................................................. 65

Функции........................................................................................................................................................... 66

Числовые/математические функции............................................................................................... 67

Символьные функции.......................................................................................................................... 69

Функции работы с датами................................................................................................................. 70

Функции преобразования................................................................................................................... 70

Прочие функции уровня строки........................................................................................................ 71

Обобщенные функции......................................................................................................................... 71

Проверки условий................................................................................................................................. 71

Преобразование значений к иным типам данных....................................................................... 72

Пользовательские функции................................................................................................................ 74

Операторы сравнения................................................................................................................................. 74

Сравнения с шаблоном....................................................................................................................... 75

Использование NULL в сравнениях................................................................................................ 76

Конкатенация строк............................................................................................................................. 76

Язык управляющих операторов............................................................................................................... 76

Ключевые слова.................................................................................................................................... 76

Декларация переменных.................................................................................................................... 77

Назначение переменных.................................................................................................................... 78

Блоки инструкций................................................................................................................................. 78

Обработка условий.............................................................................................................................. 79

Повторяемое выполнение инструкций (зацикливание)............................................................. 79

Инструкция GOTO................................................................................................................................ 80

Инструкция PRINT............................................................................................................................... 80

Возвращение из хранимых процедур............................................................................................. 80

Создание программной ошибки....................................................................................................... 80

Реализация курсоров........................................................................................................................................ 82

Синтаксис....................................................................................................................................................... 83

Декларация курсора.................................................................................................................................... 83

Открытие курсора........................................................................................................................................ 84

Выборка данных........................................................................................................................................... 84

Пункт CURRENT OF.................................................................................................................................... 85

Закрытие курсора......................................................................................................................................... 85

Пример курсора............................................................................................................................................ 86

Настройка инструкций SQL.......................................................................................................................... 87

SQL Server Query Analyzer.......................................................................................................................... 87

SQL Server Profiler......................................................................................................................................... 87

Инструкция SET............................................................................................................................................ 88

Оптимизация запросов................................................................................................................................ 88

Использование ODBC....................................................................................................................................... 90

Рекомендуемая стратегия переноса........................................................................................................ 90

Архитектура ODBC...................................................................................................................................... 90

Курсоры с возможностью продвижения только вперед.................................................................... 91

Серверные курсоры..................................................................................................................................... 92

Курсоры с прокруткой................................................................................................................................ 93

Стратегии использования результативных наборов записей по умолчанию и серверных курсоров SQL Server.................................................................................................................................................. 94

Несколько активных инструкций (hstmt) на соединение.................................................................. 95

Привязка типов данных.............................................................................................................................. 96

ODBC Extended SQL.................................................................................................................................... 97

Внешние связи............................................................................................................................................... 97

Значения даты, времени и временной метки......................................................................................... 98

Вызов хранимых процедур........................................................................................................................ 98

Перевод "родного" SQL............................................................................................................................... 99

Примерная программа Common.cpp...................................................................................................... 99

Режим ручного подтверждения................................................................................................................ 99

Разработка и администрирование репликации баз данных.......................................................... 101

ODBC, OLE/DB и репликация................................................................................................................. 102

Перенос ваших данных и приложений.................................................................................................... 104

Перенос данных с помощью Data Transformation Services............................................................ 104

Oracle Call Interface (OCI)........................................................................................................................ 104

Вложенный SQL.......................................................................................................................................... 105

Developer 2000 и приложения третьих фирм...................................................................................... 107

Интернет-приложения............................................................................................................................... 108

Заключение......................................................................................................................................................... 109

Введение

Настоящий документ предназначен для тех разработчиков приложений Oracle, которые хотят перевести свои приложения на Microsoft® SQL Server. Здесь описаны инструменты, процессы и техники, необходимые для успешного перехода. Также выделены основные точки разработки, позволяющие вам создавать высокопроизводительные приложения на основе SQL Server, поддерживающие большое число одновременно работающих пользователей.

Ожидаемая аудитория

Ожидаемая аудитория может быть и не знакома с Microsoft SQL Server и его методикой действий, но должна иметь солидные познания в области Oracle RDBMS и основных концепций баз данных. Ожидаемая аудитория должна обладать следующими качествами:

§  Достаточные познания в области основ Oracle RDBMS.

§  Знания по управлению базами данных.

§  Знакомство с языками Oracle SQL и PL/SQL.

§  Практическое знание языка программирования C/C++.

§  Членство в серверной роли sysadmin.

Для четкости и наглядности демонстрации, предполагается, что упоминаемая платформа разработки и действия приложения – это система разработки Microsoft Visual Studio® версии 6.0, операционная система Microsoft Windows NT® версии 4 (Service Pack 4),  SQL Server 7.0 и Oracle 7.3. При работе с Oracle используется драйвер ODBC Visigenic Software (версии 2.00.0300), а для работы с SQL Server 7.0 используются драйвер ODBC корпорации Microsoft (версии 3.70). В Microsoft SQL Server 7.0 входит драйвер OLE DB для Oracle, но этот драйвер полностью не обсуждается в данном документе.

Обзор

Процесс миграции приложений может выглядеть достаточно сложным. Между различными RDBMS существует множество архитектурных различий. Слова и термины, использующиеся при описании архитектуры Oracle, зачастую имеют полностью противоположное значение в Microsoft SQL Server. Более того, как Oracle, так и SQL Server внесли множество частных дополнений к стандарту SQL-92.

С точки зрения разработчика приложений, Oracle и SQL Server управляют данными приблизительно аналогичным образом. Внутренние различия между Oracle и SQL Server весьма значительны, но при правильном управлении они оказывают незначительное влияние на мигрирующее приложение.

Расширения языка SQL

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

Такой подход может излишне усложнить программный код и существенно повлиять на производительность программы. Например, функция DECODE в Oracle является нестандартным  расширением SQL, характерным для Oracle. Выражение CASE в Microsoft SQL Server является расширением SQL-92 боле высокого, нежели начальный, уровня и не реализуется во всех продуктах, связанных с базами данных.

Как DECODE в Oracle, так  и выражение CASE в SQL Server могут выполнять весьма сложные вычисления внутри запроса. Альтернативой их использованию может быть выполнение таких вычислений программно, что может потребовать извлечения из RDBMS значительно большего объема данных.

Более того, процедурные расширения языка SQL могут привести к определенным сложностям. Языки PL/SQL в Oracle и Transact-SQL в SQL Server аналогичны по функциям, но отличны по синтаксису. Точной симметрии между RDBMS и ее процедурными расширениями не существует. Вследствие этого, вы можете принять решение о неиспользовании хранимых программ, таких как хранимые процедуры и триггеры. Это весьма неприятно, поскольку такие программы могут обеспечить существенный выигрыш в производительности и безопасности, недостижимый иным образом.

Использование частных интерфейсов разработки ведет к  дополнительным сложностям. Переработка программы, использующей Oracle OCI (Oracle Call Interface, интерфейс вызовов Oracle), зачастую требует значительного вложения средств. При разработке приложения, рассчитанного на несколько RDBMS, старайтесь использовать интерфейс Open Database Connectivity (ODBC).

ODBC

ODBC разработана из учета работы с различными системами управления базами данных. ODBC предоставляет последовательные интерфейсы прикладного программирования (Application Programming Interface, API), работающие с различными базами данных с помощью конкретного драйвера базы данных.

Последовательность API означает, что функции, вызываемые программой для установления соединения, выполнения команды и получения результатов не отличаются при  работе с Oracle или SQL Server.

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

ODBC – это не панацея для достижения полной независимости от базы данных, полного набора функций и высокой производительности при любой базе данных. Различные базы данных и независимые поставщики предоставляют различные уровни поддержки ODBC. Некоторые драйвера реализуют только основной набор функций API, привязанных поверх основных библиотек интерфейса. Другие драйвера, такие как драйвер Microsoft SQL Server, предоставляют полную поддержку 2 уровня в высокопроизводительном драйвере.

Если программа использует только основные API ODBC, скорее всего, она откажется от некоторых возможностей и производительности определенных баз данных. Более того, не все "родные" расширения SQL могут быть представлены в форме управляющих последовательностей ODBC (например, DECODE в Oracle или CASE в SQL Server).

Более того, общепринята практика написание конструкций SQL, рассчитанных на оптимизатор базы данных. Техники и методы, повышающие производительность в Oracle, не обязательно оптимальны в Microsoft SQL Server 7.0. Интерфейс ODBC не может перевести техники от одной RDBMS к другой.

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

OLE DB

OLE DB – это следующее поколение технологий доступа к базам данных. Microsoft SQL Server 7.0 использует преимущества OLE DB. Более того, разработчикам приложений следует рассчитывать на OLE DB при разработке для SQL Server 7.0. Microsoft предоставляет OLE DB-провайдера для Oracle 7.3 вместе с SQL Server 7.0.

OLE DB – стратегический интерфейс программирования системного уровня Microsoft для управления данными в организации. OLE DB – это открытая спецификация, разработанная на основе ODBC. ODBC был создана для доступа к реляционным базам данных, а OLE DB – для доступа к реляционным и нереляционным базам данных, таким как ISAM/VSAM на мэйнфреймах, и иерархическим базам данных, хранилищам email и файловых систем, тексту, графическим и географическим данным и бизнес-объектам.

OLE DB определяет набор интерфейсов COM, инкапсулирующих различные службы управления базами данных и делающих возможным создание программных компонентов для реализации подобных служб. Компоненты OLE DB состоят из поставщиков данных (содержащих и поставляющих данные), потребителей данных (использующих данные) и служебных компонентов (обрабатывающих и транспортирующих, например, обработчиков запросов и механизмов управления курсором).

Интерфейсы OLE DB рассчитаны на как можно более легкую и полную интеграцию компонентов, так, чтобы поставщики компонентов OLE DB могли быстро привносить на рынок высококачественные компоненты OLE DB. Вдобавок, OLE DB включает в себя "мост" к ODBC, что позволяет продолжать поддерживать широкий спектр доступных сейчас драйверов ODBC для реляционных баз данных.

Организация настоящего документа

Для того чтобы помочь вам в реализации пошаговой миграции из Oracle в SQL Server, в каждый раздел включен обзор соответствующих отличий между Oracle 7.3 и Microsoft SQL Server 7.0. Так же включены соображения по переходу, преимущества SQL Server 7.0 и многочисленные примеры.

Архитектура и технологии

Для того чтобы начать успешную миграцию, вам необходимо понимать основы архитектуры и терминологии, связанных с Microsoft SQL Server 7.0. Многие из примеров в этом разделе взяты из примерных приложений на основе Oracle и SQL Server, приводимых вместе с настоящим документом.

Определение базы данных

В Oracle, термин база данных означает всю среду RDBMS Oracle и включает в себя три компонента.

§  Процессоры и буферы баз данных Oracle (экземпляр, instance).

§  Табличная область (tablespace) SYSTEM, хранящая единый централизованный системный каталог, состоящий из одного или нескольких файлов данных.

§  Прочие табличные области, заданные DBA (по необходимости), каждая состоящая из одного или нескольких файлов данных.

§  Два или более рабочих журнала повторного выполнения (Redo Log).

§  Архивированные журналы повторного выполнения (по необходимости).

§  Различные прочие файлы (управляющий файл, Init.ora, config.ora, и т.д.).

База данных Microsoft SQL Server логически разделяет данные, приложения и механизмы безопасности. Одна установка SQL Server может поддерживать несколько баз данных. Приложения, построенные на основе SQL Server, могут использовать базы данных для логического разделения бизнес-функций.

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

Microsoft SQL Server также устанавливает по умолчанию следующие базы данных:

§  База данных model – это шаблон для всех создаваемых пользовательских баз данных.

§  База данных tempdb аналогично временной табличной области Oracle, используемой для временного рабочего хранилища и операций по сортировке. В отличие от временной табличной области Oracle, пользователи могут создавать временные таблицы, которые будут автоматически уничтожены при выходе пользователя из системы.

§  База данных msdb, поддерживающая SQL Server Agent его распланированные задачи, оповещения и информацию о репликации.

§  Базы данных pubs и Northwind, предоставленные для примера.

Более подробную информацию о базах данных по умолчанию можно найти в SQL Server Books Online.

Системные каталоги баз данных

Каждая база данных Oracle использует централизованный системный каталог, или словарь данных, находящийся в табличной области SYSTEM. Каждая база данных Microsoft SQL Server 7.0 поддерживает свой собственный системный каталог, хранящий информацию о:

§  Объектах базы данных (таблицах, индексах, хранимых процедурах, представлениях данных, триггерах, и так далее).

§  Ограничениях.

§  Пользователях и правах.

§  Типах данных, заданных пользователем.

§  Определениях репликации.

§  Файлах, используемых базой данных.

SQL Server также содержит централизованный системный каталог в базе данных master, содержащий системные каталоги вместе с некоторой информацией о каждой из баз данных:

§  Имена баз данных и местонахождение основных файлов каждой базы данных.

§  Учетные записи имен входа (login) SQL Server.

§  Системные сообщения.

§  Параметры конфигурации баз данных.

§  Удаленные и/или подключенные сервера.

§  Информация о текущей активности.

§  Системные хранимые процедуры.

Аналогично табличной области SYSTEM в Oracle, база данных master SQL Server должна быть доступна для обеспечения доступа к любой иной базе данных. В силу этого, при планировании защиты от сбоев очень важно предусмотреть резервное копирование базы данных master после каждого значительного изменения баз данных. Администраторы баз данных могут также зеркалировать файлы, составляющие базу данных master.

Физические и логические структуры хранилища

RDBMS Oracle состоит из табличных областей, в свою очередь состоящих из файлов данных. Файлы данных форматируются по внутренним единицам, именуемым блоками. Размер блока задается DBA при создании базы данных Oracle. При создании объекта в табличной области Oracle, пользователь может задать его размер в единицах, именуемых экстентами (первоначальный экстент, следующий экстент, минимальный и максимальный экстенты).  Если размер экстента явно не задан, создается экстент со значениями по умолчанию. Экстент в Oracle может иметь различный размер и должен содержать цепочку как минимум из пяти смежных блоков.

Microsoft SQL Server использует группы файлов на уровне базы данных для управления физическим размещением таблиц и индексов. Группы файлов – это логические контейнеры из одного или нескольких файлов, а данные, содержащиеся в группе файлов, пропорционально распределяются между всеми файлами группы файлов.

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

§  Распределять большие таблицы между несколькими файлами для улучшения пропускной способности ввода-вывода.

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

§  Хранения колонок text, ntext, и image (больших объектов) отдельно от соответствующих таблиц.

§  Размещение объектов баз данных на конкретных дисководах.

§  Резервное копирование и восстановление отдельных таблиц или наборов таблиц внутри группы файлов.

SQL Server форматирует файлы по внутренним единицам, называемых страницами. Размер страницы фиксирован и равняется 8192 байтам (8 KB). Страницы организованы в экстенты, фиксированные в размере и равные 8 смежным страницам. При создании таблицы или индекса в базе данных SQL Server, под нее автоматически выделяется одна страница. Это дает более возможность более эффективно управлять хранением маленьких таблиц и индексов по сравнению с выделением целого экстента в Oracle.

Расслоение данных

Сегменты, аналогичные используемым в Oracle, не требуются при большинстве установок Microsoft SQL Server. Вместо этого, SQL Server может распределять, или расслаивать, данные более эффективно с помощью RAID, основанного на аппаратном обеспечении, или с помощью RAID, основанных на программном обеспечении, например на утилите Windows NT Disk Administrator или утилитах третьих фирм. С помощью RAID вы можете указать, что набор слоев, состоящий из нескольких дисковых устройств, представляется одним логическим диском. Если файлы базы данных создаются на таком наборе слоев, ответственность за распределение загрузки ввода-вывода между несколькими дисками ложится на дисковую подсистему. Администраторам рекомендуется распространять данные по нескольким физическим дискам именно с помощью RAID.

Рекомендуемая конфигурация RAID для SQL Server - RAID 1 (зеркалирование) или RAID 5 (наборы слоев с добавочным диском четности в целях резервирования). RAID 10 (зеркалирование наборов слоев с проверкой четности) также рекомендуется, но она значительно дороже первых двух вариантов. Наборы слоев достаточно хорошо справляются с обычным случайным вводом-выводом в/из файлов баз данных.

Если использование RAID невозможно, группы файлов являются весьма привлекательной альтернативой и предоставляют некоторые из возможностей RAID. Более того, в случае очень больших баз данных, которые могут занять несколько физических массивов RAID, группы файлов являются привлекательным методом контролируемого распределения вашего ввода-вывода по нескольким массивам RAID.

Файлы журналов транзакций должны быть оптимизированы для последовательного ввода-вывода и должны быть защищены от единичной точки сбоя (single point of failure). В соответствии с этим, для них рекомендуется использование RAID 1 (зеркалирование). При миграции размер этого диска должен быть как минимум эквивалентен сумме размеров рабочих логов повтора действий Oracle и табличной области (областей) сегмента отката Oracle. Создайте один или несколько файлов журнала, занимающих все место на локальном диске. В отличие от данных, хранящихся в группах файлов, записи журнала транзакций всегда пишутся последовательно и заполняются непропорционально.

Более подробную информацию о RAID можно найти в SQL Server Books Online, документации Windows NT Server и Microsoft Windows NT Resource Kit.

Журналы транзакций и автоматическое восстановление

RDBMS Oracle выполняет автоматическое восстановление при каждом запуске. Она проверяет скоординированность содержимого файлов табличных областей с содержимым рабочих файлов журналов повтора действий. При обнаружении несовпадения, Oracle совмещает содержимое рабочих файлов журналов повтора действий с файлами табличных областей (восстановление с повтором), а затем удаляет все незафиксированные транзакции, найденные в сегментах отката (откат). В случае если Oracle не может получить необходимую информацию из рабочих файлов журнала повтора действий, он обращается к архивированным файлам журнала повтора действий.

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

Каждый журнал транзакций SQL Server совмещает в себе функции сегмента отката Oracle и рабочего журнала повтора действий Oracle. У каждой базы данных – свой журнал транзакций, хранящий данные по изменениям этой базы данных, единый для всех пользователей. При начале транзакции и изменении данных, событие BEGIN TRANSACTION (как и событие изменения) записывается в журнал. Это событие используется механизмом для автоматического восстановления для определения точки начала транзакции. При получении каждой инструкции изменения данных изменения пишутся сначала в журнал транзакций, а затем уже в саму базу данных. Более подробную информацию можно найти в разделе “Транзакции, блокировка и параллелизм ” данного документа.

В SQL Server встроен механизм автоматической проверки, гарантирующий, что завершенные транзакции регулярно переносятся из дискового кэша SQL Server в файл журнала транзакций. В точке проверки в базу данных пишутся все кэшированные страницы, измененные с момента последней точки проверки. Сброс таких кэшированных страниц, еще известных как "грязные" (dirty), в базу данных гарантирует, что все завершенные транзакции будут записаны на диск. Этот процесс уменьшает время, необходимое на восстановление после такого сбоя системы, как, например, отключение питания. Эти параметры могут быть изменены с помощью изменения интервала восстановления в SQL Server Enterprise Manager или Transact-SQL (системная хранимая процедура sp_configure).

Резервное копирование и восстановление данных

Microsoft SQL Server предлагает несколько вариантов резервного копирования данных:

Полное копирование базы данных

Резервное копирование сводится к копированию всей базы данных. Копируются не все страницы базы данных, а только те из них, которые реально содержат данные. Копируются как страницы данных, так и страницы журнала транзакций.

Резервная копия базы данных используется для воссоздания базы данных в том ее состоянии, в каком она была на момент фиксации выполнения команды BACKUP. Если для базы данных есть только полные копии, она может быть восстановлена только до состояния на момент последнего копирования перед сбоем сервера или базы данных. Для полного резервного копирования базы данных используйте инструкцию BACKUP DATABASE или мастер резервного копирования (Backup Wizard).

Дифференциальное резервное копирование

После выполнение полного резервного копирования базы данных достаточно делать резервные копии только изменившихся страниц данных и индексов с помощью инструкции BACKUP DATABASE WITH DIFFERENTIAL или мастера резервного копирования.

Резервное копирование журнала транзакций

Журналы транзакций в Microsoft SQL Server ассоциированы с отдельными базами данных. Журнал транзакций заполняется до момента архивации или усечения. По умолчанию, SQL Server 7.0 сконфигурирован таким образом, чтобы журнал транзакций рос либо до тех пор, пока не кончится место на диске, либо до достижения заданного максимального размера. Если журнал транзакций переполняется, он создает ошибку и запрещает дальнейшие изменения данных до тех пор, пока он не будет скопирован или усечен. Это не влияет на все остальные базы данных. Журналы транзакций могут быть скопированы с помощью инструкции BACKUP LOG или мастера резервного копирования.

Резервное копирование файлов или файловых групп

Резервное копирование файлов или файловых групп сводится к копированию одного или нескольких файлов база данных заданной базы данных, что дает возможность выполнять резервное копирование базы данных меньшими единицами: на уровне файлов или файловых групп. За боле подробно информацией смотри SQL Server Books Online.

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

Как Oracle, так и SQL Server требуют особого формата файлов журналов. В SQL Server эти файлы, именуемые устройствами резервного копирования, создаются через SQL Server Enterprise Manager, хранимую процедуру Transact-SQL sp_addumpdevice или аналогичную команду SQL-DMO.

Хотя резервное копирование и может выполняться вручную, рекомендуется использовать SQL Server Enterprise Manager и/или мастер планирования поддержки базы данных (Database Maintenance Plan Wizard) для планирования регулярных резервных копирований или резервных копирований в зависимости от активности баз данных.

База данных может быть восстановлена до определенного уровня посредством наложения резервных копий журналов транзакций и/или дифференциальных резервных копий на полную резервную копию (устройство). Восстановление базы данных затирает любую информацию в базе данных информацией из резервных копий. Восстановительные операции могут производиться с помощью SQL Server Enterprise Manager, Transact-SQL (RESTORE DATABASE) или SQL-DMO.

Точно так же, как вы можете отключить архиватор Oracle для отмены автоматического резервного копирования, в Microsoft SQL Server члены фиксированной серверной роли db_owner могут заставить журнал транзакций сбрасывать свое содержимое после достижении каждой точки проверки. Это может быть сделано из SQL Server Enterprise Manager (усечение журнала на точке проверки), Transact-SQL (хранимая процедура sp_dboption) или SQL-DMO.

Сети

SQL*Net Oracle поддерживает сетевые соединения между серверами баз данных Oracle и их клиентами. Она использует протокол потока данных Transparent Network Substrate (TNS) и дает пользователям возможность использовать несколько сетевых протоколов без написания специализированного кода.

В Microsoft SQL Server Net-Libraries (сетевые библиотеки) поддерживают сетевые соединения между клиентами и сервером с использованием протокола Tabular Data Stream (TDS). Они дают возможность одновременных соединений с клиентами, использующими Named Pipes, TCP/IP Sockets или иные механизмы Inter-Process Communication (IPC). Компакт-диск с SQL Server содержит все клиентские Net-Libraries, так что нет необходимости приобретать их отдельно.

Настройки SQL Server NetLibrary могут быть изменены после установки. Утилита Client Network конфигурирует NetLibrary по умолчанию и информацию по соединению с сервером для клиента под управлением операционных систем Windows NT, Windows® 95 или Windows 98. Все клиентские приложения ODBC используют ту же самую NetLibrary по умолчанию и информацию о соединении, если только эти данные не были заданы при установке источника данных ODBC или явно указаны в строке соединения ODBC. Более подробную информацию о Net-Libraries можно найти в SQL Server Books Online.

Безопасность базы данных и роли

Для адекватной миграции вашего приложения из Oracle в Microsoft SQL Server 7.0 вам необходимо понимать, как SQL Server реализует безопасность и роли базы данных.

Учетные записи имен входа

Учетная запись имени входа позволяет пользователю иметь доступ к данным или административным настройкам SQL Server. Учетная запись имени доступа позволяет пользователям только входить в систему SQL Server и просматривать базы данных, позволяющие гостевой доступ. (Учетная запись guest не задана по умолчанию и должна быть создана)

SQL Server предлагает два типа защиты входа в систему: Windows NT Authentication Mode (также известный как интегрированная защита) и SQL Server Authentication Mode (также известный как стандартная защита). SQL Server 7.0 также поддерживает комбинацию стандартной и интегрированной защиты, известную как смешанная защита.

Режим аутентификации Windows NT Authentication Mode использует механизмы безопасности Windows NT для подтверждения соединения при входе в систему и опирается на пользовательские полномочия в системе безопасности Windows NT. Пользователям не нужно вводить ID или пароля для входа в систему SQL Server— информация берется напрямую из сетевого соединения. Когда это происходит, в таблицу syslogins делается запись и происходит ее проверка между Windows NT и SQL Server. Это известно как доверенное соединение и работает аналогично доверительным отношениям между двумя серверами под управлением Windows NT. Это работает аналогично настройке IDENTIFIED EXTERNALLY, связанной с пользовательскими учетными записями Oracle.

Режим аутентификации SQL Server Authentication Mode требует ввода пользователем идентификатора (ID) и пароля входа в систему при запросе доступа к SQL Server. Это известно как недоверенное соединение. Это работает аналогично настройке IDENTIFIED BY PASSWORD, связанной с пользовательскими учетными записями Oracle. При использовании стандартной модели безопасности, вход в систему предоставляет только доступ к механизму баз данных SQL Server, но не пользовательским базам данных.

Более подробную информацию о этих механизмах безопасности можно найти в SQL Server Books Online.

Группы, роли и права

Обе системы – Microsoft SQL Server и Oracle используют права для реализации системы защиты базы данных. Права уровня инструкций используются в SQL Server для ограничения возможности создания новых объектов баз данных (аналогично правам уровня системы в Oracle).

SQL Server также предоставляет права на уровне объектов. Как и в Oracle, владение на уровне объекта назначается создателю объекта и не может быть передано. Права уровня объекта должны быть предоставлены остальным пользователям для того, что бы они могли использовать объект. Члены фиксированной серверной роли sysadmin, или фиксированных ролей базы данных db_owner и/или db_securityadmin также могут предоставлять права на чей-либо объект остальным пользователям.

Права уровня инструкций и объектов SQL Server могут быть предоставлены напрямую учетным записям базы данных. Однако зачастую проще управлять правами ролей базы данных. Роли SQL Server используются для назначения и отзыва привилегий у групп пользователей (во многом аналогично ролям Oracle). Роли – это объекты базы данных, связанные с конкретной базой данных. Есть несколько фиксированных серверных ролей, действующих во всех базах данных. Примером фиксированной серверной роли является sysadmin. Группы Windows NT также могут быть добавлены как учетные записи имен входа SQL Server, так же, как и пользователи баз данных. Права могут быть предоставлены группе Windows NT или пользователю Windows NT.

В базе данных может быть число ролей или групп Windows NT. Роль по умолчанию public есть в любой базе данных и не может быть удалена. Роль public действует во многом аналогично учетной записи PUBLIC в Oracle. Каждый пользователь базы данных всегда является членом роли public. Пользователь базы данных может быть членом любого количества ролей в добавление к роли public. Пользователь или группа Windows NT также могут быть членом любого числа ролей, и также всегда входят в роль public.

Пользователи базы данных и учетная запись guest

В Microsoft SQL Server пользовательская учетная запись входа в систему должна быть авторизована для использования базы данных и ее объектов. Для получения доступа к базе данных учетной записью имени входа может использоваться один из следующих методов:

§  Учетная запись имени входа может быть задана как пользователь базы данных.

§  Учетная запись имени входа может использовать учетную запись guest в базе данных.

§  Групповое имя входа Windows NT может быть привязано к роли базы данных. Отдельные учетные записи Windows NT, которые являются членами этой группы, могут подключаться к базе данных.

Члены ролей db_owner или db_accessadmin, или фиксированной роли sysadmin создают роли учетных записей пользователей базы данных. Учетная запись может включать в себя несколько параметров: идентификатор входа в SQL Server, имя пользователя базы данных (по желанию) и до одного названия роли (по желанию). Имя пользователя базы данных не обязательно должно совпадать с ID входа в систему. Если имя пользователя базы данных не задано, то идентификатор для входа в систему и имя пользователя базы данных задаются одинаковыми. Если имя роли не задано, пользователь базы данных является только членом роли public. После создания пользователя базы данных, ему может быть назначено сколько угодно ролей.

Члены ролей db_owner или db_accessadmin могут также создать учетную запись guest. Учетная запись guest позволяет любой корректной учетной записи имени входа SQL Server иметь доступ к базе данных даже без наличия соответствующей учетной записи пользователя базы данных. По умолчанию, учетная запись guest наследует все привилегии, назначенные роли public; однако, эти привилегии могут быть изменены в большую или меньшую сторону.

Учетной записи пользователя или группы Windows NT может быть предоставлен доступ к базе данных точно так же как и имени входа в систему SQL Server. Когда пользователь Windows NT, являющийся членом группы, подсоединяется к базе данных, он получает права, назначенные группе Windows NT. Если он имеет членство в нескольких группах Windows NT, и некоторым из них назначены права доступа к базе данных, он получает комбинированные права всех групп, к которым он принадлежит.

Роль sysadmin

Члены фиксированной серверной роли sysadmin в Microsoft SQL Server имеют права, аналогичные правам DBA в Oracle. В SQL Server 7.0, учетная запись имени входа sa в SQL Server Authentication Mode по умолчанию является членом этой роли, как и члены локальной группы Administrators в том случае, если SQL Server установлен на машине под управлением Windows NT. Член роли sysadmin может добавлять или удалять пользователей и группы Windows NT, как и имена входа SQL Server. Члены этой роли обычно имеют следующие обязанности:

§  Установка SQL Server.

§  Конфигурация серверов и клиентов.

§  Создание баз данных.*

§  Установка прав имен входа и пользовательских прав.*

§  Передача данных в и из баз данных SQL Server.*

§  Резервное копирование и восстановление баз данных.*

§  Реализация и поддержка репликации.

§  Планировка операций, выполняющихся без присмотра.*

§  Отслеживание и настройка производительности SQL Server.*

§  Диагностика системных проблем.

*Эти обязанности могут быть переданы иным роля или пользователям.

Члены фиксированной серверной роли sysadmin имеют доступ ко всем базам данных и всем объектам (включая данные) на данном экземпляре SQL Server. Аналогично DBA в Oracle, существует ряд команд и системных процедур, которые могут быть отданы  только членами роли sysadmin.

Роль db_owner

Хотя базы данных Microsoft SQL Server в использовании аналогичны табличным областям Oracle, они администрируются иначе. Каждая база данных  SQL Server – это административный домен "в себе". Каждая база данных имеет владельца базы данных (dbo). Этот пользователь всегда является членом фиксированной роли базы данных db_owner. Другие пользователи так же могут быть членами роли db_owner. Любой пользователь, являющийся членом этой роли, может управлять административными задачами, связанными с соответствующей базой данных (в отличие от Oracle, где только DBA управляет административными задачами табличной области). Сюда входят:

§  Управление доступом к базе данных.

§  Изменение настроек базы данных (только для чтения, однопользовательская и так далее...)

§  Резервное копирование и восстановление содержимого базы данных.

§  Назначение и отзыв прав базы данных.

§  Создание и удаление объектов базы данных.

Члены роли db_owner имеют право делать что угодно со своей базой данных. Большая часть назначенных им прав распределена на несколько фиксированных ролей базы данных или же может быть назначена отдельным пользователям. Не обязательно обладать правами sysadmin на уровне сервера, чтобы иметь права db_owner в базе данных.

Установка и настройка Microsoft SQL Server

Теперь, поняв основные структурные различия между Oracle и SQL Server, вы готовы к выполнению первого шага миграции. Для выполнения этого сценария следует использовать SQL Server Query Analyzer:

1.   Используйте аппаратно или программно контролируемый RAID уровня 5 для создания логического диска объемом, достаточным для того, чтобы вместить все ваши данные. Приблизительно этот объем может быть вычислен, сложением места, занятого системной и временной табличными областями, а также табличной областью приложения Oracle.

2.   Создайте второй логический диск для размещения журналов транзакций, используя аппаратно или программно контролируемый RAID уровня 1. Размер этого диска должен быть не меньше суммы размеров файлов журналов повтора действий и табличных областей сегментов отката.

3.   С помощью SQL Server Enterprise Manager создайте базу данных с таким же именем, что и табличная область Oracle. (В примере используется имя USER_DB.) Укажите места под размещение файлов данных и журналов транзакций, совпадающие с созданными в шагах 1 и 2 соответственно. Если вы используете несколько табличных областей Oracle, нет необходимости (или хотя бы рекомендации) к созданию нескольких баз данных SQL Server. RAID распределит данные за вас.

4.   Создайте учетные записи имен входа SQL Server:

USE MASTER
EXEC SP_ADDLOGIN STUDENT_ADMIN, STUDENT_ADMIN
EXEC SP_ADDLOGIN DEPT_ADMIN, DEPT_ADMIN
EXEC SP_ADDLOGIN ENDUSER1, ENDUSER1
GO

 

5.   Добавьте в базу данных роли:

USE USER_DB
EXEC SP_ADDROLE DATA_ADMIN
EXEC SP_ADDROLE USER_LOGON
GO

 

6.   Назначьте права ролей:

GRANT CREATE TABLE, CREATE TRIGGER, CREATE VIEW,
CREATE PROCEDURE TO DATA_ADMIN
GO

 

7.   Добавьте учетные записи имен входа как учетные записи пользователей базы данных:

EXEC SP_ADDUSER ENDUSER1, ENDUSER1, USER_LOGON
EXEC SP_ADDUSER DEPT_ADMIN, DEPT_ADMIN, DATA_ADMIN
EXEC SP_ADDUSER STUDENT_ADMIN, STUDENT_ADMIN, DATA_ADMIN
GO

 

На рисунке показаны среды SQL Server и Oracle после фиксации процесса.

Определение объектов базы данных

Объекты базы данных Oracle (таблицы, представления данных и индексы) могут быть легко перенесены в Microsoft SQL Server, поскольку обе RDBMS достаточно точно следуют стандарту SQL-92, касающемуся определений объекта. Перенос определений SQL таблиц, индексов и представлений данных из Oracle в SQL Server требует достаточно простых синтаксических изменений. В таблице выделены некоторые различия в объектах баз данных между Oracle и Microsoft SQL Server.

Категория

Microsoft SQL Server

Oracle

Число колонок

1024

254

Размер строки

8060 байтов, плюс 16 байтов для указателя на каждую колонку с текстом или изображением

Неограниченно (разрешено только одно значение типа long или long raw на строку)

Максимальное число строк

Неограниченно

Неограниченно

Хранения данных типа Blob

16-байтный указатель, хранящийся в строке. Данные хранятся на других страницах данных

Одна колонка типа long или long raw на таблицу, обязательно в конце строки, данные хранятся в том же блоке, что и строка

Кластеризованные индексы таблиц

1 на таблицу

1 на таблицу (таблицы, организованные по индексу (Index-organized))

Некластеризованные индексы таблиц

249 на таблицу

Неограниченно

Максимальное число колонок в одном индексе

16

16

Максимальная длина значений  колонок внутри индекса

900 байт

½ блока

Соглашение об именовании таблиц

[[[Server.]database.]owner.]table_name

[schema.]table_name

Соглашение об именовании представлений данных

[[[Server.]database.]owner.]table_name

[schema.]table_name

Соглашение об именовании индексов

[[[Server.]database.]owner.]table_name

[schema.]table_name

Предполагается, что вы начнете с того сценария или программы Oracle SQL, которую вы использовали для создания вашей базы данных. Просто скопируйте этот сценарий или программу и внесите следующие изменения. Каждое изменение обсуждается в дальнейшем в данном разделе. Примеры взяты из примерных сценариев Oratable.sql и Sstable.sql:

1.   Удостоверьтесь, что идентификаторы объектов баз данных удовлетворяют соглашениям об именовании объектов в Microsoft SQL Server. Возможно, что вам придется только переименовать индексы.

2.   Примите во внимание те параметры хранения данных, которые могут понадобиться вашей базе данных SQL Server. Если вы используете RAID, в таких параметрах нет необходимости.

3.   Измените описания ограничений Oracle в соответствии с требованиями SQL Server. По необходимости создайте триггеры для поддержки инструкции DELETE CASCADE внешнего ключа. Если таблицы затрагивают несколько баз данных, используйте триггеры для продвижения отношений внешнего ключа.

4.   Измените инструкции CREATE INDEX для использования возможностей кластеризованных индексов.

5.   Используйте Data Transformation Services для создания инструкций CREATE TABLE. Просмотрите эти инструкции, обратите внимание, как типы данных Oracle привязаны к типам данных SQL Server.

6.   Удалите все инструкции CREATE SEQUENCE. Замените последовательности колонками идентичных значений (identity columns) в инструкциях CREATE TABLE или  ALTER TABLE.

7.   По необходимости измените инструкции CREATE VIEW.

8.   Удалите все ссылки на синонимы.

9.   Оцените использование временных таблиц Microsoft SQL Server и их необходимость в вашем приложении.

10. Измените инструкции Oracle CREATE TABLE…AS SELECT на инструкции SQL Server SELECT…INTO.

11.Оцените возможное использование заданных пользователем правил, типов данных и значений по умолчанию.


Идентификаторы объектов баз данных

Ниже приведенный график сравнивает обработку идентификаторов объектов в Oracle и Microsoft SQL Server. В большей части случаев вам не придется менять имена объектов при миграции к SQL Server.

Oracle

Microsoft SQL Server

1-30 символов в длину.
Имена баз данных: до 8 символов в длину
Имена ссылок на базы данных: до 128 символов в длину

1-128 символов Unicode в длину
Имена временных таблиц: до 116 в длину

Идентификаторы должны начинаться с буквенного знака и содержать алфавитно-цифровые символы или символы _, $, и #.

Идентификаторы могут начинаться с алфавитно-цифрового символа или с _, и могут содержать практически любой символ.

Если идентификатор начинается с пробела или содержит символы, отличные от символов _, @, #, или $, вы должны использовать [ ] (разделители) вокруг имени.

Если объект начинается с:
@ - это локальная переменная.
# - это локальный временный объект.
## - это глобальный временный объект.

Имена табличных областей должны быть уникальны.

Имена баз данных должны быть уникальны.

Имена идентификаторов должны быть уникальными внутри пользовательских учетных записей (схем).

Имена идентификаторов должны быть уникальными внутри пользовательских учетных записей базы данных.

Имена колонок должны быть уникальными внутри таблицы и представления данных

Имена колонок должны быть уникальными внутри таблицы и представления данных

Имена индексов должны быть уникальными внутри пользовательской схемы.

Имена индексов должны быть уникальными внутри таблицы.

Указание имен таблиц

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

Microsoft SQL Server использует иное соглашение при обращении к таблицам. Поскольку одна и та же учетная запись имени входа SQL Server может создавать таблицы с одинаковыми именами в нескольких базах данных, для обращения к таблицам и представлениям данных используется следующее соглашение: [[database_name.]owner_name.]table_name

Для обращения к таблице в …

Oracle

Microsoft SQL Server

вашей учетной записи

SELECT *
FROM STUDENT

SELECT * FROM USER_DB.STUDENT_ADMIN.STUDENT

Иной схеме

SELECT * FROM STUDENT_ADMIN.STUDENT

SELECT * FROM OTHER_DB.STUDENT_ADMIN.STUDENT

Вот рекомендации к именованию таблиц и представления данных Microsoft SQL Server:

§  Использование имени базы данных и имени пользователя не необходимо. Когда к таблице обращаются только по имени (например, STUDENT), SQL Server ищет эту таблицу в текущей учетной записи пользователя в текущей базе данных. Если он не находит такой таблицы, он ищет объект с таким же именем, находящийся во владении зарезервированного пользовательского имени dbo в той же базе данных. Имена таблиц должны быть уникальны внутри пользовательской учетной записи в одной базе данных.

§  Одна и та же учетная запись имени входа SQL Server может владеть таблицами с одними и теми же именами, но в разных базах данных. Например, учетная запись ENDUSER1 владеет следующими объектами баз данных: USER_DB.ENDUSER1.STUDENT и OTHER_DB.ENDUSER1.STUDENT. При ссылке используется имя пользователя базы данных, а не имя входа в систему SQL Server, поскольку они не обязательно совпадают.

§  В то же время, прочие пользователи тех же баз данных могут владеть таблицей с таким же именем:

·  USER_DB.DBO.STUDENT

·  USER_DB.DEPT_ADMIN.STUDENT

·  USER_DB.STUDENT_ADMIN.STUDENT

·  OTHER_DB.DBO.STUDENT

Таким образом, рекомендуется включать имя владения в ссылку на объект базы данных. Если в приложении используется несколько баз данных, рекомендуется также использовать имя базы данных. Если запрос распространяется на несколько серверов, включите еще и имя сервера.

§  Каждое подсоединения к SQL Server имеет текущий контекст базы данных, задаваемый в момент подсоединений командой USE. Например, рассмотрим следующий сценарий:

Пользователь, использующий учетную запись ENDUSER1, входит в базу данных USER_DB. Пользователь запрашивает таблицу STUDENT. SQL Server ищет таблицу ENDUSER1.STUDENT. Если таблица найдена, SQL Server выполняет запрошенную операцию над таблицей USER_DB.ENDUSER1.STUDENT. Если таблица не найдена в учетной записи ENDUSER1 базы данных, SQL Server ищет USER_DB.DBO.STUDENT в учетной записи dbo этой базы данных. Если таблица опять не найдено, SQL Server возвращает сообщение об ошибке, указывающее на отсутствие таблицы.

§  Если другой пользователь, например, DEPT_ADMIN, владеет таблицей, имени таблицы должно предшествовать имя пользователя базы данных (DEPT_ADMIN.STUDENT). Иначе имя базы данных по умолчанию сводится к текущему контексту.

§  Если искомая таблица существует в другой базе данных, в ссылке должно присутствовать имя базы данных. Например, для доступа к таблице STUDENT, которой владеет ENDUSER1 в базе данных OTHERDB, используйте OTHER_DB.ENDUSER1.STUDENT.

Имя владельца объекта может быть опущено посредством отделения имени базы данных от имени таблицу двумя точками. Например, при обращении к  STUDENT_DB..STUDENT, SQL Server ищет следующим образом:

1.   STUDENT_DB.current_user.STUDENT

2.   STUDENT_DB.DBO.STUDENT

Если приложение использует только одна базу данных в каждый момент времени, изъятие имени базы данных из ссылки на объект делает возможным использование приложения с другой базой данных. Все ссылки на объекты неявно используют текущую базу данных. Это полезно в том случае, когда вы хотите иметь на одном сервере рабочую и тестовую базы данных.

Создание таблиц

Поскольку Oracle и SQL Server поддерживают соглашения SQL-92 начального уровня в части идентификации объектов RDBMS, синтаксис CREATE TABLE в них аналогичен.

Oracle

Microsoft SQL Server

CREATE TABLE
[schema.]table_name
(
{col_name column_properties
[default_expression] [constraint [constraint
[...constraint]]]| [[,] constraint]}
[[,] {next_col_name | next_constraint}...]
)
[Специфичные параметры хранения данных
Oracle]

CREATE TABLE [Server.][database.][owner.] table_name
(
{col_name column_properties[constraint
[constraint [...constraint]]]| [[,] constraint]}
[[,] {next_col_name | next_constraint}...]
)
[ON file group_name]

Имена объектов баз данных в Oracle не учитывают регистра клавиатуры. В Microsoft SQL Server имена объектов базы данных, в зависимости от настроек, могут учитывать регистр клавиатуры.

При первой установке SQL Server, порядок сортировки по умолчанию – это словарный порядок, без учета регистра. (Иные значения могут быть заданы в SQL Server Setup.) Поскольку имена объектов Oracle всегда уникальны, у вас не должно возникнуть проблем при переносе объектов базы данных в SQL Server. Рекомендуется указывать все имена таблиц и колонок как в Oracle, так и в SQL Server заглавными буквами, дабы избежать проблем при установке на SQL Server с учетом регистра.

Параметры хранения таблиц и индексов

В Microsoft SQL Server использование RAID обычно упрощает размещение объектов базы данных. Кластеризованный индекс SQL Server интегрирован в структуру таблицы, аналогично организованной по индексу таблице Oracle.

Oracle

Microsoft SQL Server

CREATE TABLE DEPT_ADMIN.DEPT (
DEPT       VARCHAR2(4) NOT NULL,
DNAME  VARCHAR2(30) NOT NULL,
CONSTRAINT DEPT_DEPT_PK
                                PRIMARY KEY (DEPT)
USING INDEX TABLESPACE USER_DATA
PCTFREE 0 STORAGE (INITIAL 10K NEXT 10K
MINEXTENTS 1 MAXEXTENTS UNLIMITED),
CONSTRAINT DEPT_DNAME_UNIQUE
                                UNIQUE (DNAME)
USING INDEX TABLESPACE USER_DATA
PCTFREE 0 STORAGE (INITIAL 10K NEXT 10K
MINEXTENTS 1 MAXEXTENTS UNLIMITED)
)
PCTFREE 10           PCTUSED 40
TABLESPACE USER_DATA
STORAGE (INITIAL 10K NEXT 10K
MINEXTENTS 1 MAXEXTENTS UNLIMITED
FREELISTS 1)

CREATE TABLE USER_DB.DEPT_ADMIN.DEPT (
DEPT       VARCHAR(4) NOT NULL,
DNAME  VARCHAR(30) NOT NULL,
CONSTRAINT DEPT_DEPT_PK
                PRIMARY KEY CLUSTERED (DEPT),
CONSTRAINT DEPT_DNAME_UNIQUE
                UNIQUE NONCLUSTERED (DNAME)
)

Создание таблиц с помощью инструкции SELECT

В Oracle таблица может быть создана на основе любой корректной команды SELECT. Microsoft SQL Server предоставляет те же возможности, но в ином синтаксисе.

Oracle

Microsoft SQL Server

CREATE TABLE STUDENTBACKUP AS SELECT * FROM STUDENT

SELECT * INTO STUDENTBACKUP
FROM STUDENT

SELECTINTO не будет работать, если в базе данных, в которой выполняется такая команда, параметр select into/bulkcopy не установлен в true. (Этот параметр может быть задан владельцем базы данных с помощью SQL Server Enterprise Manager или системной хранимой процедуры Transact-SQL sp_dboption.) Используйте системную хранимую процедуру sp_helpdb для проверки статуса базы данных. Даже в том случае, если select into/bulkcopy не установлен в true, вы можете использовать команду SELECT для копирования информации во временную таблицу:

SELECT * INTO #student_backup FROM user_db.student_admin.student

 

При создании новой таблицы с помощью SELECT.. INTO определения целостности ссылок не переносятся на новый объект.

Необходимость установки select into/bulkcopy в true может усложнить процесс миграции. Если вам необходимо копировать данные в таблицы с помощью инструкции SELECT, сначала создайте таблицу, а зачем используйте инструкцию INSERT INTOSELECT для загрузки данных. Синтаксис этой команды одинаков как в Oracle, так и в SQL Server, и не требует указания каких-либо параметров.

Представление данных

Синтаксис, используемый для создания представления данных в Microsoft SQL Server аналогичен Oracle.

Oracle

Microsoft SQL Server

CREATE [OR REPLACE] [FORCE |
NOFORCE] VIEW [schema.]view_name
[(column_name [, column_name]...)]
AS select_statement
[WITH CHECK OPTION [CONSTRAINT name]]
[WITH READ ONLY]

CREATE VIEW [owner.]view_name
[(column_name [, column_name]...)]
[WITH ENCRYPTION]
AS select_statement [WITH CHECK OPTION]

 

Представления данных SQL Server требуют наличия таблиц (и прав на доступ к ним у создателя представления данных), указанных в инструкции SELECT (аналогично опции FORCE в Oracle).

По умолчанию, инструкции изменения данных в представлениях данных не проверяются на соответствие изменяемых строк сфере действия представления данных. Для проверки всех изменений используйте WITH CHECK OPTION. Основным отличием между WITH CHECK OPTION является то, что Oracle определяет ее как ограничение, а SQL Server - нет. В остальном же функции аналогичны.

Oracle предоставляет опцию WITH READ ONLY при создании представления данных. Приложения на базе SQL Server могут достигнуть того же самого результата, предоставив всем пользователям представления данных только права SELECT.

Представления данных как SQL Server, так и в Oracle поддерживают производные колонки, использование арифметических выражений, функций и константных выражений. Вот некоторые из характерных отличий SQL Server:

§  Инструкции изменения данных (INSERT или UPDATE) допустимы на многотабличных представлениях данных в том случае, если они затрагивают только одну основную таблицу. Инструкции изменения данных не могут использоваться более чем на одной таблице за одну инструкцию.

§  READTEXT и WRITETEXT не могут быть использованы на колонках text или image в представлениях данных.

§  Не могут быть использованы операторы ORDER BY, COMPUTE, FOR BROWSE или COMPUTE BY.

§  В представлении данных не может быть использовано ключевое слово INTO.

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

Oracle

Microsoft SQL Server

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(DECODE(grade
                                                                ,'A', 4
                                                                ,'A+', 4.3
                                                                ,'A-', 3.7
                                                                ,'B', 3
                                                                ,'B+', 3.3
                                                                ,'B-', 2.7
                                                                ,'C', 2
                                                                ,'C+', 2.3
                                                                ,'C-', 1.7
                                                                ,'D', 1
                                                                ,'D+', 1.3
                                                                ,'D-', 0.7
                                                                ,0)),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(CASE grade
                                                WHEN 'A' THEN 4
                                                WHEN 'A+' THEN 4.3
                                                WHEN 'A-' THEN 3.7
                                                WHEN 'B' THEN 3
                                                WHEN 'B+' THEN 3.3
                                                WHEN 'B-' THEN 2.7
                                                WHEN 'C' THEN 2
                                                WHEN 'C+' THEN 2.3
                                                WHEN 'C-' THEN 1.7
                                                WHEN 'D' THEN 1
                                                WHEN 'D+' THEN 1.3
                                                WHEN 'D-' THEN 0.7
                                                ELSE 0
                                                END),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

Индексы

Microsoft SQL Server предлагает кластеризованные и некластеризованные индексные структуры. Эти индексы состоят из страниц, организующих древовидную структуру, известную как двоичное дерево (B-tree) (аналогично такой же структуре индекса в Oracle). Стартовая страница (корневой уровень) задает диапазоны значений в таблице. Каждый диапазон на корневой странице указывает ну следующую страницу (узел решения), содержащий более ограниченный диапазон значений таблицы. В свою очередь, эти узлы решений могут указывать на другие узлы решений, тем самым, уменьшая и уменьшая диапазон поиска. Последний уровень структуры называется уровнем листьев.

Кластеризованные индексы

Кластеризованные индексы реализованы в Oracle в виде таблиц, организованных по индексу. Кластеризованный индекс – это индекс, физически связанный с таблицей. Таблица и индекс размещены в одной области хранения. Кластеризованный индекс физически располагает данный в порядке индексации, образуя промежуточные узлы решений. Страницы-"листья" индекса содержат реальные данные из таблицы. Такая архитектура делает возможным наличие в таблице только одного индекса. Microsoft SQL Server автоматически создает кластеризованный индекс для таблицы при создании в таблице ограничения PRIMARY KEY или UNIQUE. Кластеризованные индексы полезны для:

§  Первичных ключей.

§  Колонок, в которые не вносится изменений.

§  Запросов, возвращающих область значений с помощью таких операторов как BETWEEN, >, >=, <, и <=, например:

SELECT * FROM STUDENT WHERE GRAD_DATE
BETWEEN '1/1/97' AND '12/31/97'

 

§  Запросов, возвращающих большое число записей:

SELECT * FROM STUDENT WHERE LNAME = 'SMITH'

§  Колонок, использующихся в операциях сортировки  (ORDER BY, GROUP BY).

Например, в таблице STUDENT, может оказаться полезным создать некластеризованный индекс на первичном ключе ssn, а кластеризованный индекс может быть создан на lname, fname, (фамилия, имя), поскольку так обычно группируют студентов.

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

Удаление и воссоздание кластеризованного индекса – это обычная техника при реорганизации таблицы в SQL Server. Это простой путь удостовериться  в том, что страницы данных находятся рядом на диске и восстановить некоторый объем свободного пространства в таблице. Это аналогично экспорту, удалению и последующему импорту таблицы в Oracle.

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

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

В таблице приведен фрагмент исходного кода примерного приложения. Обратите внимание на использование кластеризованного индекса SQL Server.

Oracle

Microsoft SQL Server

CREATE TABLE STUDENT_ADMIN.GRADE (
SSN   CHAR(9) NOT NULL,
CCODE        VARCHAR2(4) NOT NULL,
GRADE        VARCHAR2(2) NULL,
CONSTRAINT GRADE_SSN_CCODE_PK
     PRIMARY KEY (SSN, CCODE)
CONSTRAINT GRADE_SSN_FK
     FOREIGN KEY (SSN) REFERENCES
     STUDENT_ADMIN.STUDENT (SSN),
CONSTRAINT GRADE_CCODE_FK
     FOREIGN KEY (CCODE) REFERENCES
     DEPT_ADMIN.CLASS (CCODE)
)

CREATE TABLE STUDENT_ADMIN.GRADE (
SSN   CHAR(9) NOT NULL,
CCODE        VARCHAR(4) NOT NULL,
GRADE        VARCHAR(2) NULL,
CONSTRAINT GRADE_SSN_CCODE_PK
     PRIMARY KEY CLUSTERED (SSN,                 CCODE),
CONSTRAINT GRADE_SSN_FK
     FOREIGN KEY (SSN) REFERENCES
     STUDENT_ADMIN.STUDENT (SSN),
CONSTRAINT GRADE_CCODE_FK
     FOREIGN KEY (CCODE) REFERENCES
     DEPT_ADMIN.CLASS (CCODE)
)

Некластеризованные индексы

В некластеризованных индексах, данные индекса и таблицы физически разделены, а данные в таблице хранятся в порядке, не связанном с порядком индекса. Вы можете легко перенести определения индексов Oracle в определения некластеризованных индексов Microsoft SQL Server (как указано в нижеприведенном примере). Однако из соображений производительности вы можете выбрать один из индексов данной таблицы и сделать его кластеризованным индексом.

Oracle

Microsoft SQL Server

CREATE INDEX
STUDENT_ADMIN.STUDENT_MAJOR_IDX
ON STUDENT_ADMIN.STUDENT (MAJOR)
TABLESPACE USER_DATA
PCTFREE 0
STORAGE (INITIAL 10K NEXT 10K
     MINEXTENTS 1 MAXEXTENTS UNLIMITED)

CREATE NONCLUSTERED INDEX
STUDENT_MAJOR_IDX
ON USER_DB.STUDENT_ADMIN.STUDENT      (MAJOR)

Синтаксис и именование индексов

В Oracle имя индекса должно быть уникально внутри пользовательской учетной записи. В Microsoft SQL Server имя индекса должно быть уникально внутри таблицы, но не обязательно – внутри пользовательской учетной записи или базы данных. Таким образом, при удалении индекса в SQL Server вы должны задать и имя таблицы, и имя индекса. Более того, инструкция DROP INDEX в SQL Server может удалять несколько индексов одновременно.

Oracle

Microsoft SQL Server

CREATE [UNIQUE] INDEX [schema].index_name
     ON [schema.]table_name (column_name [, column_name]...)
[INITRANS n]
[MAXTRANS n]
[TABLESPACE tablespace_name]
[STORAGE storage_parameters]
[PCTFREE n]
[NOSORT]

DROP INDEX ABC;

CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED]
    INDEX index_name ON table (column [,…n])
[WITH
        [PAD_INDEX]
        [[,] FILLFACTOR = fillfactor]
        [[,] IGNORE_DUP_KEY]
        [[,] DROP_EXISTING]
        [[,] STATISTICS_NORECOMPUTE]
]
[ON file group]

DROP INDEX USER_DB.STUDENT.DEMO_IDX, USER_DB.GRADE.DEMO_IDX

Параметры хранения данных индекса

Параметр FILLFACTOR в Microsoft SQL Server работает во многом аналогично переменной PCTFREE в Oracle. По мере увеличения размера таблицы, страницы индекса делятся в соответствии с новыми данными. Индекс должен самореорганизовываться для соответствия новым данным. Процентное соотношение факторы заполнения используется только при создании индекса и в дальнейшем не поддерживается.

Параметр FILLFACTOR (корректные значения – от 0 до 100) управляет тем, сколько места оставляется на странице индекса при его создании. Фактор заполнения по умолчанию, использующийся в том случае, если этот параметр не задан – 0, что полностью заполняет листовые страницы индекса и оставляет место на каждой узловой странице как минимум еще для одной записи (двух в случае некластеризованного индекса).

Меньший фактор заполнения изначально уменьшает разбиение страниц и увеличивает число уровней в структуре бинарного дерева индекса. Больший фактор заполнения более эффективно использует пространство индекса, требует меньшего дискового ввода/вывода при доступе к индексу и уменьшает число уровней в структуре бинарного дерева индекса.

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

Если в Oracle может понадобиться уточнить параметр PCTFREE для оптимизации производительности, то в SQL Server указание параметр FILLFACTOR нужно редко. Фактор заполнения предоставлен как параметр тонкой настройки производительности. Он полезен только при создании индекса на таблице с уже существующими данными и только тогда, когда вы можете точно предсказать будущие изменения данных.

Если вы задавали PCTFREE как 0 в индексах Oracle, рассчитывайте на фактор заполнения в 100. Такие значения используются в таблицах без вставок или изменений (таблицах только для чтения). Когда фактор заполнения выставлен в 100, SQL Server создает индексы, в которых каждая страница заполнена на 100.

Игнорирование повторяющихся ключей

Как в Oracle, так и в Microsoft SQL Server, пользователи не могут вставлять повторяющиеся значение в колонку/колонки с уникальным индексом. Такая попытка создает сообщение об ошибке. И, тем не менее, SQL Server дает разработчику возможность выбирать, как инструкции INSERT или UPDATE среагируют на ошибку.

Если в инструкции CREATE INDEX было указано IGNORE_DUP_KEY, и была выполнена инструкция INSERT или UPDATE, создающая повторяющийся ключ, SQL Server выдает предупреждающее сообщение и игнорирует (не вставляет) строку с дубликатом. Если IGNORE_DUP_KEY не было задано для индекса, SQL Server выдает сообщение об ошибке и откатывает всю инструкцию INSERT. Более подробную информацию можно найти в SQL Server Books Online.

Использование временных таблиц

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

Microsoft SQL Server предоставляет временные объекты баз данных, создающиеся именно в таких целях. Эти таблицы всегда создаются в базе данных tempdb. Имя таблицы определяет срок ее жизни в базе данных tempdb.

Имя таблицы

Описание

#table_name

Эта локальная временная таблица существует только до конца сессии пользователя или процедуры, создавших ее. Она автоматически удаляется при выходе пользователя из системы или фиксации процедуры. Такие таблицы не могут совместно использоваться несколькими пользователями. Никакие другие пользователи баз данных не могут использовать такие таблицы. На такие таблицы не могут накладываться или отзываться права.

##table_name

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

Для временных таблиц могут быть созданы индексы. Представления данных могут быть определены только на основе таблиц, явно созданных в базе данных tempdb без префикса # или ##. В нижеприведенном примере показано создание временной таблицы и связанного с ней индекса. При выходе пользователя и таблицы, и индекс автоматически удаляются.

SELECT SUM(ISNULL(TUITION_PAID,0)) SUM_PAID, MAJOR INTO #SUM_STUDENT
FROM USER_DB.STUDENT_ADMIN.STUDENT GROUP BY MAJOR

CREATE UNIQUE INDEX SUM STUDENT IDX ON #SUM STUDENT (MAJOR)

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

Типы данных

Хотя некоторые преобразования данных из Oracle в SQL Server прямолинейны, остальные могут потребовать оценки некоторых вариантов. Рекомендуется использовать DTS Wizard для автоматизации создания новых инструкций CREATE TABLE. Эти инструкции предоставят вам рекомендуемые преобразования типов данных. Впоследствии вы можете изменить эти инструкции по мере надобности.

Oracle

Microsoft SQL Server

CHAR

Рекомендуется использование char. Колонки типа char обрабатываются несколько быстрее, нежели varchar благодаря тому, что они имеют фиксированную длину данных.

VARCHAR2
и LONG

varchar или text. (Если длина данных в колонке Oracle меньше или равна 8000 байтов, используйте varchar; иначе вам придется использовать text.)

RAW и
LONG RAW

varbinary или image. (Если длина данных в колонке Oracle меньше или равна 8000 байтов, используйте varbinary; иначе вам придется использовать image.)

NUMBER

Если это целое между 1 и 255, используйте tinyint.
Если это целое между -32768 и 32767, используйте
smallint.
Если это целое между -2,147,483,648 и 2,147,483,647 используйте
int.
Если вам нужно число с плавающей точкой, используйте
numeric (у него есть и точность, и основание).
Примечание: Не используйте
float или real, поскольку могут возникнуть ошибки округления (Oracle NUMBER и SQL Server numeric не округляются).
Если вы не уверены, используйте
numeric; этот тип данных во многом аналогичен типу данных NUMBER в Oracle.

DATE

datetime.

ROWID

Используйте тип колонки identity .

CURRVAL, NEXTVAL

Используйте тип колонки identity, и глобальную переменную @@identity, функции  IDENT_SEED() и IDENT_INCR().

SYSDATE

GETDATE()

USER

USER

Использование данных Unicode

Спецификация Unicode задает единую схему кодировки для практически всех символов, широко используемых в коммерции по всему миру. Все компьютеры единообразно преобразовывают битовые схемы данных Unicode, используя единую спецификацию Unicode. Это гарантирует, что одна и та же схема будет транслироваться в один и тот же символ на всех компьютерах. Данные могут свободно передаваться из одной базы данных в другую без проблем с корректной трансляцией битовых схем в символы.

Проблемой типов данных, использующих 1 байт для кодирования одного символа, является то, что такие типы данных могут отображать только 256 различных символов. Это приводит к существованию нескольких спецификаций кодирования (или кодовых страниц) для разных алфавитов. Также подобные типы данных не могут работать с алфавитами вроде японского Kanji или корейского Hangul, имеющими тысячи символов.

Microsoft SQL Server преобразует битовые схемы в колонках char, varchar, и text в соответствии с определениями из кодовой страницы, заданной для SQL Server. Клиентские компьютеры используют для интерпретации битовых схем кодовые страницы, заданные в операционных системах. Существует множество различных кодовых страниц. Некоторые символы присутствуют во всех кодовых страницах, но отсутствуют в других. Некоторые символы определены в одних таблицах одним набором битов, а в других – другим. При создании международных систем, которые должны работать с различными языками, возникает проблемы выбора кодовых страниц для всех компьютеров так, чтобы удовлетворить все языковые требования различных стран. Также обычно трудно гарантировать, что все компьютеры выполнят нужное преобразование при взаимодействии с системой, использующей другую кодовую страницу.

Спецификация Unicode решает эту проблему, используя 2 байта на представление каждого символа. В 2 байтах достаточно битовых комбинаций (65536) для большей части коммерческих языков. Поскольку все системы Unicode единообразно используют одни и те же схемы для отображения всех символов, не возникает проблем с некорректным отображением символов при переходе от системы к системе.

В SQL Server типы данных nchar, nvarchar, и ntext поддерживают данные Unicode. Более подробную информацию о типах данных SQL Server можно найти в SQL Server Books Online.

Типы данных, заданные пользователем

Пользовательские типы данных могут быть заданы в базе данных model или в отдельно взятой пользовательской базе данных. Если пользовательский тип данных  задан в model, он доступен во всех впоследствии создаваемых базах данных. Пользовательские типы данных определяются с помощью системной хранимой процедуры sp_addtype. Более подробную информацию можно найти в SQL Server Books Online.

Вы можете использовать пользовательский тип данных в инструкциях CREATE TABLE и ALTER TABLE, и привязывать к ним значений по умолчанию и правила. Если возможность принимать значения типа null явно задана при использовании пользовательского типа данных при создании таблицы, она имеет приоритет над той же возможностью, заданной при определении типа данных.

Этот пример демонстрирует создание пользовательского типа данных. Аргументами являются имя пользовательского типа данных, тип данных и возможность принимать значения типа null:

sp_addtype gender_type, 'varchar(1)', 'not null'
go

 

Эта возможность на первый взгляд способна решить проблему миграции сценариев создания таблиц из Oracle в SQL Server. Например, достаточно просто добавить тип данных Oracle DATE:

sp_addtype date, datetime

 

Это не работает с типами данных, требующими указания длины данных, как, к примеру, тип данных Oracle NUMBER. При этом возвращается сообщение об ошибке, указывающее на необходимость указания длины типа данных:

sp_addtype varchar2, varchar
Go
Msg 15091, Level 16, State 1
You must specify a length with this physical type.

 

Колонки Microsoft timestamp

Колонки типа timestamp делают возможным обновления в режиме BROWSE и делают более эффективными операции обновления курсоров. timestamp – это тип данных, автоматически обновляющийся при вставке или обновлении строки, содержащих колонки timestamp.

Значения в колонках timestamp хранятся не как реальное время или дата, а как данные типа binary(8) или varbinary(8), указывающие последовательность событий над рядами в таблице. В таблице может быть только одна колонка типа timestamp.

Более подробную информацию можно найти в SQL Server Books Online.

Права на уровне объектов

Права Microsoft SQL Server на уровне объектов могут быть назначены, запрещены или отозваны у прочих пользователей базы данных, групп базы данных и роли public. SQL Server не позволяет владельцу объекта даровать привилегии ALTER TABLE и CREATE INDEX, как то позволяет Oracle. Эти привилегии должны оставаться у владельца объекта.

Инструкция GRANT создает запись в системе безопасности, позволяющую пользователю текущей базы данных работать с данными в текущей базе данных или выполнять определенные инструкции Transact-SQL. Синтаксис инструкции GRANT идентичен в Oracle и SQL Server.

Инструкция Transact-SQL DENY создает запись в системе безопасности, запрещающую право в учетной записи и запрещающая учетной записи наследовать это право из групп или ролей, в которых она числится. В Oracle нет инструкции DENY.

Инструкция Transact-SQL REVOKE удаляет ранее назначенное или запрещенное право у пользователя данной базы данных.

Oracle

Microsoft SQL Server

GRANT {ALL [PRIVILEGES][column_list] | permission_list [column_list]}
ON {table_name [(column_list)]
 | view_name [(column_list)]
 | stored_procedure_name}
TO {PUBLIC | name_list }
[WITH GRANT OPTION]

GRANT
    {ALL [PRIVILEGES] | permission[,…n]}
    {
        [(column[,…n])] ON {table | view}
        | ON {table | view}[(column[,…n])]
        | ON {stored_procedure | extended_procedure}
    }
TO security_account[,…n]
[WITH GRANT OPTION]
[AS {group | role}]

REVOKE [GRANT OPTION FOR]
    {ALL [PRIVILEGES] | permission[,n]}
    {
        [(column[,n])] ON {table | view}
        | ON {table | view}[(column[,n])]
        | {stored_procedure | extended_procedure}
    }
{TO | FROM}
    security_account[,n]
[CASCADE]
[AS {group | role}]

DENY
    {ALL [PRIVILEGES] | permission[,…n]}
    {
        [(column[,…n])] ON {table | view}
        | ON {table | view}[(column[,…n])]
        | ON {stored_procedure | extended_procedure}
    }
TO security_account[,…n]
[CASCADE]

Более подробную информацию о правах уровня объекта можно найти в SQL Server Books Online.

В Oracle право REFERENCES может быть назначено только пользователю. В SQL Server право REFERENCES может быть назначено как пользователю, так и группе. Права INSERT, UPDATE, DELETE и SELECT налагаются одинаково в Oracle и SQL Server.

Реализация целостности данных и бизнес-правил

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

Тип целостности

Как реализуется

Целостность сущностей

Ограничения PRIMARY KEY

Ограничения UNIQUE

Свойство IDENTITY

Целостность домена

Определения DEFAULT в домене

Ограничения FOREIGN KEY

Ограничения CHECK

Возможность принимать значения типа null

Целостность ссылок

Ограничение FOREIGN KEY

Ограничение CHECK

Триггеры, реализующие функции Oracle CASCADE и DELETE

Целостность по требованию пользователя

Все ограничения в колонках и таблицах в CREATE TABLE

Хранимые процедуры

Триггеры

Целостность сущностей

Целостность сущностей определяет строку как уникальную сущность в данной таблице. Целостность сущностей гарантирует целостность идентификационной колонки (колонок) или первичного ключа в таблице с помощью индексов, ограничений UNIQUE, ограничений PRIMARY KEY и свойств IDENTITY.

Именование ограничений

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

CONSTRAINT constraint_name

Первичные ключи и уникальные колонки

Стандарт SQL-92 требует, чтобы все значения в первичном ключе были уникальными, и колонка не содержала данных типа null. Как Oracle, так и Microsoft SQL Server гарантируют уникальность посредством автоматического создания уникального индекса при создании ограничения PRIMARY KEY или UNIQUE. Вдобавок, колонки первичных ключей автоматически определяются как NOT NULL. В таблице может быть только один первичный ключ.

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

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

При переносе вашего приложения обратите внимание, что в SQL Server только одна строка в уникальном ключе может содержать NULL (индексы из одной или нескольких колонок), а в Oracle таких строк может быть несколько.

Oracle

Microsoft SQL Server

CREATE TABLE DEPT_ADMIN.DEPT
(DEPT VARCHAR2(4) NOT NULL,
DNAME VARCHAR2(30) NOT NULL,
CONSTRAINT DEPT_DEPT_PK
     PRIMARY KEY (DEPT)
     USING INDEX TABLESPACE USER_DATA
     PCTFREE 0 STORAGE (
     INITIAL 10K NEXT 10K
     MINEXTENTS 1 MAXEXTENTS UNLIMITED),
CONSTRAINT DEPT_DNAME_UNIQUE
     UNIQUE (DNAME)
     USING INDEX TABLESPACE USER_DATA
     PCTFREE 0 STORAGE (
     INITIAL 10K NEXT 10K
     MINEXTENTS 1 MAXEXTENTS UNLIMITED)
)

CREATE TABLE USER_DB.DEPT_ADMIN.DEPT
(DEPT     VARCHAR(4) NOT NULL,
DNAME  VARCHAR(30) NOT NULL,
CONSTRAINT DEPT_DEPT_PK
     PRIMARY KEY CLUSTERED (DEPT),
CONSTRAINT DEPT_DNAME_UNIQUE
     UNIQUE NONCLUSTERED (DNAME)
)

Добавление и удаление ограничений

Отключение ограничений может увеличить производительность базы данных и ускорить процесс репликации данных. К примеру, при воссоздании или репликации данных на удаленном узле вам не нужно повторять проверки ограничений, поскольку целостность данных уже была проверена при их вводе в базу данных. Вы можете запрограммировать приложение Oracle на отключение и включение ограничений  (за исключением PRIMARY KEY и UNIQUE). Рекомендуется использовать вариант NOT FOR REPLICATION для подавления ограничений на уровне колонок, внешних ключей и CHECK во время репликации.

В тех случаях, когда вы не реплицируете данные, и вам нужно удалить ограничение, вы можете выполнить это в Microsoft SQL Server , используя параметры CHECK и WITH NOCHECK в инструкции ALTER TABLE.

Иллюстрация демонстрирует сравнение этого процесса.

В SQL Server вы можете задержать все ограничения с помощью ключевого слова ALL в инструкции NOCHECK.

Если ваше приложение Oracle использует параметр CASCADE для отключения или удаления ограничение PRIMARY KEY или UNIQUE, вам может понадобиться переписать часть кода, поскольку параметр CASCADE отключает или удаляет как родительскую, так и все связанные ограничения целостности.

Вот пример такого синтаксиса:

DROP CONSTRAINT DEPT_DEPT_PK CASCADE

 

Приложения на основе SQL Server должны быть изменены таким образом, чтобы сначала удалять дочерние ограничения, а затем – родительские ограничения. К примеру, для удаления ограничения PRIMARY KEY в таблице DEPT, сначала должны быть удалены внешние ключи STUDENT.MAJOR и CLASS.DEPT. Вот пример такого синтаксиса:

ALTER TABLE STUDENT
DROP CONSTRAINT STUDENT_MAJOR_FK

ALTER TABLE CLASS
DROP CONSTRAINT CLASS_DEPT_FK

ALTER TABLE DEPT
DROP CONSTRAINT DEPT_DEPT_PK

 

Синтаксис ALTER TABLE, добавляющий и удаляющий ограничения, практически аналогичен в Oracle и SQL Server.

Создание последовательных числовых значений

Если ваше приложение Oracle использует SEQUENCE, оно легко может быть приведено к использованию свойства IDENTITY Microsoft SQL Server.

Категория

Microsoft SQL Server IDENTITY

Синтаксис

CREATE TABLE new_employees
( Empid int IDENTITY (1,1), Employee_Name varchar(60),
CONSTRAINT Emp_PK PRIMARY KEY (Empid)
)
If increment interval is 5:
CREATE TABLE new_employees
( Empid int IDENTITY (1,5), Employee_Name varchar(60),
CONSTRAINT Emp_PK PRIMARY KEY (Empid)
)

Число колонок Identity в таблице

Одна

Возможность введения значений Null

Нет

Использование ограничений и значений по умолчанию,

Не могут быть использованы

Претворение в жизнь уникальности

Да

Запрос текущего максимального числа identity после выполнения операций INSERT, SELECT INTO или массового копирования

@@IDENTITY (function)

Возврат начального значения, заданного при создании колонки identity

IDENT_SEED('table_name')

Возврат прироста, заданного при создании колонки identity

IDENT_INCR('table_name')

SELECT syntax

Ключевое слово IDENTITYCOL может использоваться вместо имени колонки при ссылке на таблицу, использующую колонку со свойством IDENTITY, в инструкциях SELECT, INSERT, UPDATE и DELETE.

Хотя свойство IDENTITY автоматизирует нумерацию строк в одной таблице, отдельные таблицы, каждая со своей колонкой идентификатора, могут создать одни и те же значения. Это связано с тем, что свойство IDENTITY гарантировано уникально только в таблице, в которой используется. Если приложению нужно создавать колонку идентификатора, уникальную во всей базе данных, или любой базе данных на любом сетевом компьютере в мире, используйте свойство ROWGUIDCOL, тип данных uniqueidentifier и функцию NEWID. SQL Server использует колонки глобально уникальных идентификаторов при репликации сведением для гарантирования того, что строки уникально идентифицируются во всех копиях таблицы.

Более подробную информацию о создании и изменении колонок идентификаторов можно найти в SQL Server Books Online.

Целостность домена

Целостность домена гарантирует корректность данных в данной колонке. Целостность домена гарантируется ограничением типа (с помощью типов данных), формата (с помощью ограничений CHECK) или диапазона возможных значений (с помощью ограничений REFERENCE и CHECK).

Ограничения DEFAULT и CHECK

Oracle рассматривает значение по умолчанию как свойство колонки, Microsoft SQL Server – как ограничение. Ограничение DEFAULT в SQL Server может содержать константы, встроенные функции, не требующие аргументов (нуль-арные функции) или NULL.

Для упрощения миграции свойств колонок DEFAULT из Oracle, вам следует определять ограничения DEFAULT на уровне колонок в SQL Server без применения имен ограничений. SQL Server сам создает уникальные имена для каждого ограничения DEFAULT.

Синтаксис, используемый для определения ограничений CHECK, одинаков как в Oracle, так и в SQL Server. Условие поиска должно сводиться к булевому выражению и не может содержать подзапросы. Ограничения CHECK на уровне колонок могут ссылаться только на ограничиваемую колонку, а ограничения уровня таблицы – только на колонки ограничиваемой таблицы. В одной таблицы могут быть заданы несколько ограничений CHECK. Синтаксис SQL Server позволяет создавать только одно ограничение CHECK уровня колонки на колонку в инструкции CREATE TABLE, а ограничение может иметь несколько условий.

Лучшим методом тестирования ваших измененных инструкций CREATE TABLE является использование SQL Server Query Analyzer в SQL Server, и только обработать синтаксис. В панели результатов будут указаны все ошибки. Более подробную информацию о синтаксисе ограничений можно найти в SQL Server Books Online.

Oracle

Microsoft SQL Server

CREATE TABLE STUDENT_ADMIN.STUDENT (
SSN CHAR(9) NOT NULL,
FNAME VARCHAR2(12) NULL,
LNAME VARCHAR2(20) NOT NULL,
GENDER CHAR(1) NOT NULL
     CONSTRAINT STUDENT_GENDER_CK
     CHECK (GENDER IN ('M','F')),
MAJOR VARCHAR2(4)
     DEFAULT 'Undc' NOT NULL,
BIRTH_DATE DATE NULL,
TUITION_PAID NUMBER(12,2) NULL,
TUITION_TOTAL NUMBER(12,2) NULL,
START_DATE DATE NULL,
GRAD_DATE DATE NULL,
LOAN_AMOUNT NUMBER(12,2) NULL,
DEGREE_PROGRAM CHAR(1)
     DEFAULT 'U' NOT NULL
     CONSTRAINT STUDENT_DEGREE_CK CHECK
     (DEGREE_PROGRAM IN ('U', 'M', 'P', 'D')),
...

CREATE TABLE USER_DB.STUDENT_ADMIN.STUDENT (
SSN CHAR(9) NOT NULL,
FNAME VARCHAR(12) NULL,
LNAME VARCHAR(20) NOT NULL,
GENDER CHAR(1) NOT NULL
     CONSTRAINT STUDENT_GENDER_CK
     CHECK (GENDER IN ('M','F')),
MAJOR VARCHAR(4)
     DEFAULT 'Undc' NOT NULL,
BIRTH_DATE DATETIME NULL,
TUITION_PAID NUMERIC(12,2) NULL,
TUITION_TOTAL NUMERIC(12,2) NULL,
START_DATE DATETIME NULL,
GRAD_DATE DATETIME NULL,
LOAN_AMOUNT NUMERIC(12,2) NULL,
DEGREE_PROGRAM CHAR(1)
     DEFAULT 'U' NOT NULL
     CONSTRAINT STUDENT_DEGREE_CK
           CHECK
     (DEGREE_PROGRAM IN ('U', 'M', 'P', 'D')),
...

Замечание по заданным пользователем правилам и значениям по умолчанию: синтаксис правил и значений по умолчанию Microsoft SQL Server остается из соображений обратной совместимости, но для разработки новых приложений рекомендуется использовать ограничения CHECK и DEFAULT. Более подробную информацию можно найти в SQL Server Books Online.

Возможность принимать значения типа null

Microsoft SQL Server и Oracle создают ограничения колонок для гарантирования возможности принимать значения типа null. Колонки Oracle по умолчанию сводится к NULL, до тех пор, пока NOT NULL не указано в инструкциях CREATE TABLE или ALTER TABLE. В Microsoft SQL Server, параметры базы данных и сессии могут "затереть" возможность типа данных принимать значения типа null, указанные в описании колонки.

Всем вашим сценариям SQL (как в Oracle, так и в SQL Server) следует явно определять и NULL, и NOT NULL для каждой колонки. За примерами реализации этой стратегии смотри Oratable.sql и Sstable.sql, сценарии создания примерных таблиц. В случае отсутствия явного определения возможность колонки принимать значения типа null следуют следующим правилам.

Параметры Null

Описание

В колонке задан тип данных, определенный пользователем

Microsoft SQL Server использует возможность принимать значения типа null при, заданную при создании типа данных. Используйте системную хранимую процедуру sp_help для получения информации о возможности типа данных принимать значения типа null .

В колонке задан тип данных, предоставляемый системой

В случае если тип данных, предоставляемый системой, дает только один вариант, этот вариант имеет приоритет. На данный момент, тип данных bit может быть задан только как NOT NULL.
Если какие-либо параметры сессии установлены в ON (с помощью SET), то:
     Если ANSI_NULL_DFLT_ON установлено в ON,       задается NULL.
     Если ANSI_NULL_DFLT_OFF установлено в ON, задается NOT NULL.
Если установлены какие-либо настройки базы данных (с помощью системной хранимой процедуры sp_dboption), то:
     Если ANSI null default установлено в true, задается NULL.
     Если ANSI null default установлено в false, задается NOT NULL.

NULL/NOT NULL
на задано

Если явно не задано (никакая из настроек ANSI_NULL_DFLT не установлена), сессия не изменялась и в базе данных сохранены настройки по умолчанию (ANSI null default установлено в false), то SQL Server задает NOT NULL.

Целостность ссылок

В таблице приведено сравнение синтаксисов, используемых для определения целостности ссылок.

Constraint

Oracle

Microsoft SQL Server

PRIMARY KEY

[CONSTRAINT constraint_name]
PRIMARY KEY (col_name [, col_name2 [..., col_name16]])
[USING INDEX storage_parameters]

[CONSTRAINT constraint_name]
PRIMARY KEY [CLUSTERED | NONCLUSTERED] (col_name [, col_name2 [..., col_name16]])
[ON segment_name]
[NOT FOR REPLICATION]

UNIQUE

[CONSTRAINT constraint_name]
UNIQUE (col_name [, col_name2 [..., col_name16]])
[USING INDEX storage_parameters]

[CONSTRAINT constraint_name]
UNIQUE [CLUSTERED | NONCLUSTERED](col_name [, col_name2 [..., col_name16]])
[ON segment_name]
[NOT FOR REPLICATION]

FOREIGN KEY

[CONSTRAINT constraint_name]
[FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
[ON DELETE CASCADE]

[CONSTRAINT constraint_name]
[FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
[NOT FOR REPLICATION]

DEFAULT

Свойство колонки, а не ограничение
DEFAULT (constant_expression)

[CONSTRAINT constraint_name]
DEFAULT {constant_expression | niladic-function | NULL}
[FOR col_name]
[NOT FOR REPLICATION]

CHECK

[CONSTRAINT constraint_name]
CHECK (expression)

[CONSTRAINT constraint_name]
CHECK [NOT FOR REPLICATION] (expression)

Параметр NOT FOR REPLICATION используется для подавления ограничений уровня колонки, FOREIGN KEY и CHECK при репликации.

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

Правила определения внешних ключей аналогичны в обеих RDBMS. Число колонок и тип данных каждой колонки, указанной в инструкции внешнего ключа, должно соответствовать инструкции REFERENCES. Значение, не равное null, введенное в таких колонках, должно существовать в таблице и колонках, заданных инструкцией REFERENCES, а колонки таблицы, на которую идет ссылка, должны иметь ограничение PRIMARY KEY или UNIQUE.

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

Как Oracle, так и SQL Server поддерживают таблицы, ссылающиеся сами на себя, т.е. такие таблицы, в которых ссылка (внешний ключ) относится к одной или нескольким колонкам той же таблицы. К примеру, колонка prereq в таблице CLASS может ссылаться на колонку ccode таблицы CLASS для того, чтобы гарантировать введение корректного кода курса в поле предварительного условия.

В то время как каскадные обновления и удаления реализованы в Oracle инструкцией CASCADE DELETE, SQL Server предоставляет такие же возможности с помощью триггеров таблиц. Более подробную информацию можно найти в разделе “SQL Language Support” данного документа.

Целостность по требованию пользователя

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

Хранимые процедуры

Хранимые процедуры Microsoft SQL Server используют инструкцию CREATE PROCEDURE для того, чтобы принимать и возвращать переданные пользователям параметры. Все хранимые процедуры, за исключением временных хранимых процедур, создаются в текущей базе данных. В таблице приведен синтаксис в Oracle и SQL Server.

Oracle

Microsoft SQL Server

CREATE OR REPLACE PROCEDURE [user.]procedure
    [(argument [IN | OUT] datatype
    [, argument [IN | OUT] datatype]
{IS | AS} block

 

CREATE PROC[EDURE] procedure_name [;number]
    [
        {@parameter data_type} [VARYING] [= default] [OUTPUT]
    ]
    [,…n]
[WITH
    { RECOMPILE   | ENCRYPTION  | RECOMPILE, ENCRYPTION} ]
[FOR REPLICATION]
AS
    sql_statement […n]

В SQL Server временные процедуры создаются в базе данных tempdb с помощью добавления префиксов: или одного символа # к  procedure_name (#procedure_name) для локальных временных процедур или двух (##procedure_name) – для глобальных.

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

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

Хранимые процедуры SQL Server могут иметь до 32 уровней вложенности. Уровень вложенности увеличивается при начале выполнения вызванной процедуры, и уменьшается при фиксации ее выполнения.

В нижеприведенном примере демонстрируется, как хранимая процедура Transact-SQL может быть использована для замещения пакованной функции Oracle PL/SQL. В данном примере версия Transact-SQL значительно проще благодаря возможности SQL Server возвращать результирующие наборы записей напрямую из инструкции SELECT в хранимой процедуре без использования курсора.

Oracle

Microsoft SQL Server

CREATE OR REPLACE PACKAGE STUDENT_ADMIN.P1 AS
     ROWCOUNT NUMBER :=0;
     CURSOR C1 RETURN STUDENT%ROWTYPE;
     FUNCTION SHOW_RELUCTANT_STUDENTS
          (WORKVAR OUT VARCHAR2) RETURN NUMBER;
END P1;
/

CREATE OR REPLACE PACKAGE BODY STUDENT_ADMIN.P1 AS
     CURSOR C1 RETURN STUDENT%ROWTYPE IS
           SELECT * FROM STUDENT_ADMIN.STUDENT
                                                WHERE NOT EXISTS
           (SELECT 'X' FROM STUDENT_ADMIN.GRADE
           WHERE GRADE.SSN=STUDENT.SSN) ORDER BY SSN;

FUNCTION SHOW_RELUCTANT_STUDENTS
     (WORKVAR OUT VARCHAR2) RETURN NUMBER IS
     WORKREC STUDENT%ROWTYPE;
     BEGIN
           IF NOT C1%ISOPEN THEN OPEN C1;
           ROWCOUNT :=0;
           ENDIF;
           FETCH C1 INTO WORKREC;
           IF (C1%NOTFOUND) THEN
                CLOSE C1;
                ROWCOUNT :=0;
           ELSE
                WORKVAR := WORKREC.FNAME||' '||WORKREC.LNAME||
                ', social security number '||WORKREC.SSN||' is not enrolled
                                                in any classes!';
                ROWCOUNT := ROWCOUNT + 1;
           ENDIF;
RETURN(ROWCOUNT);

EXCEPTION
     WHEN OTHERS THEN
           IF C1%ISOPEN THEN CLOSE C1;
                ROWCOUNT :=0;
           ENDIF;
           RAISE_APPLICATION_ERROR(-20001,SQLERRM);
END SHOW_RELUCTANT_STUDENTS;
END P1;
/

CREATE PROCEDURE
STUDENT_ADMIN.SHOW_RELUCTANT_STUDENTS
AS SELECT FNAME+'' +LNAME+', social security
     number'+ SSN+' is not enrolled in any classes!'
FROM STUDENT_ADMIN.STUDENT S
WHERE NOT EXISTS
     (SELECT 'X' FROM STUDENT_ADMIN.GRADE G
     WHERE G.SSN=S.SSN)
ORDER BY SSN
RETURN@@ROWCOUNT
GO

SQL Server не поддерживает конструкций, аналогичных пакетам или функциям Oracle и н поддерживает параметра CREATE OR REPLACE при создании хранимых процедур.

Отложенное выполнение хранимой процедуры

Microsoft SQL Server предоставляет инструкцию WAITFOR, позволяющую разработчикам задавать время, временной интервал или событие, запускающие выполнение блока инструкцией, хранимой процедуры или транзакции. Это Transact-SQL-эквивалент dbms_lock.sleep в Oracle.

WAITFOR {DELAY 'time' | TIME 'time'}

где

DELAY:

Указывает Microsoft SQL Server на необходимость ожидания истечения казанного промежутка времени (до 24 часов).

'time':

Ожидаемое время. time может быть задано в любом формате, приемлемом для данных datetime, или же может быть задано как локальная переменная. Даты не могут быть заданы; таким образом не разрешается ввод той части данных datetime, где хранится дата.

TIME:

Указывает SQL Server на необходимость ждать наступления указанного времени.

Например:

BEGIN

    WAITFOR TIME '22:20'

    EXECUTE update_all_stats

END

 

Указание параметров в хранимой процедуре

Для указания параметров в хранимых процедурах используйте следующий синтаксис.

Oracle

Microsoft SQL Server

Varname datatype
DEFAULT <value>;

{@parameter data_type} [VARYING] [= default] [OUTPUT]

Триггеры

Как Oracle, так и Microsoft SQL Server поддерживают триггеры, но реализуют их несколько по-разному.

Описание

Oracle

Microsoft SQL Server

Число триггеров на таблицу

Неограниченно

Неограниченно

Триггеры, выполняемые перед инструкциями INSERT, UPDATE, DELETE

Да

Нет

Триггеры, выполняемые после инструкций INSERT, UPDATE, DELETE

Да

Да

Триггеры уровня инструкции

Да

Да

Триггеры уровня ряда

Да

Нет

Ограничения выполняются перед выполнением

Да, если триггер не отключен.

Да. Более того, это настраивается в Data Transformation Services

Ссылка на старые значения в триггерах UPDATE или DELETE

:old

DELETED.column

Ссылка на новые значения в триггере INSERT

:new

INSERTED.column

Отключение триггеров

ALTER TRIGGER

Настройка в Data Transformation Services

DELETED и INSERTED – это логические (концептуальные таблицы), создаваемые SQL Server для триггеров. Они структурно аналогичны таблице, на которой определен триггер и содержат старые или новые значения строк, которые могут быть изменены действиями пользователя. Эти таблицы отслеживают изменения уровня строки в Transact-SQL. Эти таблицы предоставляют те же возможности, что и триггеры уровня строки в Oracle. При выполнении инструкции INSERT, UPDATE или DELETE в SQL Server строки одновременно добавляются в таблицу триггеров и в таблицы INSERTED и DELETED.

Таблицы INSERTED и DELETED идентичны таблице триггеров. У них те же самые имена колонок и типы данных. Например, если триггер построен на таблице GRADE, таблицы INSERTED и DELETED имеют следующую структуру.

GRADE

INSERTED

DELETED

SSN CHAR(9)
CCODE VARCHAR(4)
GRADE VARCHAR(2)

SSN CHAR(9)
CCODE VARCHAR(4)
GRADE VARCHAR(2)

SSN CHAR(9)
CCODE VARCHAR(4)
GRADE VARCHAR(2)

Таблицы INSERTED и DELETED могут быть исследованы триггером на предмет определение того, какие действия должны быть предприняты триггером. Таблица INSERTED используется в инструкциях INSERT и UPDATE. Таблица DELETED используется в инструкциях DELETE и UPDATE.

Инструкция UPDATE использует таблицы INSERTED и DELETED, поскольку SQL Server всегда удаляет старые строки и вставляет новые при выполнении инструкции UPDATE. Следовательно, при выполнении инструкции UPDATE строки в таблице INSERTED всегда дублируют строки в таблице DELETED.

В нижеприведенном примере таблицы INSERTED и DELETED используются для замены триггера PL/SQL уровня строки. Для запроса всех строк из обеих таблиц используется полная внешняя связь.

Oracle

Microsoft SQL Server

CREATE TRIGGER      STUDENT_ADMIN.TRACK_GRADES
AFTER
INSERT OR UPDATE OR DELETE
ON STUDENT_ADMIN.GRADE
FOR EACH ROW
BEGIN
INSERT INTO GRADE_HISTORY(
     TABLE_USER, ACTION_DATE,
     OLD_SSN, OLD_CCODE, OLD_GRADE,
     NEW_SSN, NEW_CCODE, NEW_GRADE)
VALUES (USER, SYSDATE,
     :OLD.SSN, :OLD.CCODE, :OLD.GRADE,
     :NEW.SSN, :NEW.CCODE, :NEW.GRADE),
END;

CREATE TRIGGER STUDENT_ADMIN.TRACK_GRADES
ON STUDENT_ADMIN.GRADE
FOR INSERT, UPDATE, DELETE
AS
INSERT INTO GRADE_HISTORY(
     TABLE_USER, ACTION_DATE,
     OLD_SSN, OLD_CCODE, OLD_GRADE
     NEW_SSN, NEW_CCODE, NEW_GRADE)
SELECT USER, GETDATE(),
     OLD.SSN, OLD.CCODE, OLD.GRADE,
     NEW.SSN, NEW.CCODE, NEW.GRADE
FROM INSERTED NEW FULL OUTER JOIN
           DELETED OLD ON NEW.SSN = OLD.SSN

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

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

Описательная целостность ссылок (declarative referential integrity, DRI) в Microsoft SQL Server не предоставляет возможности целостности ссылок между базами данных. Если требуются такие возможности, используйте триггеры. В триггерах недопустимы следующие инструкции Transact-SQL:

§  Инструкции CREATE (DATABASE, TABLE, INDEX, PROCEDURE, DEFAULT, RULE, TRIGGER, SCHEMA и VIEW)

§  Инструкции DROP (TRIGGER, INDEX, TABLE, PROCEDURE, DATABASE, VIEW, DEFAULT, RULE)

§  Инструкции ALTER (DATABASE, TABLE, VIEW, PROCEDURE, TRIGGER)

§  TRUNCATE TABLE

§  GRANT, REVOKE, DENY

§  UPDATE STATISTICS

§  RECONFIGURE

§  UPDATE STATISTICS

§  RESTORE DATABASE, RESTORE LOG

§  LOAD LOG, DATABASE

§  Инструкции DISK

§  SELECT INTO (поскольку она создает таблицу)

Более подробную информацию о триггерах можно найти в SQL Server Books Online.

Транзакции, блокировка и параллелизм

Этот раздел объясняет, как выполняются транзакции в Oracle и Microsoft SQL Server, и указывает на разницу в блокировочных процессах и вопросах параллелизма в обоих типах баз данных.

Транзакции

В Oracle транзакция автоматически начинается при выполнении операции вставки, обновления или удаления. Приложение должно выдать команду COMMIT, ожидая сохранения изменений в базе данных. Если команда COMMIT не выдана, все изменения автоматически откатываются.

По умолчанию Microsoft SQL Server автоматически выдает команду COMMIT после каждой операции вставки, обновления или удаления. Поскольку данные автоматически сохраняются, вы не можете откатить какие-либо изменения.

Вы можете начать транзакцию в Microsoft® SQL Serverкак явную, неявную или транзакцию с автоматическим подтверждением. Автоматическое подтверждение является поведением по умолчанию; для изменения этого режима вы можете воспользоваться явным или неявным режимами транзакций.

§  Транзакции с автоматическим подтверждением

Это режим по умолчанию в SQL Server. Каждая отдельная инструкция Transact-SQL автоматически подтверждается по фиксации. Для управления транзакциями вам не нужно выдавать никаких инструкций.

§  Неявные транзакции

Как и в Oracle, неявная транзакция начинается при выполнении инструкций INSERT, UPDATE, DELETE или иных инструкций управления данными. Для того чтобы сделать возможными неявные транзакции, используйте инструкцию SET IMPLICIT_TRANSACTIONS ON.

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

§  Явные транзакции

Явная транзакция – это группа инструкций SQL, окруженная нижеприведенными разделителями транзакций. Обратите внимание, что BEGIN TRANSACTION и COMMIT TRANSACTION являются обязательными:

§  BEGIN TRANSACTION [transaction_name]

§  COMMIT TRANSACTION [transaction_name]

§  ROLLBACK TRANSACTION [transaction_name | savepoint_name]

§  SAVE TRAN[SACTION] {savepoint_name | @savepoint_variable}

Инструкция SAVE TRANSACTION действует аналогично команде SAVEPOINT в Oracle, устанавливая точку сохранения, с которой можно начать частичный откат.

В нижеприведенном примере, отделение English изменяется на Literature. Обратите внимание на использование инструкций BEGIN TRANSACTION и COMMIT TRANSACTION.

Oracle

Microsoft SQL Server

INSERT INTO DEPT_ADMIN.DEPT (DEPT, DNAME)
VALUES ('LIT', 'Literature')
/
UPDATE DEPT_ADMIN.CLASS
SET MAJOR = 'LIT'
WHERE MAJOR = 'ENG'
/
UPDATE STUDENT_ADMIN.STUDENT
SET MAJOR = 'LIT'
WHERE MAJOR = 'ENG'
/
DELETE FROM DEPT_ADMIN.DEPT
WHERE DEPT = 'ENG'
/
COMMIT
/

BEGIN TRANSACTION

INSERT INTO DEPT_ADMIN.DEPT (DEPT, DNAME)
VALUES ('LIT', 'Literature')

UPDATE DEPT_ADMIN.CLASS
SET DEPT = 'LIT'
WHERE DEPT = 'ENG'

UPDATE STUDENT_ADMIN.STUDENT
SET MAJOR = 'LIT'
WHERE MAJOR = 'ENG'

DELETE FROM DEPT_ADMIN.DEPT
WHERE DEPT = 'ENG'

COMMIT TRANSACTION
GO

Транзакции могут быть вложены одна в другую. В этом случае, внешняя пара инструкций создает и подтверждает транзакцию, а внутренние пары отслеживают уровень вложенности. При обнаружении вложенной транзакции увеличивается функция @@TRANCOUNT. Обычно подобное вложение транзакций происходит при вызове хранимыми процедурами или триггерами, содержащими инструкции BEGINCOMMIT, аналогичных процедур. Хотя транзакции и могут быть вложены, это мало влияет на поведение инструкции ROLLBACK TRANSACTION.

В хранимых процедурах и триггерах число инструкций BEGIN TRANSACTION должно соответствовать числу инструкций COMMIT TRANSACTION. Хранимая процедура или триггер, содержащие непарные инструкции BEGIN TRANSACTION и COMMIT TRANSACTION, выводят сообщение об ошибке при выполнении. Синтаксис позволяет вызывать хранимые процедуры и триггеры изнутри транзакций в том случае, если они содержат инструкции BEGIN TRANSACTION и COMMIT TRANSACTION.

По возможности разбивайте большие транзакции на несколько маленьких. Удостоверьтесь, что каждая транзакция вполне определена внутри одного пакета. Для минимизации возможных конфликтов параллелизма, транзакции не должны занимать нескольких пакетов или ждать пользовательского ввода. Группировка нескольких инструкций Transact-SQL в одну длинную транзакцию может отрицательно повлиять на время восстановления и привести к проблемам параллелизма.

При программировании в ODBC вы можете выбрать режим неявных или явных транзакций с помощью функции SQLSetConnectOption. Выбор программой ODBC одного или другого зависит от установки параметра AUTOCOMMIT. Если AUTOCOMMIT установлено в ON (по умолчанию), вы находитесь в явном режиме. Если  AUTOCOMMIT установлено в OFF, вы находитесь в неявном режиме.

При выдаче сценария через SQL Server Query Analyzer или иные инструменты запроса, вы можете или использовать явную инструкцию BEGIN TRANSACTION, описанную ранее, или же начать сценарий с инструкции SET IMPLICIT_TRANSACTIONS ON. Подход с BEGIN TRANSACTION более гибок, подход с неявными транзакциями более совместим с Oracle.

Блокировка и изолирование транзакций

Одной из ключевых функций системы управления базами данных (database management system, DBMS) является гарантирование того, что несколько пользователей могут одновременно читать и писать данные в базу данных без получения противоречивого набора записей, связанного с происходящими изменениями в базе данных и без случайного затирания чужих изменений. Oracle и Microsoft® SQL Serverиспользуют разные стратегии блокировки и изоляции для решения этой проблемы. Вам следует принять эти различия во внимание при миграции приложения из Oracle в SQL Server; в противном случае ваше приложение может плохо масштабироваться на большое число пользователей.

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

Авторы данных в Oracle запрашивают блокировку на данные, которые должны быть обновлены, удалены или вставлены. Такие блокировки держатся до конца транзакции, и не дают прочим пользователям затереть неподтвержденные изменения.

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

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

Динамическая блокировка

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

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

§  Увеличение производительности, поскольку SQL Server минимизирует перегрузку системы, используя тот тип блокировки, который наиболее подходит к задаче.

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

Неспособность Oracle расширять блокировку уровня строки может привести к проблемам в запросах, включающих пункт FOR UPDATE и UPDATE, запрашивающих большое число строк. К примеру, будем считать, что таблица STUDENT имеет 100,000 рядов, и пользователь Oracle выдает следующую инструкцию обратите внимание, что задействовано 100,000 строк:

UPDATE STUDENT set (col) = (value);

RDBMS Oracle по очереди блокирует каждую строку в таблице STUDENT, что может занять некоторое время и потребует большого объема системных ресурсов. Oracle не расширяет запрос на блокировку всей таблицы.

Та же самая инструкция в SQL Server может привести (по умолчанию) к тому, что блокировка уровня строки расширится до блокировки уровня таблицы, что быстрее и эффективнее.

Изменение поведения блокировки по умолчанию

Как Microsoft SQL Sever, так и Oracle используют один и тот же уровень изоляции транзакций по умолчанию  – “READ COMMITTED”. Обе базы данных также дают разработчику возможность запрашивать иные режимы блокировки и изоляции. В Oracle наиболее употребимыми механизмами являются инструкция FOR UPDATE в команде SELECT, команда SET TRANSACTION READ ONLY и явная команда LOCK TABLE.

Из-за различий в стратегии блокировки и изоляции, сложно напрямую привязать эти параметры блокировки Oracle к SQL Server. Для получения более полного понимания этого процесса важно понимать те возможности, которые SQL Server предоставляет для изменения режима блокировки по умолчанию.

В SQL Server наиболее используемым механизмом изменения механизма блокировки по умолчанию является инструкция SET TRANSACTION ISOLATION LEVEL и рекомендации блокировки, поддерживаемые инструкциями SELECT и UPDATE. Инструкция SET TRANSACTION ISOLATION LEVEL задает уровни изоляции транзакции на период пользовательской сессии. Заданные параметр становится режимом по умолчанию, используемом в том случае, если в пункте FROM инструкции SQL не указана иная рекомендация блокировки. Изоляция транзакции задается приблизительно так:

SET TRANSACTION ISOLATION LEVEL
    {
        READ COMMITTED
        | READ UNCOMMITTED
        | REPEATABLE READ
        | SERIALIZABLE
    }

 

READ COMMITTED

Эта настройка задана в SQL Server по умолчанию. Разделенные блокировки удерживаются в течение периода чтения данных во избежание "грязного" (dirty) чтения, но данные могут быть изменены до конца транзакции, что может привести к неповторяющимся чтениям или фантомным данным.

READ UNCOMMITTED

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

REPEATABLE READ

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

SERIALIZABLE

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

SQL Server реализует все четыре стандартных ANSI-уровня изоляции транзакций; Oracle – только READ COMMITTED”, являющийся режимом по умолчанию, и SERIALIZABLE.”

SQL Server напрямую не поддерживает нестандартного по ANSI уровня изоляции транзакции READ ONLY, поддерживаемого Oracle. Если транзакция в приложении требует возможности повторного чтения, вам может понадобиться использовать уровень изоляции SERIALIZABLE, предлагаемый SQL Server. Если весь доступ к базе данных идет только для чтения, вы можете повысить производительность, установив настройку базы данных SQL Server в READ ONLY.

SELECTFOR UPDATE

Инструкция SELECTFOR UPDATE в Oracle используется тогда, когда приложению необходимо выдавать позиционируемые обновления или удаления в курсоре с помощью синтаксиса WHERE CURRENT OF. В данном случае, возможно удаление пункта FOR UPDATE; поскольку курсоры SQL Server по умолчанию поддерживают обновление.

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

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

Эта рекомендация не блокирует доступ остальным читателям, но не дает потенциальным авторам получить такую же блокировку данных. При использовании ODBC, вы также можете достичь аналогичного эффекта с помощью SQLSETSTMTOPTION (…,SQL_CONCURRENCY)= SQL_CONCUR_LOCK. Любая из этих установок уменьшает параллелизм.

Явное затребование блокировки уровня таблицы

Microsoft SQL Server может предоставлять те же функции блокировки таблиц, что и Oracle.

Возможность

Oracle

Microsoft SQL Server

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

LOCK TABLE…IN SHARE MODE

SELECT…table_name (TABLOCK)

 

Блокировка таблицы до конца транзакции

 

SELECT…table_name (TABLOCK REPEATABLEREAD)

Исключительная блокировка не дает остальным пользователям возможности читать или обновлять таблицу и удерживается до конца команды или транзакции

LOCK TABLE…IN EXCLUSIVE MODE

SELECT…table_name (TABLOCKX)

Указание числа миллисекунд, в течение которых инструкция ожидает освобождения блокировки.

NOWAIT works like “LOCK_TIMEOUT 0”

LOCK_TIMEOUT

Обработка взаимоблокировок

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

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

Взаимоблокировок обычно можно избежать с помощью нескольких простых техник:

§  Получать доступ к таблицам в одном и том же порядке во всех частях вашего приложения.

§  Использовать кластеризованный индекс во всех таблицах для гарантированного порядка строк.

§  Сохранять транзакции короткими.

Более подробную информацию можно найти в статье Microsoft Knowledge Base “Detecting and Avoiding Deadlocks in Microsoft SQL Server.”

Удаленные транзакции

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

Удаленные сервера устанавливаются попарно. Вы должны сконфигурировать оба сервера таким образом, чтобы они распознавали друг друга как удаленные сервера. Имя каждого сервера должно быть добавлено к его партнеру с помощью системной хранимой процедуры sp_addlinkedserver или SQL Server Enterprise Manager.

После установки удаленного сервера используйте системную хранимую процедуру sp_addremotelogin или SQL Server Enterprise Manager для задания ID удаленного входа в систему для тех пользователей, кому нужно иметь доступ к удаленному серверу. После фиксации этого шага вы должны назначить права для выполнения хранимых процедур.

Затем для выполнения процедур на удаленном сервере используется инструкция EXECUTE. Этот пример использует хранимую процедуру validate_student на удаленном сервере STUDSVR1 и сохраняет возвращенный статус, указывающий на успех или отказ в @retvalue1:

DECLARE @retvalue1 int
EXECUTE @retvalue = STUDSVR1.student_db.student_admin.validate_student '111111111'

Более подробную информацию можно найти в SQL Server Books Online.

Распределенные транзакции

Oracle автоматически инициирует распределенную транзакцию в том случае, если изменения производятся в таблицах на двух или более соединенных сетью узлах баз данных. Распределенные транзакции в SQL Server используют службы двухфазной фиксации Microsoft Distributed Transaction Coordinator (MS DTC), поставляемые с SQL Server.

По умолчанию, SQL Server должен быть проинструктирован для того, чтобы принимать участие в распределенных транзакциях. Участие SQL Server в транзакции MS DTC может быть запущено любым из следующих условий:

§  Инструкцией BEGIN DISTRIBUTED TRANSACTION. Эта инструкция начинает новую транзакцию MS DTC.

§  Клиентским приложением, напрямую вызывающим интерфейсы DTC.

В данном примере обратите внимание на распределенное обновление одновременно в локальной таблице GRADE и удаленной таблице CLASS (с помощью процедуры class_name):

BEGIN DISTRIBUTED TRANSACTION
UPDATE STUDENT_ADMIN.GRADE
       SET GRADE = 'B+' WHERE SSN = '111111111' AND CCODE = '1234'
DECLARE @retvalue1 int
EXECUTE @retvalue1 = CLASS_SVR1.dept_db.dept_admin.class_name '1234',      'Basketweaving'
COMMIT TRANSACTION
GO

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

Обработка двухфазной фиксации

Механизмы двухфазного фиксации Oracle и MS DTC аналогичны по действиям. На первой фазе двухфазного фиксации в SQL Server менеджер транзакций запрашивает каждый из перечисленных менеджеров ресурсов о подготовке к фиксации. Если какой-либо менеджер ресурсов не может подготовиться к фиксации, менеджер транзакций передает решение об отмене всем, занятым в транзакции.

Если все менеджеры ресурсов успешно подготовились к фиксации, менеджер транзакций передает решение о фиксации. Это – вторая фаза процесса фиксации. Менеджер ресурсов, подготавливаясь к фиксации, еще не знает, будет ли транзакция завершена или прервана. MS DTC хранит последовательный журнал, так что его решения о фиксации или отмене долговечны. Если менеджер ресурсов или транзакций дают сбой, они согласовывают сомнительные транзакции при восстановлении соединения.

Поддержка языка SQL

Этот раздел очерчивает аналогии и отличия между синтаксисом языков Transact-SQL и PL/SQL и предоставляет стратегии перехода.

SELECT и инструкции управления данными

Вот ряд рекомендаций по миграции инструкций Oracle DML и программ PL/SQL в SQL Server.

1.   Удостоверьтесь в корректности синтаксиса всех инструкций SELECT, INSERT, UPDATE и DELETE. Внесите требуемые изменения.

2.   Измените все внешние связи на стандартный синтаксис внешних связей SQL-92.

3.   Замените функции Oracle на соответствующие функции SQL Server.

4.   Проверьте все операторы сравнения.

5.   Замените оператор конкатенации строк “||” оператором конкатенации строк “+”.

6.   Замените программы PL/SQL на программы Transact-SQL.

7.   Замените все курсоры PL/SQL либо на некурсорные инструкции SELECT, либо на курсоры Transact-SQL.

8.   Замените процедуры, функции и пакеты PL/SQL на процедуры Transact-SQL.

9.   Преобразуйте триггеры PL/SQL на триггеры Transact-SQL.

10. Используйте инструкцию SET SHOWPLAN для отладки ваших запросов на предмет производительности.

Инструкции SELECT

Синтаксис инструкции SELECT аналогичен в Oracle и Microsoft SQL Server.

Oracle

Microsoft SQL Server

SELECT [/*+ optimizer_hints*/]
 [ALL | DISTINCT] select_list
 [FROM
{table_name | view_name | select_statement}]
[WHERE clause]
[GROUP BY group_by_expression]
[HAVING search_condition]
[START WITH … CONNECT BY]
[{UNION | UNION ALL | INTERSECT |
   MINUS} SELECT …]
[ORDER BY clause]
[FOR UPDATE]

SELECT select_list
[INTO new_table_]
FROM table_source
[WHERE search_condition]
[ GROUP BY [ALL] group_by_expression [,…n]
        [ WITH { CUBE | ROLLUP } ]
[HAVING search_condition]
[ORDER BY order_expression [ASC | DESC] ]

In addition:

UNION Operator
COMPUTE Clause
FOR BROWSE Clause
OPTION Clause

Характерные для Oracle рекомендации оптимизации в зависимости от затрат не поддерживаются SQL Server и должны быть удалены. Рекомендуется использовать оптимизацию в зависимости от затрат SQL Server Более подробную информацию можно найти в разделе “Настройка инструкций SQLэтого документа.

SQL Server не поддерживает инструкцию Oracle START WITH…CONNECT BY. Вы можете заменить ее в SQL Server с помощью создания процедуры, выполняющей те же задачи. Смотрите “Expanding Hierarchies” в SQL Server Books Online и соответствующие статьи в Knowledge Base.

Операторы набора Oracle INTERSECT и MINUS не поддерживаются SQL Server. Операторы SQL Server EXISTS и NOT EXISTS могут быть использованы для достижения того же результата.

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

Oracle

Microsoft SQL Server

SELECT CCODE, CNAME
FROM DEPT_ADMIN.CLASS
INTERSECT
SELECT C.CCODE, C.CNAME
FROM STUDENT_ADMIN.GRADE G,
DEPT_ADMIN.CLASS C
WHERE C.CCODE = G.CCODE

SELECT CCODE, CNAME
FROM DEPT_ADMIN.CLASS C
WHERE EXISTS
(SELECT 'X' FROM STUDENT_ADMIN.GRADE      G
WHERE C.CCODE = G.CCODE)

В данном примере используется оператор MINUS для выявления всех классов без студентов.

Oracle

Microsoft SQL Server

SELECT CCODE, CNAME
FROM DEPT_ADMIN.CLASS
MINUS
SELECT C.CCODE, C.CNAME
FROM STUDENT_ADMIN.GRADE G,
DEPT_ADMIN.CLASS C
WHERE C.CCODE = G.CCODE

SELECT CCODE, CNAME
FROM DEPT_ADMIN.CLASSC
WHERE NOT EXISTS
(SELECT 'X' FROM STUDENT_ADMIN.GRADE
     G
WHERE C.CCODE = G.CCODE)

Инструкции INSERT

Синтаксис инструкции INSERT аналогичен в Oracle и Microsoft SQL Server.

Oracle

Microsoft SQL Server

INSERT INTO
{table_name | view_name | select_statement} [(column_list)]
{values_list | select_statement}

INSERT [INTO]
    {
     table_name [ [AS] table_alias] WITH ( <table_hint_limited> […n])
     | view_name [ [AS] table_alias]
     | rowset_function_limited
    }

    {    [(column_list)]
        { VALUES ( {    DEFAULT
                        |    NULL
                        |    expression
                        }[,…n]
            )
        | derived_table
        | execute_statement    
        }
    }
    | DEFAULT VALUES

Язык Transact-SQL поддерживает вставку в таблицы и представления данных, но не поддерживает операций INSERT над инструкциями SELECT. Если код вашего приложения Oracle выполняет вставку в инструкцию SELECT, это должно быть исправлено.

Oracle

Microsoft SQL Server

INSERT INTO (SELECT SSN, CCODE, GRADE       FROM GRADE)
VALUES ('111111111', '1111',NULL)

INSERT INTO GRADE (SSN, CCODE, GRADE)
VALUES ('111111111', '1111',NULL)

Параметр values_list в Transact-SQL может содержать DEFAULT – стандартное ключевое слово SQL-92, не поддерживаемое Oracle. Это ключевое слово указывает на то, что при вставке должно использоваться значение колонки по умолчанию. В том случае, если для заданной колонки не существует значения по умолчанию, вставляется NULL. Если колонка не поддерживает NULL, возвращается сообщение об ошибке. Если колонка определена как тип данных timestamp, вставляется следующее значение.

Ключевое слово DEFAULT не может быть использовано с колонкой identity. Для создания следующего последовательного номера, колонки со свойством IDENTITY должны быть исключены из списков the column_list или values_clause. Вам не обязательно использовать ключевое слово DEFAULT для получения значения колонки по умолчанию. Как и в Oracle, если колонка не указана в column_list и у нее есть значение по умолчанию, оно и будет в нее помещено. Это наиболее совместимый подход при миграции.

Одной из полезных возможностей Transact-SQL (EXECute procedure_name) является выполнение процедуры и размещение ее результатов в конечной таблице или представлении данных. Oracle не дает такой возможности.

Инструкции UPDATE

Поскольку Transact-SQL поддерживает большую часть синтаксиса, используемого командой UPDATE в Oracle, требуется минимальный пересмотр.

Oracle

Microsoft SQL Server

UPDATE
{table_name | view_name | select_statement}
SET [column_name(s) = {constant_value | expression | select_statement | column_list |
variable_list]
{where_statement}

 UPDATE
        {
         table_name [ [AS] table_alias] WITH ( <table_hint_limited> […n])
         | view_name [ [AS] table_alias]
         | rowset_function_limited
        }
        SET
        {column_name = {expression | DEFAULT | NULL}
        | @variable = expression
        | @variable = column = expression } [,…n]

    {{[FROM {<table_source>} [, …n] ]

        [WHERE
            <search_condition>] }
        |
        [WHERE CURRENT OF
        { { [GLOBAL] cursor_name } | cursor_variable_name}
        ] }
        [OPTION (<query_hint> [,…n] )]

Инструкция UPDATE Transact-SQL не поддерживает операций обновления над инструкциями SELECT. Если кода вашего приложения Oracle выполняет обновления  инструкции SELECT, вы можете преобразовать инструкцию SELECT в представление данных, а затем использовать имя представления данных в инструкции SQL Server UPDATE. Смотри примеры выше, в Инструкциях INSERT.”

Команда UPDATE в Oracle может использовать только программные переменные из блока PL/SQL. Язык Transact-SQL не требует для этого использования блоков.

Oracle

Microsoft SQL Server

DECLARE
VAR1 NUMBER(10,2);
BEGIN
     VAR1 := 2500;
     UPDATE STUDENT_ADMIN.STUDENT
     SET TUITION_TOTAL = VAR1;
END;

DECLARE
@VAR1 NUMERIC(10,2)
SELECT @VAR1 = 2500
UPDATE STUDENT_ADMIN.STUDENT
SET TUITION_TOTAL=@VAR1

Ключевое слово DEFAULT может быть использовано для установки колонки в ее значение по умолчанию в SQL Server. Вы не можете сбросить колонку до значения по умолчанию в команде UPDATE в Oracle.

Transact-SQL и Oracle SQL поддерживают использование подзапросов в инструкции UPDATE. Однако пункт FROM в Transact-SQL может быть использован для создания команды UPDATE, основанного на связи. Эта возможность делает синтаксис инструкции UPDATE более читаемым и иногда может повысить производительность.

Oracle

Microsoft SQL Server

UPDATE STUDENT_ADMIN.STUDENT S
SET TUITION_TOTAL = 1500
WHERE SSN IN (SELECT SSN
           FROM GRADE G
                             WHERE G.SSN = S.SSN
                             AND G.CCODE = '1234')

Подзапрос:

UPDATE STUDENT_ADMIN.STUDENT S
SET TUITION_TOTAL = 1500
WHERE SSN IN (SELECT SSN
           FROM GRADE G
                             WHERE G.SSN = S.SSN
                             AND G.CCODE = '1234')

Пункт FROM:

UPDATE STUDENT_ADMIN.STUDENT S
SET TUITION_TOTAL = 1500
FROM GRADE G
WHERE S.SSN = G.SSN
     AND G.CCODE = '1234'

Инструкции DELETE

В большей части запросов, вам не нужно изменять инструкции DELETE. Если вы выполняете удаления из инструкции SELECT в Oracle, вы должны изменить синтаксис в SQL Server, поскольку эта возможность не поддерживается Transact-SQL.

Transact-SQL поддерживает использование подзапросов в пункте WHERE, как и связей в пункте FROM. Последнее может увеличить эффективность инструкций. Смотри примеры, приведенные ранее в Инструкциях UPDATE.”

Oracle

Microsoft SQL Server

DELETE [FROM]
{table_name | view_name | select_statement}
[WHERE clause]

DELETE
    [FROM ]
        {
         table_name [ [AS] table_alias] WITH ( <table_hint_limited> […n])
         | view_name [ [AS] table_alias]
         | rowset_function_limited
        }

        [ FROM {<table_source>} [, …n] ]

    [WHERE
        { <search_condition>
        |    { [ CURRENT OF
                {
                    { [ GLOBAL ] cursor_name }
                    | cursor_variable_name
                }
             ]
        }
    ]
    [OPTION (<query_hint> [,…n])]

Инструкция TRUNCATE TABLE

Синтаксис инструкции TRUNCATE TABLE, используемый в Oracle и Microsoft SQL Server, один и тот же. TRUNCATE TABLE используется для удаления всех строк из таблицы и не может быть откачена. Структура таблицы и все ее индексы сохраняются. Триггеры DELETE не выполняются. Если таблица упоминается в ограничении FOREIGN KEY, она не может быть урезана.

Oracle

Microsoft SQL Server

TRUNCATE TABLE table_name
[{DROP | REUSE} STORAGE]

TRUNCATE TABLE table_name

В SQL Server эту операцию может  выполнять только владелец таблицы. В Oracle эту команду может выдавать владелец таблицы, или пользователь, имеющий системную привилегию DELETE TABLE.

Команда TRUNCATE TABLE в Oracle может при желании освобождать пространство, занимаемое строками таблицы. Инструкция TRUNCATE TABLE в SQL Server всегда восстанавливает пространство, занимаемое данными таблицы и связанными с ней индексами.

Работа с данными в колонках Identity и timestamp

Последовательности Oracle – это объекты базы данных, напрямую не связанные с какой-либо таблицей или колонкой. Связь между колонкой и последовательностью реализуется приложением, посредством назначения следующего значения последовательности колонке программным образом. Таим образом, Oracle не претворяет в жизнь каких-либо правил при работе с последовательностями. Однако в Microsoft SQL Server значение в колонке identity не может быть обновлено, как и не может быть использовано ключевое слово DEFAULT.

По умолчанию, данные не могут вставляться напрямую в колонку identity. Колонка identity автоматически создает уникальное последовательное число для каждой новой строки, вставленной в таблицу. Эта настройка по умолчанию может быть изменена следующей инструкцией SET:

SET IDENTITY_INSERT table_name ON

Когда IDENTITY_INSERT выставлено в ON, пользователь может вставлять любое значение в колонку identity новой строки. Для предотвращения введения повторяющихся чисел в колонке должен быть создан уникальный индекс. Целью этой инструкции является возможность пользователя воссоздавать значение случайной удаленной строки. Функция @@IDENTITY может быть использована для получения последнего значения identity.

Инструкция TRUNCATE TABLE сбрасывает колонку identity к оригинальному значению SEED. Если вам не нужно сбрасывать значение identity, используйте инструкцию DELETE без пункта WHERE вместо инструкции TRUNCATE TABLE. Вам потребуется оценить, как это влияет на вашу миграцию из Oracle, поскольку ORACLE SEQUENCES не сбрасываются после команды TRUNCATE TABLE.

Вы можете выполнять только вставки и удаления при работе с колонками timestamp. Если вы попробуете обновить колонку timestamp, вы получите сообщение об ошибке:

Msg 272, Level 16, State 1 Can’t update a TIMESTAMP column.

Блокировка запрошенных строк

Oracle использует пункт FOR UPDATE для блокировки строк, заданных командой SELECT. Вам не нужно использовать эквивалентный пункт при работе с Microsoft SQL Server, поскольку это настройка по умолчанию.

Обобщения строк и пункт Compute

Пункт COMPUTE в SQL Server используется для создания функций обобщения строк (SUM, AVG, MIN, MAX и COUNT), становящихся дополнительными строками в результатах запроса. Он позволяет вам видеть одновременно отдельные строки и их обобщение. Вы можете подсчитывать суммарные значения в подгруппах и подсчитывать несколько функций в одной группе.

Команда SELECT в Oracle не поддерживает пункта COMPUTE. Однако пункт COMPUTE в SQL Server работает аналогично команде COMPUTE, которую можно встретить в инструменте запросов Oracle SQL*Plus.

Пункты Join

Microsoft SQL Server 7.0 позволяет объединять в одном пункте join до 256 таблиц, включая как временные так и постоянные таблицы. В Oracle нет ограничений на количество связанных таблиц.

При использовании внешних связей в Oracle оператор внешней связи (+) обычно размещается после дочерней колонки (внешнего ключа) в связи. Знак (+) означает колонку, в которой меньше уникальных значений. Так всегда происходит, если только внешний ключ не допускает использования значений типа null; в этом случае символ + может быть помещен у родительской колонки (ограничения PRIMARY KEY или UNIQUE). Вы не можете поместить символ + с обеих сторон знака равенства (=).

В SQL Server вы можете использовать операторы внешней связи *= и =*. * используется для обозначения колонки, в которой больше уникальных значений. Если дочерня колонка (внешний ключ) не позволяет значений null, * помещается на стороне родительской колонки (ограничения PRIMARY KEY или UNIQUE) от знака равенства. Размещение * фактически обратно размещению в Oracle. Вы не можете поместить * с обеих сторон знака равенства (=).

Операторы *= и =* считаются устаревшими. SQL Server также поддерживает стандартные операторы связей SQL-92, перечисленные ниже. Рекомендуется использовать их синтаксис. Стандартный синтаксис SQL-92 более мощен и имеет меньше ограничений, нежели операторы *.

Операция связи

Описание

CROSS JOIN

Результат пересечения таблиц. Он возвращает те же строки, как если бы в старой связи не было указано пункта WHERE. Этот тип связи называется в Oracle Cartesian.

INNER

Эта связь указывает, что все внутренние строки должны быть возвращены. Все несоответствующие строки отбрасываются. Это аналогично стандартной связи таблиц Oracle.

LEFT [OUTER]

Это тип связи задает, что должны быть возвращены все внешние строки из левой таблицы, даже если им не соответствует число колонок в правой. Это аналогично внешней связи Oracle (+).

RIGHT [OUTER]

Это тип связи задает, что должны быть возвращены все внешние строки из правой таблицы, даже если им не соответствует число колонок в левой. Это аналогично внешней связи Oracle (+).

FULL [OUTER]

Если строка из любой таблицы не соответствует критериям отбора, указывает, что строка должна быть включена в результативный набор, а ее колонки, соответствующие внешней таблице, выставлены в NULL. Это могло бы быть аналогично размещению оператора внешней связи Oracle на обеих сторонах знака “=” (col1(+) = col2(+)), что не разрешено.

Нижеприведенные примеры кода возвращают примеры классов, в которых заняты все студенты. Внешние ссылки определены между таблицами student и grade, что позволяет указывать всех студентов, даже тех, которые не заняты ни в каких классах. Внешние ссылки также заданы для таблицы class для того, чтобы вернут названия классов. Если бы внешние связи не были добавлены к таблицам class, студенты, не занятые ни в одном классе, не были бы возвращены, поскольку у них код курса (CCODE) равен null.

Oracle

Microsoft SQL Server

SELECT S.SSN AS SSN,
FNAME, LNAME
FROM STUDENT_ADMIN.STUDENT S,
DEPT_ADMIN.CLASS C,
STUDENT_ADMIN.GRADE G
WHERE S.SSN = G.SSN(+)
AND G.CCODE = C.CCODE(+)

SELECT S.SSN AS SSN,
FNAME, LNAME
FROM STUDENT_ADMIN.GRADE G
RIGHT OUTER JOIN
STUDENT_ADMIN.STUDENT S
ON G.SSN = S.SSN
LEFT OUTER JOIN
DEPT_ADMIN.CLASS C
ON G.CCODE = C.CCODE

Использование инструкций вместо SELECT имен таблиц

Microsoft SQL Server и Oracle поддерживают использование инструкций SELECT как источника таблиц при выполнении запросов. SQL Server требует наличия псевдонима, в то время, как в Oracle он необязателен.

Oracle

Microsoft SQL Server

SELECT SSN, LNAME, FNAME,
TUITION_PAID, SUM_PAID
FROM STUDENT_ADMIN.STUDENT,
(SELECT SUM(TUITION_PAID) SUM_PAID
FROM STUDENT_ADMIN.STUDENT)

SELECT SSN, LNAME, FNAME,
TUITION_PAID, SUM_PAID
FROM STUDENT_ADMIN.STUDENT,
(SELECT SUM(TUITION_PAID) SUM_PAID
FROM STUDENT_ADMIN.STUDENT) SUM_STUDENT

Чтение и изменение BLOB

Microsoft SQL Server реализует большие двоичные объекты (BLOB) с помощью типов данных text и image. Oracle реализует BLOB с помощью типов данных LONG и LONG RAW. В Oracle команда SELECT может делать запрос по параметрам из колонок LONG и LONG RAW.

В SQL Server вы можете использовать стандартные инструкции Transact-SQL или специализированную инструкцию READTEXT для чтения данных из колонок text и image. Инструкция READTEXT позволяет вам читать части колонок text и image. Oracle не предоставляет аналогичных инструкция для работы с колонками LONG и LONG RAW.

Инструкция READTEXT использует параметр text_pointer, который может быть получен с помощью функции TEXTPTR. Функция TEXTPTR возвращает указатель на колонку text или image в указанной строке или колонку text или image в последней строке, возвращенной запросом в том случае, если их больше одной. Поскольку функция TEXTPTR возвращает двоичную строку длиной в 16-байт, лучше всего сохранить ее в декларированной локальной переменной, и использовать эту переменную в READTEXT.

Инструкция READTEXT указывает, сколько байтов надо возвращать. Значение функции @@TEXTSIZE, указывающее на предельное число возвращаемых символов или байт, вытесняет значение, заданное в инструкции READTEXT в том случае, если оно меньше параметра, указанного в READTEXT.

Инструкция SET может быть использована с параметром TEXTSIZE для указания размера, в байтах, текстовых данных, возвращаемых инструкцией SELECT. Если вы зададите TEXTSIZE равным 0, размер принимается равным размеру по умолчанию (4 Кб). Установка параметра TEXTSIZE влияет на функцию @@TEXTSIZE. Драйвер ODBC SQL Server автоматически устанавливает параметр TEXTSIZE при изменении параметра SQL_MAX_LENGTH.

В Oracle команды UPDATE и INSERT используются для изменения значений в колонках LONG и LONG RAW. В SQL Server вы можете использовать стандартные инструкции UPDATE и INSERT или инструкции UPDATETEXT и WRITETEXT. Как UPDATETEXT, так и WRITETEXT имеют возможность непротоколирования, а UPDATETEXT делает возможным частичное обновление колонок text и image.

UPDATETEXT может использоваться для замены существующих данных, удаления существующих данных или вставки новых данных. Новые данные могут быть вставлены из константы, таблицы, колонки или текстового указателя.

Инструкция WRITETEXT полностью затирает все существующие в колонке данные. Используйте WRITETEXT для замены данных, а UPDATETEXT – для их изменения. Инструкция UPDATETEXT более гибка, поскольку она изменяет только часть текстового или двоичного значения, а не все значение. Более подробную информацию можно найти в SQL Server Books Online.

Функции

На таблицах в этом разделе продемонстрирована связь между скалярными и обобщенными функциями в Oracle и SQL Server. Хотя имена и одинаковы, важно обратить внимание на то, что функции отличаются числом и типом аргументов. Более того, функции, предоставляемые только Microsoft SQL Server, не упоминаются в этом списке, поскольку этот документ посвящен упрощению миграции существующих приложений Oracle. Примерами функций, не поддерживаемых Oracle, могут служить перевод радиан в градусы (DEGREES), выдача числа Пи (PI) и генерация случайного числа(RAND).

Числовые/математические функции

Ниже приведены числовые/математические функции, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Абсолютное значение

ABS

Аналогично

Арккосинус

ACOS

Аналогично

Арксинус

ASIN

Аналогично

Арктангенс n

ATAN

Аналогично

Арктангенс n и m

ATAN2

ATN2

Наименьшее целое >= числа

CEIL

CEILING

Косинус

COS

Аналогично

Гиперболический косинус

COSH

COT

Экспоненциальное значение

EXP

Аналогично

Наибольшее целое <= числа

FLOOR

Аналогично

Натуральный логарифм

LN

LOG

Логарифм с любым основанием

LOG(N)

Отсутствует

Логарифм с основанием 10

LOG(10)

LOG10

Остаток от целочисленного деления

MOD

Используйте оператор (%)

Возведение в степень

POWER

Аналогично

Случайное число

Отсутствует

RAND

Округление

ROUND

Аналогично

Знак числа

SIGN

Аналогично

Синус

SIN

Аналогично

Гиперболический синус

SINH

Отсутствует

Квадратный корень

SQRT

Аналогично

Тангенс

TAN

Аналогично

Гиперболический тангенс

TANH

Отсутствует

Усечение

TRUNC

Отсутствует

Наибольшее число из списка

GREATEST

Отсутствует

Наименьшее число из списка

LEAST

Отсутствует

Преобразование числа если NULL

NVL

ISNULL

Символьные функции

Ниже приведены символьные функции, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Преобразование символа в ASCII

ASCII

Аналогично

Конкатенация строк

CONCAT

(выражение + выражение)

Преобразование ASCII в символ

CHR

CHAR

Возврат первого вхождения символа в символьной строке (слева)

INSTR

CHARINDEX

Преобразование символов к нижнему регистру (LOWER)

LOWER

Аналогично

Преобразование символов к верхнему регистру (UPPER)

UPPER

Аналогично

Набивка левой части строки символов

LPAD

Отсутствует

Удаление ведущих пробелов

LTRIM

Аналогично

Удаление хвостовых пробелов

RTRIM

Аналогично

Первое вхождение подстроки в строке символов

INSTR

PATINDEX

Повтор строки символов несколько раз

RPAD

REPLICATE

Фонетическая репрезентация строки символов

SOUNDEX

Аналогично

Строка повторяющихся пробелов

RPAD

SPACE

Преобразование числовых данных в строковые

TO_CHAR

STR

Подстрока

SUBSTR

SUBSTRING

Замена символов

REPLACE

STUFF

Написание каждого слова в строке с заглавной буквы

INITCAP

Отсутствует

Перевод строки символов

TRANSLATE

Отсутствует

Длина строки символов

LENGTH

DATALENGTH или LEN

Наибольшая строка символов из списка

GREATEST

Отсутствует

Наименьшая строка символов из списка

LEAST

Отсутствует

Преобразование строки символов если NULL

NVL

ISNULL

Функции работы с датами

Ниже приведены функции работы с датами, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Добавление даты

(колонка с датой +/- значение) или
ADD_MONTHS

DATEADD

Разница дат

(колонка с датой +/- значение) или
MONTHS_BETWEEN

DATEDIFF

Текущая дата/время

SYSDATE

GETDATE()

Последний день месяца

LAST_DAY

Отсутствует

Преобразование временной зоны

NEW_TIME

Отсутствует

Первый день недели после даты

NEXT_DAY

Отсутствует

Строка символов, отображающая дату

TO_CHAR

DATENAME

Числовое представление

TO_NUMBER (TO_CHAR))

DATEPART

Округление даты

ROUND

CONVERT

Усечение даты

TRUNC

CONVERT

Преобразование строки символов в дату

TO_DATE

CONVERT

Преобразование даты если NULL

NVL

ISNULL

Функции преобразования

Ниже приведены функции преобразования, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Число в символ

TO_CHAR

CONVERT

Символ в число

TO_NUMBER

CONVERT

Дату в символ

TO_CHAR

CONVERT

Символ в дату

TO_DATE

CONVERT

Шестнадцатеричное в двоичное

HEX_TO_RAW

CONVERT

Двоичное в шестнадцатеричное

RAW_TO_HEX

CONVERT

Прочие функции уровня строки

Ниже приведены прочие функции уровня строки, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Возвращение первого значение, не равного null

DECODE

COALESCE

Текущее значение последовательности

CURRVAL

Отсутствует

Следующее значение последовательности

NEXTVAL

Отсутствует

Если exp1 = exp2, вернуть null

DECODE

NULLIF

Числовое значение ID пользовательского имени входа в систему

UID

SUSER_ID

Пользовательское имя входа

USER

SUSER_NAME

Числовое значение ID пользователя в базе данных

UID

USER_ID

Имя пользователя в базе данных

USER

USER_NAME

Текущий пользователь

CURRENT_USER

Аналогично

Пользовательское окружение (ревизионный хвост)

USERENV

Отсутствует

Уровень в инструкции CONNECT BY

LEVEL

Отсутствует

Обобщенные функции

Ниже приведены обобщенные функции, поддерживаемые Oracle, и их эквиваленты в Microsoft SQL Server.

Функция

Oracle

Microsoft SQL Server

Среднее

AVG

Аналогично

Счетчик

COUNT

Аналогично

Максимум

MAX

Аналогично

Минимум

MIN

Аналогично

Среднее отклонение

STDDEV

STDEV или STDEVP

Суммирование

SUM

Аналогично

Дисперсия

VARIANCE

VAR или VARP

Проверки условий

И инструкция DECODE в Oracle, и выражение CASE в Microsoft SQL Server выполняют условные тесты. Когда значение test_value совпадает с перечисленными выражениями, возвращается соответствующее значение. В случае отсутствия совпадения, возвращается default_value. Если default_value не задано, как DECODE, так и CASE возвращают NULL. В таблице указан синтаксис и пример преобразованной команды DECODE.

Oracle

Microsoft SQL Server

DECODE (test_value,
  expression1, value1
  [[,expression2, value2] […]]
  [,default_value]
)

 

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(DECODE(grade
                                                ,'A', 4
                                                ,'A+', 4.3
                                                ,'A-', 3.7
                                                ,'B', 3
                                                ,'B+', 3.3
                                                ,'B-', 2.7
                                                ,'C', 2
                                                ,'C+', 2.3
                                                ,'C-', 1.7
                                                ,'D', 1
                                                ,'D+', 1.3
                                                ,'D-', 0.7
                                                ,0)),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

CASE test_value
WHEN expression1 THEN value1
[[WHEN expression2 THEN value2] [...]]
[ELSE default_value]
END

 

CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(CASE grade
                                WHEN 'A' THEN 4
                                WHEN 'A+' THEN 4.3
                                WHEN 'A-' THEN 3.7
                                WHEN 'B' THEN 3
                                WHEN 'B+' THEN 3.3
                                WHEN 'B-' THEN 2.7
                                WHEN 'C' THEN 2
                                WHEN 'C+' THEN 2.3
                                WHEN 'C-' THEN 1.7
                                WHEN 'D' THEN 1
                                WHEN 'D+' THEN 1.3
                                WHEN 'D-' THEN 0.7
                                ELSE 0
                                END),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

Выражение CASE может использовать инструкции SELECT для выполнения булевских проверок, что не возможно в команде DECODE. Более подробную информацию о выражении CASE можно найти в SQL Server Books Online.

Преобразование значений к иным типам данных

Функции Microsoft SQL Server CONVERT и CAST  – многоцелевые функции преобразования. Они предоставляют аналогичные возможности, преобразовывая один тип данных в другой, и поддерживая большой число специальных форматов даты:

CAST(expression AS data_type)

CONVERT (data type[(length)], expression [, style])

CAST – это стандартная функция SQL-92. Эти функции выполняют те же операции, что и функции TO_CHAR, TO_NUMBER, TO_DATE, HEXTORAW и RAWTOHEX в Oracle.

Тип данных – это любой системный тип данных, в который должно быть преобразовано выражение. Пользовательские типы данных не могут быть использованы. Параметр length – необязательный и используется с типами данных char, varchar, binary и varbinary. Максимально допустимая длина равна 8000.

Преобразование

Oracle

Microsoft SQL Server

Символ в число

TO_NUMBER('10')

CONVERT(numeric, '10')

Число в символ

TO_CHAR(10)

CONVERT(char, 10)

Символ в дату

TO_DATE('04-JUL-97')
TO_DATE('04-JUL-1997',
'dd-mon-yyyy')
TO_DATE('July 4, 1997',
'Month dd, yyyy')

CONVERT(datetime, '04-JUL-97')
CONVERT (datetime, '04-JUL-1997')
CONVERT (datetime, 'July 4, 1997')

Дату в символ

TO_CHAR(sysdate)
TO_CHAR(sysdate, 'dd mon yyyy')
TO_CHAR(sysdate, 'mm/dd/yyyy')

CONVERT(char, getdate())
CONVERT(char, getdate(), 106)
CONVERT(char, getdate(), 101)

Шестнадцатеричное в двоичное

HEXTORAW('1F')

CONVERT(binary, '1F')

Двоичное в шестнадцатеричное

RAWTOHEX(binary_column)

CONVERT(char, binary_column)

Обратит внимание на то, как строки символов преобразуются в даты. В Oracle форматом даты по умолчанию является DD-MON-YY.” При использовании любого другого формата, вы должны предоставить соответствующую модель формата. Функция CONVERT автоматически конвертирует стандартные форматы дат без необходимости модели формата.

При конвертировании из даты в строку символов, выводом по умолчанию функции CONVERT будет dd mon yyyy hh:mm:ss:mmm(24h)”. Цифровой код стиля используется для форматирования вывода в иные типы формата даты. Более подробную информацию о функции CONVERT можно найти в SQL Server Books Online.

В нижеприведенной таблице показаны выводы по умолчанию дат Microsoft SQL Server.

Без века

С веком

Стандартный

Вывод

-

0 or 100 (*)

По умолчанию

mon dd yyyy hh:miAM (or PM)

1

101

США

mm/dd/yy

2

102

ANSI

yy.mm.dd

3

103

Английский/французский

dd/mm/yy

4

104

Немецкий

dd.mm.yy

5

105

Итальянский

dd-mm-yy

6

106

-

dd mon yy

7

107

-

mon dd, yy

8

108

-

hh:mm:ss

-

9 or 109 (*)

По умолчанию с миллисекундами

mon dd yyyy hh:mi:ss:mmm (AM or PM)

10

110

США

mm-dd-yy

11

111

Япония

yy/mm/dd

12

112

ISO

yymmdd

-

13 or 113 (*)

По умолчанию в Европе

dd mon yyyy hh:mm:ss:mmm(24h)

14

114

-

hh:mi:ss:mmm(24h)

Пользовательские функции

Функции Oracle PL/SQL могут быть использованы в инструкциях Oracle SQL. Те же возможности часто могут быть достигнуты иными методами в Microsoft SQL Server.

В нижеприведенном примере пользовательская функция Oracle GET_SUM_MAJOR используется для получения суммы платы за обучение, выплаченной студентом. Она может быть заменена в SQL Server с помощью использования запроса как таблицы.

Oracle

Microsoft SQL Server

SELECT ssn, fname, lname, tuition_paid,
tuition_paid/get_sum_major(major) as      percent_major
FROM student_admin.student

SELECT ssn, fname, lname, tuition_paid, tuition_paid/sum_major as percent_major
FROM student_admin.student,
    (SELECT major, sum(tuition_paid) sum_major
    FROM student_admin.student
    GROUP BY major) sum_student
WHERE student.major = sum_student.major

CREATE OR REPLACE FUNCTION get_sum_major
(inmajor varchar2) RETURN NUMBER
AS sum_paid number;
BEGIN
SELECT sum(tuition_paid) into sum_paid
FROM student_admin.student
WHERE major = inmajor;
RETURN(sum_paid);
END get_sum_major;

No CREATE FUNCTION syntax is required;
use CREATE PROCEDURE syntax.

Операторы сравнения

Операторы сравнения в Oracle и Microsoft SQL Server практически идентичны.

 

Operator

Oracle

Microsoft SQL Server

Равен

(=)

Аналогично

Больше чем

(>)

Аналогично

Меньше чем

(<)

Аналогично

Больше чем или равно

(>=)

Аналогично

Меньше чем или равно

(<=)

Аналогично

Не равно

(!=, <>,^=)

Аналогично

Не более чем, не менее чем

Отсутствует

!> , !<

В любом члене набора

IN

Аналогично

Ни в одном члене набора

NOT IN

Аналогично

Любое значение в наборе

ANY, SOME

Аналогично

Относится ко всем членам набора.

!= ALL, <> ALL, < ALL, > ALL, <= ALL, >= ALL

Аналогично

Подобен шаблону

LIKE

Аналогично

Не подобен шаблону

NOT LIKE

Аналогично

Значение между x b y

BETWEEN x AND y

Аналогично

Значение вне пределов

NOT BETWEEN

Аналогично

Значение существует

EXISTS

Аналогично

Значение не существует

NOT EXISTS

Аналогично

Значение {является | не является} NULL

IS NULL, IS NOT NULL

Аналогично. Также поддерживает = NULL, != NULL для обратной совместимости (не рекомендуется).

Сравнения с шаблоном

Ключевое слово SQL Server LIKE предоставляет возможности поиска по маске, не поддерживаемые Oracle. Кроме поддержки символов маски % и _, общих для обеих RDBMS, SQL Server также поддерживает символы [ ] и [^].

Набор символов [ ] используется для поиска любого одиночного символа из заданного диапазона. К примеру, если вы ищете символы от a до f в одиночном положении, вы можете задать это с помощью операторов LIKE '[a-f]' или LIKE '[abcdef]'. Польза дополнительных символов маски очевидна из таблицы.

Oracle

Microsoft SQL Server

SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE 'A%'
           OR LNAME LIKE 'B%'
           OR LNAME LIKE 'C%'

SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE '[ABC]%'

Набор символов [^] используется для указания символов, НЕ входящих в заданный диапазон. К примеру, если подходит любой символ кроме символов от a до f, вы используете LIKE '[^a - f]' или  LIKE '[^abcdef]'.

Более подробную информацию о ключевом слове LIKE можно найти в SQL Server Books Online.

Использование NULL в сравнениях

Хотя Microsoft SQL Server традиционно поддерживает стандарт SQL-92, как и некоторые нестандартные реализации NULL, он поддерживает использование NULL в Oracle.

SET ANSI_NULLS должно быть выставлено в ON для выполнения распределенных запросов.

Драйвер ODBC SQL Server и OLE DB Provider для SQL Server автоматически выдает SET ANSI_NULLS в ON при запуске. Эта установка может быть сконфигурирована в источниках данных ODBC, атрибутах связи ODBC или свойствах соединения OLE DB, устанавливаемых приложением перед подсоединением к SQL Server. SET ANSI_NULLS по умолчанию устанавливается в OFF для соединений из приложений DBLibrary.

Когда SET ANSI_DEFAULTS установлено в ON, SET ANSI_NULLS доступно.

Более подробную информацию о использовании NULL можно найти в SQL Server Books Online.

Конкатенация строк

Oracle использует два символа "трубы" (||) как оператор конкатенации строк, а SQL Server использует знак (+). Это отличие требует минимальных изменений в коде вашего приложения.

Oracle

Microsoft SQL Server

SELECT FNAME||' '||LNAME AS NAME
FROM STUDENT_ADMIN.STUDENT

SELECT FNAME +' '+ LNAME AS NAME
FROM STUDENT_ADMIN.STUDENT

Язык управляющих операторов

Язык управляющих операторов управляет порядком выполнения инструкций SQL, блоков инструкций и хранимых процедур. PL/SQL и Transact-SQL предоставляют много аналогичных конструкций, хотя есть и некоторые синтаксические отличия.

Ключевые слова

В таблице приведены ключевые слова, поддерживаемые каждой RDBMS.

Инструкция

Oracle PL/SQL

Microsoft SQL Server

Transact-SQL

Декларация переменных

DECLARE

DECLARE

Блок инструкций

BEGIN...END;

BEGIN...END

Обработка условий

IF…THEN,
ELSIF…THEN,
ELSE
ENDIF;

IF…[BEGIN…END]
ELSE <condition>
[BEGIN…END]
ELSE IF <condition>
CASE expression

Безусловный выход

RETURN

RETURN

Безусловный переход к инструкции, следующей за концом текущего программного блока

EXIT

BREAK

Повторение цикла WHILE

Отсутствует

CONTINUE

Ожидание определенного промежутка

Отсутствует (dbms_lock.sleep)

WAITFOR

Управление циклами

WHILE LOOP…END LOOP;


LABEL…GOTO LABEL;
FOR…END LOOP;
LOOP…END LOOP;

WHILE <condition>
BEGIN… END

LABEL…GOTO LABEL

Комментарии

/* … */, --

/* … */, --

Вывод

RDBMS_OUTPUT.PUT_LINE

PRINT

Создание программной ошибки

RAISE_APPLICATION_ERROR

RAISERROR

Выполнение программы

EXECUTE

EXECUTE

Разделитель инструкций

Точка с запятой (;)

Отсутствует

Объявления переменных

Переменные Transact-SQL и PL/SQL создаются с помощью ключевого слова DECLARE. Переменные Transact-SQL определяются с помощью символа @ и, подобно переменным PL/SQL, инициализируются значением null при создании.

Oracle

Microsoft SQL Server

DECLARE
VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
VBIRTH_DATE DATE;
VLOAN_AMOUNT NUMBER(12,2);

DECLARE
@VSSN CHAR(9),
@VFNAME VARCHAR2(12),
@VLNAME VARCHAR2(20),
@VBIRTH_DATE DATETIME,
@VLOAN_AMOUNT NUMERIC(12,2)

Transact-SQL не поддерживает определений типа данных переменной %TYPE и %ROWTYPE. Переменные Transact-SQL не могут быть инициализированы в команде DECLARE. Ключевые слова Oracle NOT NULL и CONSTANT не могут быть использованы в определениях типа данных Microsoft SQL Server.

Подобно типам данных Oracle LONG и LONG RAW, типы данных text и image не могут быть использованы для определения переменных. Более того, определения таблиц и записей в стиле PL/SQL также не поддерживаются.

Назначение переменных

Oracle и Microsoft SQL Server предоставляют следующие методы назначения значений локальным переменным.

Oracle

Microsoft SQL Server

Оператор присваивания (:=)

SET @variable = value

Синтаксис SELECT...INTO для выбора значений колонок из одной строки

SELECT @var=<expression> [FROM…] для назначения литерала, выражения, затрагивающего другие локальные переменные или значения колонки из одной строки

Синтаксис FETCH…INTO

Синтаксис FETCH…INTO

§   

§  Вот некоторые примеры синтаксиса.

Oracle

Microsoft SQL Server

DECLARE VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
BEGIN
VSSN := '123448887';
SELECT FNAME, LNAME INTO VFNAME, VLNAME FROM STUDENTS WHERE SSN=VSSN;
END;

DECLARE @VSSN CHAR(9),
@VFNAME VARCHAR(12),
@VLNAME VARCHAR(20)
SET @VSSN = '12355887'
SELECT @VFNAME=FNAME, @VLNAME=LNAME FROM STUDENTS WHERE SSN = @VSSN

Блоки инструкций

Oracle PL/SQL и Microsoft SQL Server Transact-SQL поддерживают использование терминологии BEGIN…END для определения блоков инструкций. Transact-SQL не требует использования блока инструкций после инструкции DECLARE. Блоки инструкций BEGINEND требуются Microsoft SQL Server для инструкций IF и циклов WHILE в том случае, если выполняется более одной инструкции.

Oracle

Microsoft SQL Server

DECLARE
     DECLARE VARIABLES ...
BEGIN -- THIS IS REQUIRED SYNTAX
     PROGRAM_STATEMENTS ...
     IF ...THEN
           STATEMENT1;
          STATEMENT2;
           STATEMENTN;
END IF;
WHILE ... LOOP
           STATEMENT1;
           STATEMENT2;
           STATEMENTN;
     END LOOP;
END; -- THIS IS REQUIRED SYNTAX

DECLARE
     DECLARE VARIABLES ...
BEGIN -- THIS IS OPTIONAL SYNTAX
     PROGRAM_STATEMENTS ...
     IF ...
     BEGIN

           STATEMENT1
           STATEMENT2
           STATEMENTN
           END
WHILE ...
           BEGIN

           STATEMENT1
           STATEMENT2
           STATEMENTN
     END
END -- THIS IS REQUIRED SYNTAX

Обработка условий

Инструкции условий Microsoft SQL Server Transact-SQL включают IF и ELSE, и не включают инструкции ELSIF в Oracle PL/SQL. Инструкции IF могут быть вложенными для достижения того же самого эффекта. В случае "обширных" проверок инструкция CASE может оказаться более читаемой.

Oracle

Microsoft SQL Server

DECLARE
VDEGREE_PROGRAM CHAR(1);
VDEGREE_PROGRAM_NAME VARCHAR2(20);
BEGIN
     VDEGREE_PROGRAM := 'U';
     IF VDEGREE_PROGRAM = 'U' THEN
           VDEGREE_PROGRAM_NAME :=
                'Undergraduate';
     ELSIF VDEGREE_PROGRAM = 'M' THEN
           VDEGREE_PROGRAM_NAME :=
                'Masters';
     ELSIF VDEGREE_PROGRAM = 'P' THEN
           VDEGREE_PROGRAM_NAME := 'PhD';
     ELSE VDEGREE_PROGRAM_NAME :=
                'Unknown';
     END IF;
END;

DECLARE
@VDEGREE_PROGRAM CHAR(1),
@VDEGREE_PROGRAM_NAME VARCHAR(20)
SELECT @VDEGREE_PROGRAM = 'U'
SELECT @VDEGREE_PROGRAM_NAME =
     CASE @VDEGREE_PROGRAM
           WHEN 'U' THEN 'Undergraduate'
           WHEN 'M' THEN 'Masters'
           WHEN 'P' THEN 'PhD'.
           ELSE 'Unknown'
     END

Повторяемое выполнение инструкций (цикл)

Oracle PL/SQL предоставляет безусловные циклы LOOP и FOR LOOP. Transact-SQL предоставляет цикл WHILE и инструкции GOTO для зацикливания.

WHILE Boolean_expression
       {sql_statement | statement_block}
       [BREAK] [CONTINUE]

Цикл WHILE проверяет булевское выражение при каждом повторном исполнении одной или более инструкций. Инструкции выполняются повторно до тех пор, пока указанное выражение сводится к TRUE. Если требуется выполнение нескольких инструкций, они должны быть помещены внутри блока BEGINEND.

Oracle

Microsoft SQL Server

DECLARE
COUNTER NUMBER;
BEGIN
     COUNTER := 0
     WHILE (COUNTER <5) LOOP
           COUNTER := COUNTER + 1;
     END LOOP;
END;

DECLARE
@COUNTER NUMERIC
SELECT@COUNTER = 1
WHILE (@COUNTER <5)
BEGIN
     SELECT @COUNTER = @COUNTER +1
END

Выполнение инструкций может быть проконтролировано изнутри цикла с помощью ключевых слов BREAK и CONTINUE. Ключевое слово BREAK вызывает безусловный выход из цикла WHILE, а ключевое слово CONTINUE вызывает повторный запуск цикла WHILE, пропуская все следующие инструкции. Ключевое слово BREAK аналогично ключевому слову EXIT в Oracle PL/SQL. Oracle не имеет аналога CONTINUE.

Инструкция GOTO

Как Oracle, так и Microsoft SQL Server имеют инструкцию GOTO, но с различным синтаксисом. Инструкция GOTO в Transact-SQL приводит к тому, что выполнение переходит на метку. Ни одна из инструкций между инструкцией GOTO и меткой не выполняются.

Oracle

Microsoft SQL Server

GOTO label;
<<label name here>>

GOTO label
:label

Инструкция PRINT

Инструкция PRINT в Transact-SQL выполняет те же операции, что и процедура RDBMS_OUTPUT.put_line в PL/SQL. Она используется для вывода заданных пользователем сообщений.

Объем сообщения для инструкции PRINT ограничен 8,000 символов. Переменные, определенные как char или varchar, могут быть включены в выводимый текст. Если используется другой тип данных, должны быть использованы функции CONVERT или CAST. Печататься могут локальные переменные, глобальные переменные и текст. Для отделения текста могут использоваться как одинарные, так и двойные кавычки.

Возврат из хранимых процедур

Как Microsoft SQL Server, так и Oracle имеют инструкции RETURN. RETURN дает вашей программе возможность безусловного выхода из запроса или процедуры.  Инструкция RETURN выполняется немедленно и полностью и может быть использована в любом месте для выхода из процедуры, пакета или блока инструкций. Инструкции, следующие за RETURN, не выполняются.

Oracle

Microsoft SQL Server

RETURN <expression>:

RETURN <integer>

Создание программной ошибки

Инструкция RAISERROR в Transact-SQL возвращает определенное пользователем сообщение об ошибке и устанавливает системный флаг, сохраняющий информацию о возникновении ошибки. Это аналогично функции обработчику исключений PL/SQL raise_application_error.

Инструкция RAISERROR позволяет клиенту получать данные из таблицы sysmessages или создавать сообщение динамически с указанной пользователем информацией. При определении это сообщение отсылается обратно клиенту как сообщение об ошибке сервера.

RAISERROR ({msg_id | msg_str}, severity, state
       [, argument1 [, argument2]])
       [WITH options]

При переносе программ PL/SQL  может оказаться ненужным использование инструкции RAISERROR. В нижеприведенном примере кода программа PL/SQL использует обработчик исключения raise_application_error, в то время как программа Transact-SQL ничего не использует. Обработчик исключения raise_application_error был создан для предотвращения возможности возвращения программой PL/SQL двусмысленного сообщения unhandled exception. Вместо этого она всегда возвращает номер ошибки Oracle (SQLERRM) при возникновении непредвиденной проблемы.

При сбое программы Transact-SQL она всегда возвращает детальное сообщение об ошибке в клиентскую программу. Таким образом, до тех пор, пока нет необходимости в специализированной обработке ошибок, инструкция RAISERROR не всегда нужна.

Oracle

Microsoft SQL Server

CREATE OR REPLACE FUNCTION
DEPT_ADMIN.DELETE_DEPT
(VDEPT IN VARCHAR2) RETURN NUMBER AS
BEGIN
DELETE FROM DEPT_ADMIN.DEPT
WHERE DEPT = VDEPT;
RETURN(SQL%ROWCOUNT);
EXCEPTION
WHEN OTHER THEN
RAISE_APPLICATION_ERROR (-20001,SQLERRM);
END DELETE_DEPT;
/

CREATE PROCEDURE
DEPT_ADMIN.DELETE_DEPT
@VDEPT VARCHAR(4) AS
DELETE FROM DEPT_DB.DBO.DEPT
WHERE DEPT = @VDEPT
RETURN @@ROWCOUNT
GO

Реализация курсоров

Oracle всегда требует использования курсоров с инструкцией SELECT, вне зависимости от числа строк, запрашиваемых из базы данных. В Microsoft SQL Server инструкция SELECT, не заключенная в курсор, возвращает строки клиенту как набор записей по умолчанию. Это – эффективный путь возвращения данных в клиентское приложение.

SQL Server предоставляет два интерфейса для функций курсора. При использовании курсоров в пакетах или хранимых процедурах Transact-SQL, инструкции SQL могут быть использованы для декларирования, открытия и запроса из курсора, а также позиционируемых обновлений и удалений. При использовании курсоров из программ DBLibrary, ODBC или OLEDB клиентские библиотеки SQL Server прозрачно вызывают встроенные функции сервера для обеспечения более эффективной работы с курсорами.

При переносе процедуры  PL/SQL из Oracle, сначала определите, так ли вам необходимы курсоры для реализации тех же функций в Transact-SQL. Если курсор только возвращает набор строк в клиентское приложение, используйте бескурсорную инструкцию SELECT в Transact-SQL, возвращающую набор строк по умолчанию. Если курсор используется для загрузки данных в локальные переменные по строке за раз, вам следует использовать курсоры и в Transact-SQL.

Синтаксис

В таблице указан синтаксис использования курсоров.

Операция

Oracle

Microsoft SQL Server

Декларация курсора

CURSOR cursor_name [(cursor_parameter(s))]
IS select_statement;

DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,n]]]

Открытие курсора

OPEN cursor_name [(cursor_parameter(s))];

OPEN cursor_name

Выборка данных из курсора

FETCH cursor_name INTO variable(s)

FETCH [[NEXT | PRIOR | FIRST | LAST | ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar}]
FROM] cursor_name
[INTO @variable(s)]

Обновление выборки

UPDATE table_name
SET statement(s)…
WHERE CURRENT OF cursor_name;

UPDATE table_name
SET statement(s)…
WHERE CURRENT OF cursor_name

Удаление выборки

DELETE FROM table_name
WHERE CURRENT OF cursor_name;

DELETE FROM table_name
WHERE CURRENT OF cursor_name

Закрытие курсора

CLOSE cursor_name;

CLOSE cursor_name

Удаление структур данных курсора

Отсутствует

DEALLOCATE cursor_name

Объявление курсора

Хотя инструкция DECLARE CURSOR в Transact-SQL не поддерживает использование аргументов курсора, она поддерживает локальные переменные. Значения этих локальных переменных используются при открытии курсора. Microsoft SQL Server предоставляет множество дополнительных возможностей в инструкции DECLARE CURSOR.

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

Приложения могут запросить определенный тип курсора, а затем выполнить инструкцию Transact-SQL, не поддерживаемую серверными курсорами запрошенного типа. SQL Server возвращает сообщение об ошибке, гласящее, что тип курсора был изменен, или, в ряде случаев неявно преобразовывает курсор. Более полный список факторов, заставляющих SQL Server 7.0 неявно изменить тип курсора, можно найти в SQL Server Books Online.

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

Если выбран параметр READ ONLY, запрещается обновление любой строки курсора. Этот параметр затирает возможность курсора быть обновленным по умолчанию.

Инструкция UPDATE [OF column_list] используется для задания обновляемых колонок в курсоре. Если задано [OF column_list], только перечисленные колонки могут быть модифицированы. Если список не задан, все колонки могут быть изменены, если только курсор не определен как READ ONLY.

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

Открытие курсора

Transact-SQL не поддерживает передачу аргументов в курсор при его открытии, в отличие от PL/SQL. При открытии курсора Transact-SQL, членство и сортировка результирующего набора записей фиксируются. Обновления и удаления, сделанные другими пользователями в соответствующих таблицах, отражаются в выборках из всех курсоров без параметра INSENSITIVE. В случае курсора INSENSITIVE создается временная таблица.

Выборка данных

По курсорам Oracle можно перемещаться только вперед  в них нет возможности обратной или относительной прокрутки. В курсорах SQL Server можно перемещаться как вперед, так и назад с помощью параметров выборки, приведенных в нижеуказанной таблице. Эти параметра выборки могут использоваться только в том случае, если курсор определялся с параметром SCROLL.

Параметр выборки

Описание

NEXT

Возвращает первую строку результирующего набора записей в том случае, ели это первая выборка из курсора; в противном случае, он перемещает курсор на одну строку вперед по набору записей. NEXT – это основной метод, используемый для перемещения по набору записей. NEXT – это параметр выборки по умолчанию.

PRIOR

Возвращает предыдущую строку из набора записей.

FIRST

Перемещает курсор на первую строку в наборе записей и возвращает ее.

LAST

Перемещает курсор на последнюю строку в наборе записей и возвращает ее.

ABSOLUTE n

Возвращает n-ую строку набора записей. Если  n – отрицательное значение, отсчет ведется от последней строки набора записей назад.

RELATIVE n

Возвращает n-ую строку набора записей после текущей строки. Если n – отрицательное значение, отсчет ведется назад от текущей позиции.

Инструкция FETCH в Transact-SQL не требует пункта INTO. Если не указано переменных для записи возвращаемых значений, строка автоматически возвращается клиенту как набор записей из одной строки. Однако в том случае, если вашей процедуре необходимо передавать записи на клиент, бескурсорная инструкция SELECT окажется намного эффективней.

Функция @@FETCH_STATUS обновляется после каждой инструкции FETCH. Она аналогична использованию переменных CURSOR_NAME%FOUND и CURSOR_NAME%NOTFOUND в PL/SQL. Функция @@FETCH_STATUS устанавливается в 0 после успешной выборки. Если выборка попыталась прочитать данные после конца курсора, возвращается –1. Если запрошенная строка была удалены из таблицы после открытия курсора, функция @@FETCH_STATUS возвращает –2. Значение–2 обычно появляется в курсорах, декларированных с параметром SCROLL. Эта переменную следует проверять после каждой выборки для гарантирования корректности данных.

SQL Server не поддерживает синтаксис циклов в курсорах FOR из Oracle.

Пункт CURRENT OF

Синтаксис и функционирования пункта CURRENT OF для обновлений и удалений текущей строки одинаков в PL/SQL и Transact-SQL. Позиционируемая инструкция UPDATE или DELETE выполняется над текущей строкой в заданном курсоре.

Закрытие курсора

Инструкция Transact-SQL CLOSE CURSOR закрывает курсор, но оставляет структуры данных доступными для повторного открытия. Инструкция PL/SQL CLOSE CURSOR закрывает курсор и освобождает все структуры данных.

Transact-SQL требует использования инструкции DEALLOCATE CURSOR для удаления структур данных курсора. Инструкция DEALLOCATE CURSOR отличается от CLOSE CURSOR тем, что закрытый курсор может быть снова открыт. Инструкция DEALLOCATE CURSOR освобождает все структуры данных, ассоциируемые с курсором, и удаляет определение курсора.

Пример курсора

В нижеприведенном примере показаны эквивалентные инструкции курсора в PL/SQL и Transact-SQL.

Oracle

Microsoft SQL Server

DECLARE
VSSN CHAR(9);
VFNAME VARCHAR(12);
VLNAME VARCHAR(20);
CURSOR CUR1 IS
SELECT SSN, FNAME, LNAME
FROM STUDENT ORDER BY LNAME;
BEGIN
     OPEN CUR1;
     FETCH CUR1 INTO VSSN, VFNAME, VLNAME;
     WHILE (CUR1%FOUND) LOOP
     FETCH CUR1 INTO VSSN, VFNAME, VLNAME;
END LOOP;
CLOSE CUR1;
END;

DECLARE
@VSSN CHAR(9),
@VFNAME VARCHAR(12),
@VLNAME VARCHAR(20)
DECLARE curl CURSOR FOR
     SELECT SSN, FNAME, LNAME
     FROM STUDENT ORDER BY SSN
OPEN CUR1
FETCH NEXT FROM CUR1
     INTO @VSSN, @VFNAME, @VLNAME
WHILE (@@FETCH_STATUS <> -1)
     BEGIN
           FETCH NEXT FROM CUR1
           INTO @VSSN, @VFNAME, @VLNAME
     END
CLOSE CUR1
DEALLOCATE CUR1

Настройка инструкций SQL

Это раздел предоставляет информацию по некоторым инструментам SQL Server, который вы может использовать для настройки инструкций Transact-SQL. Более подробную информацию о настройке базы данных SQL Server database можно найти в Microsoft SQL Server 7.0 Tuning Guide по адресу http://msdn.microsoft.com/developer/sqlserver/sql7perftune.htm.

SQL Server Query Analyzer

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

SQL Server Profiler

Этот графический инструмент захватывает продолжительную запись активность сервера в реальном времени. SQL Server Profiler отслеживает многие события сервера и категории событий, фильтрует их по заданным пользователем критериям и выводили трассировку на экран, в файл или на иной сервер под управлением SQL Server.

SQL Server Profiler может быть использован для:

§  Отслеживания производительности SQL Server.

§  Отладки инструкций и хранимых процедур Transact-SQL.

§  Идентификации медленных запросов.

§  Выявления и устранения проблем SQL Server с помощью захвата всех событий, приведших к конкретной проблеме, и их повтора на тестовой системе для изоляции проблемы.

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

§  Захват событий на рабочей системе и их повтор на тестовой системе, воссоздавая события рабочей машины в отладочных или тестовых целях. Повтор захваченных событий на отдельной системе дает пользователям возможность продолжать использование рабочей системы без вмешательства.

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

Инструкция SET

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

Инструкция SET FORCEPLAN ON заставляет оптимизатор обрабатывать связи в том же порядке, в каком таблицы упомянуты в пункте FROM, аналогично рекомендации ORDERED, используемой оптимизатором Oracle.

Инструкции SET SHOWPLAN_ALL и SET SHOWPLAN_TEXT возвращают только информацию о плане выполнения инструкции или запроса и не выполняют сам запрос или инструкцию. Для выполнения запроса или инструкции, установите соответствующую инструкцию в OFF. После этого запрос или инструкция будут выполнены. Параметр SHOWPLAN аналогичен инструменту EXPLAIN PLAN в Oracle.

С помощью SET STATISTICS PROFILE ON каждый выполняемый запрос возвращает свой стандартный набор записей плюс дополнительный набор записей, указывающий профиль выполнения запроса. В прочие параметры входит SET STATISTICS IO и SET STATISTICS TIME.

Обработка инструкции Transact-SQL состоит из двух фаз, компиляции и выполнения. Параметр NOEXEC компилирует каждый запрос, но не выполняет его. После установки NOEXEC в ON, последующие инструкции не выполняются (включая иные инструкции SET) до тех пор, пока NOEXEC не будет выставлено в OFF.

SET SHOWPLAN ON
SET NOEXEC ON
go
SELECT * FROM DEPT_ADMIN.DEPT,
   STUDENT_ADMIN.STUDENT
WHERE MAJOR = DEPT
go
STEP 1
The type of query is SETON
STEP 1
The type of query is SETON
STEP 1
The type of query is SELECT
FROM TABLE
DEPT_ADMIN.DEPT
Nested iteration
Table Scan
FROM TABLE
STUDENT_ADMIN.STUDENT
Nested iteration
Table Scan

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

Oracle требует использования рекомендаций для того, чтобы влиять на действия и производительность своего оптимизатора, основывающегося на затратах. Оптимизатор, основанный на затратах, в Microsoft SQL Server не требует использования рекомендаций для принятия участия в процессе оценки запроса. Они, однако, все-таки представляются, поскольку в некоторых ситуациях могут требовать их использования.

Рекомендация INDEX = {index_name | index_id} задает имя или ID индекса для использования с таблицей. index_id, равное  0 вызывает обязательное сканирование таблицы, в те время как index_id, равное 1 вызывает использование кластеризованного индекса в том случае, если он существует. Это аналогично рекомендациям индекса в Oracle.

Рекомендация SQL Server FASTFIRSTROW указывает оптимизацию на необходимость использования некластеризованного индекса в том случае, если его порядок колонок соответствует пункту ORDER BY. Эта рекомендация аналогична рекомендации FIRST_ROWS в Oracle.

Использование ODBC

В этом разделе предоставляется информация о том, как Oracle и SQL Server используют ODBC, и о разработке или миграции приложений ODBC.

Рекомендуемая стратегия переноса

Используйте следующий процесс при переносе вашего приложения из Oracle к SQL Server:

1.   Обдумайте перенос вашего приложения в ODBC, если оно было изначально написано на Oracle Pro*C или с помощью Oracle Call Interface (OCI).

2.   Рассмотрите возможности курсоров и наборов записей по умолчанию, имеющихся в SQL Server, и выберите ту стратегию выборки, которая наиболее эффективна в вашем приложении.

3.   Переназначьте типы данных SQL ODBC от Oracle к SQL Server там, где это необходимо.

4.   Используйте расширения ODBC Extended SQL для создания общих инструкций SQL.

5.   Определите, необходим ли режим ручного подтверждения в приложении на основе SQL Server.

6.   Проверьте производительность вашего приложения и по необходимости измените код.

Архитектура ODBC

Microsoft предоставляет как 16-битную, так и 32-битную версии своего драйвера для доступа к SQL Server через ODBC. 32-битный драйвер ODBC SQL Server потокобезопасна (thread-safe). Драйвер сериализует разделяемый доступ нескольких потоков к разделенным дескрипторам инструкций (hstmt), дескрипторам соединений (hdbc) и дескрипторам сред (henv). Однако программа ODBC все еще отвечает за сохранение операций в инструкциях и пространствах соединений в соответствующем порядке, даже в том случае, если приложение использует несколько потоков.

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

В большей части случаев драйвер ODBC для Oracle использует SQL*Net для того, чтобы связаться с Oracle RDBMS. Однако SQL*Net может и не использоваться при установлении связи с Personal Oracle.

На иллюстрации приведена архитектура приложений/драйвера для 32-битных сред.

Термин переключение (thunking) означает перехват вызова функции, специальную ее обработку для перехода между 16-битным и 32-битным кодом и последующую передачу управления конечной функции. Обратите внимание на то, как ODBC Cursor Library может находиться между менеджером драйвера и соответствующим драйвером. Эта библиотека предоставляет возможности курсоров с прокруткой поверх драйверов, поддерживающих курсоры с возможностью продвижения только вперед.

Курсоры с возможностью продвижения только вперед

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

В Oracle любой результирующий набор записей команды SELECT рассматривается как курсор с возможностью продвижения только вперед при выборке на клиентском приложении. Это так при использовании ODBC, OCI или Embedded SQL в качестве инструмента разработки.

По умолчанию, каждая команда FETCH в Oracle, выданная клиентским приложением (например, SQLFetch в ODBC) вызывает обращение к серверу для возврата одной строки. Если клиентскому приложению необходимо выбрать более одной строки за раз, оно должно создать массив и выполнить выборку в массив.

Между выборками на курсоре только для чтения не удерживается никаких блокировок благодаря модели многоверсионного параллелизма, используемой в  Oracle. Когда программа задает обновляемый курсор с помощью пункта FOR UPDATE, все строки, запрашиваемые командой SELECT, блокируются при открытии инструкции. Такие блокировки уровня строки будут удерживаться до выдачи программой инструкции COMMIT или ROLLBACK.

В SQL Server инструкция SELECT не всегда ассоциируется с курсором на сервере. По умолчанию, SQL Server просто передает все строки результирующего набора записей из инструкции SELECT клиенту. Эта передача начинается сразу же по выполнению инструкции SELECT. Передача результирующих наборов записей также может быть выполнена инструкциями SELECT в хранимых процедурах. Более того, одна хранимая процедура или пакет команд может передать несколько наборов записей в ответ на одну инструкцию EXECUTE.

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

По сравнению с курсорами Oracle, результирующие наборы записей по умолчанию накладывают некоторые ограничения на клиентское приложение SQL Server. Клиентское приложение SQL Server должно сразу же выбирать все строки результирующего набора записей, возвращенного инструкцией EXECUTE. Если приложение должно передавать данные по частям, одно должно буферизовать их во внутренний массив. Если приложение не выбирает все данные, соединение с SQL Server остается занятым.

В таком случае никакая иная работа (вроде инструкции UPDATE) не может быть выполнена на этом соединении до тех пор, пока все данные не будут выбраны или же клиент не отменит запрос. Более того, сервер продолжает удерживать разделенные блокировки на страницах данных таблицы до окончания выборки. Тот факт, что эти разделенные блокировки удерживаются до окончания выборки, делает обязательной как можно более скорую выборку всех строк. Такая техника прямо противоположна пошаговой выборке, часто встречающейся в приложениях Oracle.

Серверные курсоры

Microsoft SQL Server предоставляет серверные курсоры для удовлетворения необходимости в пошаговой выборке результирующих наборов записей по сети. Серверные курсоры могут быть запрошены в приложении с помощью обращения к SQLSetStmtOption и установки параметра SQL_CURSOR_TYPE.

Когда инструкция SELECT выполняется как серверный курсор, инструкция EXECUTE возвращает только идентификатор курсора. Последующие запросы на выборку передают обратно на сервер идентификатор курсора и параметр, задающий число строк к выборке. Сервер возвращает запрошенное число строк.

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

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

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

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

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

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

По этим причинам, разумно ограничить использование серверных курсоров теми частями вашего приложения, где их функции реально необходимы. Примером, демонстрирующим использование серверных курсоров, может служить функция LIST_STUDENTS в файле примера (Ssdemo.cpp) SQL Server ODBC.

Курсоры с прокруткой

RDBMS Oracle поддерживает только курсоры с продвижением вперед. Каждая строка выбирается приложением в том порядке, который был задан в запросе. Oracle не поддерживает перемещения назад к уже прочитанной строке. Единственной возможностью вернуться назад является закрытие и повторное открытие курсора. К сожалению, в таком случае происходит позиционирование на первую запись в активном наборе записей.

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

Хотя Oracle напрямую не поддерживает прокручиваемых курсоров, это ограничение может быть обойдено при использовании определенных возможностей ODBC. К примеру, некоторые драйвера ODBC Oracle, такие как драйвер, поставляемый со средой визуальной разработки Microsoft Developer Studio®, предоставляют основанные на клиенте прокручиваемые курсоры в самом драйвере.

Как вариант, ODBC Cursor Library поддерживает курсоры с блоковой прокруткой в любом драйвере ODBC, соответствующем уровню совместимости Level One. Оба этих варианта курсоров реализуют прокрутку посредством использования RDBMS для прямой выборки, и кэширования данных в памяти или на диске. При запросе данных, драйвер по необходимости получает их из RDBMS или локального кэша.

Курсоры, основанные на клиенте, также поддерживают позиционированные инструкции UPDATE и DELETE для наборов записей, созданных инструкциями SELECT. Библиотека курсоров создает инструкции UPDATE и DELETE с пунктом WHERE, указывающим  кэшированное значение каждой колонки в строке.

Если вам необходимы курсоры с прокруткой, и вы пытаетесь сохранить один и тот же исходный код для реализаций в Oracle и SQL Server, ODBC Cursor Library может оказаться полезным вариантом. Более подробную информацию о ODBC Cursor Library можно найти в документации по ODBC.

Стратегии использования результативных наборов записей по умолчанию и серверных курсоров SQL Server

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

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

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

§  Если приложение требует возможностей прокрутки, курсоров только для чтения, как ODBC Cursor Library, так и серверные курсоры могут стать хорошими вариантами. ODBC Cursor Library дает вам совместимость между SQL Server и Oracle, а серверные курсоры дает вам большую гибкость, например, в части объема выбираемых данных.

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

§  При использовании серверных курсоров, старайтесь использовать SQLExtendedFetch для выборки блоками строк, а не построчно. Это аналогично выборке в массив в приложениях Oracle. Каждый запрос на выборку из серверного курсора требует обращения от приложения к RDBMS в сети.

§  Аналогией может служить покупка бакалейных товаров. Предположим, вы покупаете 10 мешков товаров в магазине, загружаете один в машину, едете домой, выгружаете его и возвращаетесь в магазин за следующим. Это – маловероятный сценарий; но именно так вы поступаете, обращаясь к SQL Server из вашей программы с построчной выборкой из серверного курсора.

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

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

Примеры такой техники можно увидеть в  функции LIST_STUDENTS в файле Ssdemo.cpp примерной программы SQL Server ODBC. Обратите внимание на то, что серверный курсор запрашивается только тогда, когда инструкция SELECT может вернуть больше одной строки. После выполнения, размер набора записей устанавливается в разумный размер пакета. Это позволяет одному и тому же циклу SQLExtendedFetch работать эффективно как в случае результативных наборов записей по умолчанию, так и в случае серверных курсоров.

Более подробную информацию о реализации курсора можно найти в SQL Server Books Online.

Несколько активных инструкций (hstmt) на соединение

Драйвер ODBC использует дескриптор инструкции (hstmt) для отслеживания каждой инструкции SQL в программе. Дескриптор инструкции всегда связан с дескриптором соединения с RDBMS (hdbc). Менеджер драйверов ODBC использует дескриптор соединения для отсылки запрашиваемой инструкции SQL в указанную RDBMS. Большая часть драйверов ODBC для Oracle позволяют использовать нескольких инструкций на соединение. Однако драйвер ODBC для SQL Server позволяет только один активный дескриптор инструкции на соединение в случае использования результативных наборов записей по умолчанию. Функция SQLGetInfo этого драйвера SQL Server возвращает 1 при запросе параметра SQL_ACTIVE_STATEMENTS. При установке параметров таким образом, чтобы сделать возможным использование серверных курсоров, поддерживаются несколько активных инструкций на соединение.

Более подробную информацию об установке параметров инструкций для запроса серверных курсоров можно найти в SQL Server Books Online.

Привязка типов данных

Драйвер ODBC для SQL Server предоставляет более богатый набор привязок типов данных, нежели большая часть доступных драйверов ODBC для Oracle.

Тип данных Microsoft SQL Server

Тип данных SQL ODBC

binary

SQL_BINARY

bit

SQL_BIT

char, character

SQL_CHAR

datetime

SQL_TIMESTAMP

decimal, dec

SQL_DECIMAL

float, double precision, float(n) для n = 8-15

SQL_FLOAT

Image

SQL_LONGVARBINARY

int, integer

SQL_INTEGER

Money

SQL_DECIMAL

Nchar

SQL_WCHAR

Ntext

SQL_WLONGVARCHAR

Numeric

SQL_NUMERIC

Nvarchar

SQL_WVARCHAR

real, float(n) для n = 1-7

SQL_REAL

Smalldatetime

SQL_TIMESTAMP

Smallint

SQL_SMALLINT

Smallmoney

SQL_DECIMAL

Sysname

SQL_VARCHAR

Text

SQL_LONGVARCHAR

Timestamp

SQL_BINARY

Tinyint

SQL_TINYINT

Uniqueidentifier

SQL_GUID

Varbinary

SQL_VARBINARY

Varchar

SQL_VARCHAR

Тип данных timestamp преобразуется в тип данных SQL_BINARY. Это вызвано тем, что значения в колонке timestamp не являются данными типа datetime, но данными типа binary(8). Они используются для индикации последовательности действий SQL Server на строке.

Привязки типов данных Oracle для драйвера Microsoft ODBC для Oracle указаны в следующей таблице.

Тип данных Oracle

Тип данных SQL ODBC

CHAR

SQL_CHAR

DATE

SQL_TIMESTAMP

LONG

SQL_LONGVARCHAR

LONG RAW

SQL_LONGVARBINARY

NUMBER

SQL_FLOAT

NUMBER(P)

SQL_DECIMAL

NUMBER(P,S)

SQL_DECIMAL

RAW

SQL_BINARY

VARCHAR2

SQL_VARCHAR

Драйвера ODBC для Oracle от других производителей могут иметь иные привязки типов данных.

ODBC Extended SQL

Стандарт ODBC Extended SQL предоставляет расширения SQL для ODBC, поддерживающие набор продвинутых нестандартных функций SQL, предоставляемый как Oracle, так и SQL Server. Этот стандарт позволяет драйверу ODBC преобразовывать общие инструкции SQL в родной для Oracle или для SQL Server синтаксис SQL.

Этот стандарт связан с внешними связями, предикатными знаками переключения, скалярными функциями, значениями даты/времени/временной метки и хранимыми программами. Этот синтаксис используется для определения этих расширений:

--(*vendor(Microsoft), product(ODBC) extension *)--

OR

{extension}

Преобразование происходит во время выполнения и не требует какого-либо пересмотра программного кода. В большей части сценариев разработки программ, наилучшим подходом будет написание одной программы и оставление ODBC выполнения конверсии для конкретной RDBMS во время выполнения программы.

Внешние связи

Oracle и SQL Server не имеют совместимого синтаксиса внешних связей. Это может быть разрешено с помощью синтаксиса внешних связей ODBC extended SQL. Синтаксис Microsoft SQL Server совпадает с синтаксисом ODBC Extended SQL/SQL-92. Единственным отличием является контейнер {oj    }.

ODBC Extended SQL и SQL-92

Oracle

Microsoft SQL Server

SELECT STUDENT.SSN, FNAME, LNAME, CCODE, GRADE
FROM {oj STUDENT LEFT OUTER JOIN GRADE ON STUDENT.SSN = GRADE.SSN}

SELECT STUDENT.SSN, FNAME, LNAME,
CCODE, GRADE
FROM STUDENT, GRADE
WHERE STUDENT.SSN = GRADE.SSN(+)

SELECT STUDENT.SSN, FNAME, LNAME,
     CCODE, GRADE
FROM STUDENT LEFT OUTER JOIN GRADE
     ON STUDENT.SSN = GRADE.SSN

Значения даты, времени и временной метки

ODBC предоставляет три символа переключения для значений даты, времени и временной метки.

Категория

Краткий синтаксис

Формат

Дата

{d 'value'}

"yyyy-mm-dd"

Время

{t 'value'}

"hh:mm:ss"

Временная метка

{Ts 'value'}

"yyyy-mm-dd hh:mm:ss[.f…]"

Формат даты более влияет на приложения Oracle, чем на приложения SQL Server. Oracle ожидает формата даты DD-MON-YY”. В любом другом случае для выполнения преобразования используются функции TO_CHAR или TO_DATE вкупе с моделью формата данных.

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

Как указано в таблице, ODBC Extended SQL работает с обеими базами данных. SQL Server не требует функций преобразования. И, тем не менее, краткий синтаксис ODBC может быть, в общем, применен как к Oracle, так и SQL Server.

ODBC Extended SQL

Oracle

Microsoft SQL Server

SELECT SSN, FNAME, LNAME, BIRTH_DATE
FROM STUDENT WHERE BIRTH_DATE < {D '1970-07-04'}

SELECT SSN, FNAME, LNAME,
     BIRTH_DATE
FROM STUDENT
WHERE BIRTH_DATE <
     TO_DATE('1970-07-04', 'YYYY-MM-DD')

SELECT SSN, FNAME, LNAME,
     BIRTH_DATE
FROM STUDENT
WHERE BIRTH_DATE < '1970-07-04'

Вызов хранимых процедур

Краткий синтаксис ODBC для вызова хранимых процедур поддерживает хранимые процедуры Microsoft SQL Server и хранимые процедуры, функции и пакеты Oracle. Возможное “?=” обрабатывает значение, возвращаемое функцией Oracle или процедурой SQL Server. Синтаксис параметров используется для передачи и возврата информации в/из программы. В большей части ситуаций один и тот же синтаксис может быть применен в приложениях на основе Oracle или SQL Server.

В нижеприведенном примере функция SHOW_RELUCTANT_STUDENTS является частью пакета P1 в Oracle. Эта функция должна существовать в пакете, поскольку она возвращает несколько строк из курсора PL/SQL. Когда вы вызываете функцию или процедуру, существующую в пакете, имя пакета должно быть указано перед именем программы.

Функция SHOW_RELUCTANT_STUDENTS в пакете P1 использует курсор пакета для возвращения нескольких строк данных. Каждая строка должны быть запрошена вызовом этой функции. Если больше не осталось строк для запроса, функция возвращает 0, указывая на окончание данных. Конечная производительность этого примерного пакета Oracle и его функций может быть менее чем удовлетворительной. В данном примере, функция SQL Server значительно быстрее.

Обобщенный ODBC Extended SQL

Oracle

Microsoft SQL Server

{?=} call procedure_name[(parameter(s))]}

SQLExecDirect(hstmt1,(SQLCHAR *)"{? = call owner.procedure(?)}",
SQL_NTS);

SQLExecDirect(hstmt1, (SQLCHAR*)"{? = call
     STUDENT_ADMIN.P1.
SHOW_RELUCTANT
_STUDENTS(?)}"
,
SQL_NTS);

SQLExecDirect(hstmt1, (SQLCHAR*)"{? = call
     STUDENT_ADMIN.
SHOW_RELUCTANT
_STUDENTS}"
,
SQL_NTS);

Перевод "родного" SQL

Из-за множества доступных драйверов ODBC как для Oracle, так и для SQL Server, вы можете не всегда получать одну и ту же строку преобразования для расширенных функций SQL. Для того чтобы приложения было легче отлаживать, вы можете использовать функцию SQLNativeSql. Эта функция возвращает строку SQL в том виде, в который ее преобразовывает драйвер.

Ниже приведены возможные результаты преобразования строки SQL, содержащей скалярную функцию CONVERT. Колонка SSN определена как CHAR(9), и преобразовывается в числовое значение.

Исходная инструкция

Инструкция, преобразованная в Oracle

Инструкция, преобразованная в SQL Server

SELECT (fn CONVERT
(SSN, SQL_INTEGER)}

FROM STUDENT

SELECT TO_NUMBER(SSN)
FROM STUDENT

SELECT CONVERT(INT,SSN)
FROM STUDENT

Примерная программа Common.cpp

Примерная программа Common.cpp не использует преимуществ синтаксиса ODBC Extended SQL. Скорее, она реализует набор представлений данных и процедур для инкапсуляции всех функций, не являющихся общими для Oracle и SQL Server. Эта программа, хотя и написанная с помощью ODBC, предназначена для того, чтобы показать, как программист может легко обойти любые очевидные преграды при написании общей программы.

Эти техники и стратегии лучше всего реализуются в средах разработки, не использующих ODBC. Если вы используете ODBC, рассмотрите вариант использования синтаксиса ODBC Extended SQL для обхода каких-либо синтаксических отличий между Oracle и SQL Server.

Режим ручного подтверждения

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

По умолчанию, SQL Server автоматически подтверждает каждое произошедшее изменение. В ODBC это называется режимом автоматического подтверждения. Если вы не хотите, чтобы это происходило, вы можете использовать инструкцию BEGIN TRANSACTION для сигнализации начала блока инструкций, составляющих транзакцию. После выдачи такой инструкции, должна следовать явная инструкция COMMIT TRANSACTION или ROLLBACK TRANSACTION.

Для гарантии совместимости с вашим приложением для Oracle рекомендуется использовать функцию SQLConnectOption для введения вашего приложения на базе SQL Server в режим неявных транзакций. Параметр SQL_AUTOCOMMIT должен быть выставлен в SQL_AUTOCOMMIT_OFF для выполнения этого. Эта выдержка из кода примерного приложения демонстрирует такую концепцию:

SQLSetConnectOption(hdbc1, SQL_AUTOCOMMIT,-sql_AUTOCOMMIT_OFF);

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

Если выставлен параметр SQL_AUTOCOMMIT_OFF, приложение должно явно подтверждать или откатывать транзакции с помощью функции SQLTransact. Эта функция запрашивает операцию подтверждения или отката по всем активным операциям на всех дескрипторах инструкций, связанных с дескриптором соединения. Она также может запросить операцию подтверждения или отката по всем дескрипторам соединений, связанным с дескриптором среды.

SQLTransact(henv1, hdbc1, SQL_ROLLBACK);
(SQLTransact(henv1, hdbc1, SQL_COMMIT);

При выключенном режиме автоматического подтверждения драйвер выдает инструкцию SET IMPLICIT_TRANSACTIONS ON на сервер. Начиная с SQL Server 6.5, в этом режиме поддерживаются инструкции DDL.

Для подтверждения ил отката транзакции в режиме ручного подтверждения, приложение должно вызвать SQLTransact. Драйвер SQL Server посылает инструкцию COMMIT TRANSACTION для подтверждения транзакции и инструкцию ROLLBACK TRANSACTION для отката транзакции.

Будьте готовы к тому, что режим ручного подтверждения может заметно повлиять на производительность вашего приложения на основе SQL Server. Каждый запрос на подтверждение требует отдельного обращения к серверу для посылки строки COMMIT TRANSACTION.

Если у вас есть отдельные по-атомные транзакции (одиночные инструкции INSERT, UPDATE или DELETE, за которыми сразу же следует COMMIT), используйте режим автоматического подтверждения.

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

Разработка и администрирование репликации баз данных

В этом разделе объясняются различия в реализации репликации в Oracle и Microsoft SQL Server.

Oracle

Microsoft SQL Server

Репликация снимков только для чтения

Репликация снимков с немедленным обновлением подписчиков

Многомастерская репликация, обновляемые снимки

Репликация транзакциями с немедленным обновлением подписчиков – выгоднее для хорошо подсоединенных подписчиков, находящихся в режиме online в момент публикации.

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

Как видно из названия, репликация снимками в SQL Server делает снимок публикуемых данных в базе данных в определенный момент времени. Репликация снимками требует меньшей постоянной загрузки процессора, нежели репликация транзакциями, поскольку она не требует постоянного отслеживания изменений данных на исходных серверах. Вместо копирования инструкций INSERT, UPDATE и DELETE (что характерно для репликации транзакциями) или изменений данных (что характерно для репликации сведением), обновление на подписчиках происходит посредством полного обновления набора данных. Таким образом, репликация снимками отсылает все данные на подписчик вместо отсылки только изменений.

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

Репликация сведением SQL Server позволяет узлам вносить автономные изменения в реплицируемые данные, и позднее объединять изменения сделанные на всех узлах. Как и в Oracle, репликация сведением поддерживает выявление конфликтов, как на уровне колонок, так и на уровне строк. То есть, вы можете определить конфликткак любое изменение одной и той же строки в двух точках, или же только как одновременное изменение одной и той же колонки в двух точках.

SQL Server предоставляет возможности разнородной репликации, являющейся простейшим способом публикации данных на разнородных подписчиках с помощью ODBC и OLE/DB и создания исходящей публикации (push subscription) с издателя к подписчику ODBC. Альтернативой может служить, однако, создание публикации и последующее создание приложения с включенным управляющим элементом распределения. Включенный управляющий элемент реализует входящую публикацию (pull subscription) от подписчика к издателю. В случае подписчиков ODBC подписывающаяся база данных не имеет административных возможностей, касающихся выполняемой репликации.

Приведенная таблица сравнивает механизмы разрешения конфликтов в Oracle и SQL Server:

Oracle

Microsoft SQL Server

Разрешение на основе приоритета узлов или значений, запрограммированное с помощью PL/SQL

Разрешение на основе приоритетов с помощью COM или Transact-SQL

Разрешение конфликтов для “групп колонок”

Поддерживается с помощью разрешения, заданного пользователем

Разрешение конфликтов на уровне колонок и строк

Поддерживается и то, и другое

ODBC, OLE/DB и репликация

В Microsoft SQL Server сервер распределения подсоединяется ко всем серверам-подписчикам как клиент ODBC или OLE/DB. Репликация требует наличия 32-битных драйверов ODBC на всех серверах распределения. Программа SQL Server Setup автоматически устанавливает необходимые драйверы на компьютерах под управлением Windows NT.

Вам не нужно заранее определять источники данных ODBC для серверов-подписчиков SQL Server, поскольку процесс распределения просто использует сетевые имена подписчиков для установления соединения.

SQL Server также включает драйвер ODBC, поддерживающий подписку Oracle к SQL Server. Этот драйвер существует только в версии для компьютеров на базе процессоров Intel. Для репликации на подписчиков ODBC Oracle вы также должны соответствующий драйвер Oracle SQL*Net у Oracle или вашего поставщика программного обеспечения.

Если в реестре Windows NT указан пароль, драйвер ODBC для Oracle подсоединяется к Oracle, не запрашивая пароля. Если в реестре Windows NT не указан пароль, вы должны ввести имя пользователя и пароль для источника данных ODBC Oracle при задании параметров DSN в диалоговом окне New ODBC Subscriber SQL Server Enterprise Manager.

Необходимо учитывать следующие ограничения, касающиеся репликации на подписчиков ODBC Oracle:

§  Тип данных datetime привязан к типу данных DATE. Диапазон данных для типа данных DATE в Oracle лежит в пределах от 4712 до нашей эры до 4712 нашей эры. Если вы производите репликацию на Oracle, удостоверьтесь в том, что значения datetime в реплицируемой колонке SQL Server лежат в этих пределах.

§  Реплицируемая таблица может иметь только одну колонку text или image.

§  Тип данных datetime привязан к типу данных CHAR в Oracle.[A.A.R.1] 

§  Диапазоны типов float и real в SQL Server отличаются от аналогичных диапазонов в Oracle.

Драйвера иных подписчиков ODBC должны соответствовать репликационным требованиям SQL Server для обобщенных подписчиков ODBC. Драйвер ODBC:

§  Должен соответствовать требованиям ODBC Level 1.

§  Должен быть 32-битным потокобезопасным в той архитектуре процессора, на которой выполняется процесс распределения.

§  Должен иметь способности транзакций.

§  Должен поддерживать язык определения данных (DDL).

§  Не может быть только для чтения.

Перенос данных и приложений

В этом разделе представлены различные методы переноса данных из базы данных Oracle в базу данных Microsoft SQL Server.

Перенос данных с помощью Data Transformation Services

Простейшим методом переноса данных из Oracle в SQL Server является использование возможностей Data Transformation Services (DTS) в Microsoft SQL Server 7.0. Мастер DTS проведет вас через процесс переноса данных в SQL Server.

Oracle Call Interface (OCI)

Если ваши приложения используют Oracle Call Interface (OCI), вы можете счесть нужным переписать их с использованием ODBC. OCI специфичен для RDBMS Oracle и не может быть использован с Microsoft SQL Server или иными базами данных.

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

Oracle Call Interface

Oracle ODBC

rcl = olog(&logon_data_area, &host_data_area,
user_name, -1, (text*) 0, -1, (text) 0, -1,
OCI_LM_DEF);

rcl = SQLConnect(hdbc1,
(SQLCHAR*)
ODBC_dsn, (SQLSMALLINT) SQL_NTS,
(SQLCHAR*) user_name, (SQLSMALLINT) SQL_NTS,
(SQLCHAR*) user_password, (SQLSMALLINT) SQL_NTS);

В нижеприведенной таблице указаны примерные варианты переноса функций OCI в ODBC. Все они приблизительны. Может и не существовать точного совпадения при переносе. Ваш программный код может потребовать дополнительного пересмотра кода для достижения аналогичных функций.

Функция OCI

Функция ODBC

Obindps

SQLBindParameter

Obndra

SQLBindParameter

Obndrn

SQLBindParameter

Obndrv

SQLBindParameter

Obreak

SQLCancel

Ocan

SQLCancel, SQLFreeStmt

Oclose

SQLFreeStmt

Ocof

SQLSetConnectOption

Ocom

SQLTransact

Ocon

SQLSetConnectOption

Odefin

SQLBindCol

Odefinps

SQLBindCol

Odescr

SQLDescribeCol

Oerhms

SQLError

Oexec

SQLExecute, SQLExecDirect

Oexfet

SQLExecute, SQLExecDirect, and SQLFetch

Oexn

SQLExecute, SQLExecDirect

Ofen

SQLExtendedFetch

Ofetch

SQLFetch

Oflng

SQLGetData

Ogetpi

SQLGetData

Olog

SQLConnect

Ologof

SQLDisconnect

Oopen

SQLExecute, SQLExecDirect

Oparse

SQLPrepare

Orol

SQLTransact

Вложенный SQL

Многие приложения написаны с помощью Oracle Programmatic Interfaces (Pro*C, Pro*Cobol и так далее). Эти интерфейсы поддерживают использование вложенного SQL стандарта SQL-92. Они также включают характерные только для Oracle программные расширения.

Приложения для Oracle, использующие вложенный SQL, могут быть перенесены в SQL Server с помощью Microsoft Embedded SQL (ESQL) для сред разработки программ на языке C. Эта среда предоставляет адекватный, но менее чем оптимальный контроль за производительностью и использование возможностей SQL Server по сравнению с приложениями ODBC.

Некоторые возможности Oracle Pro* не поддерживаются в прекомпиляторе Microsofts ESQL. Если ваше приложение для Oracle активно использует эти возможности, возможно, лучшим вариантом перехода будет ее переработка для ODBC. В число таких возможностей входит:

§  Переменные массивов хостов.

§  Инструкции VAR и TYPE для выравнивания типов данных

§  Поддержка вложенного SQL в модулях C++.

§  Поддержка вложенных блоков PL/SQL или Transact-SQL.

§  Переменные курсоров.

§  Поддержка многопотоковых приложений.

§  Поддержка Oracle Communication Area (ORACA).

Если ваше приложение Oracle было разработано на Cobol, оно может быть перенесено в Embedded SQL для Cobol от Micro Focus. Вы можете столкнуться с теми же ограничениями в Cobol, что и в прекомпиляторе Microsoft ESQL для C.

Вы можете перенести ваше приложение с вложенным SQL для Oracle в среду ODBC. Этот процесс достаточно просто и предоставляет много преимуществ. ODBC не требует использования прекомпилятора, как того требует вложенный SQL. Следовательно, исчезает большая часть дополнительной нагрузки, связанной с разработкой программы.

В таблице указаны приблизительные отношения между инструкциями Embedded SQL и функциями ODBC.

Инструкции Embedded SQL

Функции ODBC

CONNECT

SQLConnect

PREPARE

SQLPrepare

EXECUTE

SQLExecute

DECLARE CURSOR и OPEN CURSOR

SQLExecute

EXECUTE IMMEDIATE

SQLExecDirect

DESCRIBE SELECT LIST

SQLNumResultCols, SQLColAttributes, SQLDescribeCol

FETCH

SQLFetch

SQLCA.SQLERRD[2]

SQLRowCount

CLOSE

SQLFreeStmt

COMMIT WORK, ROLLBACK WORK

SQLTransact

COMMIT WORK RELEASE,
ROLLBACK WORK RELEASE

SQLDisconnect

SQLCA, SQLSTATE

SQLError

ALTER, CREATE, DROP, GRANT, REVOKE

SQLExecute, SQLExecDirect

Наиболее значительные изменения при переносе программ с использованием вложенного SQL в среду ODBC связаны с обработкой ошибок инструкций SQL. Параметр MODE = ORACLE часто используется при разработке программ с использованием вложенного SQL. При использовании этого параметра SQL Communications Area (SQLCA) обычно используется для операций обработки ошибок.

Структура SQLCA содержит:

§  Коды ошибок Oracle.

§  Сообщения об ошибках Oracle.

§  Предупреждающие флаги.

§  Информацию о событиях программы.

§  Число строк, обработанных последней инструкцией SQL.

В большей части случаев вам следует проверять значение переменной sqlca.sqlcode после выполнения каждой инструкции SQL. Если ее значение меньше нуля, значит, произошла ошибка. Если значение больше нуля, запрошенная инструкция была выполнена с предупреждениями. Текст сообщения об ошибках Oracle может быть получен из переменной sqlca.sqlerrm.sqlerrmc.

В ODBC функция возвращает цифровой код статуса, означающий успешное выполнение или провал, сразу же после выполнения запрошенной операции. Коды статусов определяются литералами, и в их число входят SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR и прочие. Проверка этих кодов после каждого вызова функции ложится на вас.

Связанное значение SQLSTATE может быть получено с помощью вызова функции SQLError. Эта функция возвращает код ошибки SQLSTATE, родной код ошибки (специфичный для источника данных) и текст сообщения об ошибке.

Приложение обычно вызывает эту функцию после того, как предыдущий вызов функции ODBC вернул SQL_ERROR или SQL_SUCCESS_WITH_INFO. Однако же, любая функция ODBC может послать ноль и более сообщений при выполнении, так что приложение может вызывать SQLError после каждого вызова функции ODBC.

Вот примеры обработки ошибок в каждой из сред.

Oracle Pro*C и EMBEDDED SQL

Oracle ODBC

EXEC SQL DECLARE CURSOR C1 CURSOR
     FOR SELECT SSN, FNAME, LNAME FROM    STUDENT ORDER BY SSN;
EXEC SQL OPEN C1;
if (sqlca.sqlcode) != 0 {
/* handle error condition,
     look at sqlca.sqlerrm.sqlerrmc for error      description...*/}

if (SQLExecDirect(hstmtl,
(SQLCHAR*)"SELECT SSN, FNAME, LNAME
     FROM STUDENT ORDER BY SSN",
     SQL_NTS) != SQL_SUCCESS) {
/* handle error condition, use SQLError
     for SQLSTATE details regarding error...*/}

Developer 2000 и приложения третьих фирм

Если вы разработали приложение с помощью Oracle Developer 2000 и хотите использовать его с SQL Server, рассмотрите вариант его переноса в Microsoft Visual Basic®. Visual Basic – это мощная система разработки, работающая с обеими базами данных. Вы можете также рассмотреть варианты иных систем разработки  в системе Microsoft Visual Studio, или PowerBuilder, SQL Windows и иных.

Если вы не имеете возможности сразу же мигрировать из Developer 2000, рассмотрите вариант использования Oracle Gateway для SQL Server. Он может быть использован как промежуточный шаг при миграции от Oracle к SQL Server. Этот шлюз позволяет RDBMS Oracle подсоединяться SQL Server. Все запросы к данным SQL Server автоматически перерабатываются шлюзом. С точки зрения приложения Developer 2000, это подсоединения прозрачно. Данные SQL Server выглядят как данные Oracle. В программный код должно быть внесено совсем немного изменений.

Еще одним промежуточным шагом может быть использование приложения Developer 2000 напрямую с SQL Server. Developer 2000 может напрямую работать с SQL Server с помощью Oracle Open Client Adapter (OCA). OCA удовлетворяет требованиям ODBC Level 1 и имеет ограниченную поддержку функций ODBC Level 2.

OCA устанавливает соединение с драйвером ODBC для SQL Server. При подсоединении инструментария Developer 2000 к SQL Server, вы должны указать имя источника данных ODBC как часть строки соединения с базой данных. При выходе из приложения Developer 2000, соединение OCA с источником данных ODBC прекращается.

Синтаксис строки входа в систему и соединения продемонстрирован в нижеприведенном примере. В этом примере пользователь входит в SQL Server, используя учетную запись STUDENT_ADMIN. Имя источника данных ODBC SQL Server - STUDENT_DATA:

STUDENT_ADMIN/STUDENT_ADMIN@ODBC:STUDENT_DATA

Использование драйвера ODBC не гарантирует корректной работы приложения Developer 2000 с SQL Server. Программный код приложения должны быть соответствующим образом изменен для работы с иным источником данных, нежели Oracle. К примеру, свойства защиты колонок характерно только для Oracle и не работает в SQL Server.

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

Также должен быть изменен режим блокировки. При использовании Oracle Developer 2000 пытается блокировать каждую строку данных сразу же после изменения в этой строке. При использовании SQL Server режим блокировки должен быть установлен в "отложенный" (delayed), чтобы строка блокировалась только при ее записи в базу данных.

Существует ряд других вопросов, также требующих разрешения, включая возможность ситуаций взаимоблокировки в случае многочисленных вставок в одну и ту же страницу данных таблицы в программном блоке PL/SQL. Более подробную информацию можно найти в разделе “Транзакции, блокировка и параллелизмданного документа.

Интернет-приложения

Microsoft SQL Server включает в себя SQL Server Web Assistant, мастер, создающий стандартные файлы HTML из данных SQL Server. Мастер может сконфигурировать вашу страницу Web таким образом, чтобы она была статичной, периодически обновляемой или обновляемой при изменении данных. Мастер проводит вас через процесс создания веб-страницы.

Заключение

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

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


 [A.A.R.1]Есть несоответствие с предыдущими высказываниями – на два пункта выше