Программирование >>  Программирование баз данных 

1 ... 106 107 108 [ 109 ] 110 111 112 ... 346


go как команда, а не оператор языка T-SQL

Одной из распространенных ошибок является мнение о том, что GO - оператор языка T-SQL. В действительности GO - это команда, которая распознается только инструментальными средствами редактирования (Management Studio, SQLCMD). Некоторые инструментальные средства независимых разработчиков не поддерживают команду GO, но большинство тех средств, которые предназначены для использования в СУБД SQL Server, обеспечивают такую поддержку.

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

При попытке включить оператор GO в транзитный запрос с использованием ODBC, OLE DB, ADO, ADO.NET или любого другого метода доступа сервер возвращает сообщение об ошибке. Оператор GO воспринимается только инструментальными средствами и служит индикатором того, что заканчивается текущий пакет и начинается дрзгой. В каждом из упомянутых выше методов доступа в качестве команды рассматриваются в основном разные объекты. В частности, как объект команды может рассматриваться ряд взаимосвязанных операторов, но при этом подразумевается, что каждое вьшолнение объекта команды равносильно применению одного и только одного пакета.

Ошибки в пакетах

Ошибки в пакетах подразделяются на две категории:

синтаксические ошибки;

ошибки, обнаруживаемые на этапе прогона программы.

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

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



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

Условия использования пакетов

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

Операторы, для которых требуется отдельный пакет

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

CREATE DEFAULT;

CREATE PROCEDURE;

CREATE RULE;

CREATE TRIGGER;

CREATE VIEW.

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

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

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

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



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

CREATE DATABASE Test

CREATE TABLE TestTable

coll int, col2 int

После вызова этого сценария на выполнение на первый взгляд создается такое впечатление, что все действия завершены успешно: Command(s) completed successfully.

В действительности же дело обстоит иначе- достаточно проверить схему INFORMATION SCHEMA в базе данных Test, в результате чего обнаруживается, что некоторые объекты в этой базе данных отсутствуют:

SELECT TABLE CATALOG FROM INFORMATION SCHEMA.TABLES WHERE TABLE NAME =

TestTable TABLE CATALOG

master

(1 row(s) affected)

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

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

Даже поверхностные размышления на эту тему могут привести к заключению, что возникшую ошибку легко исправить, - достаточно предусмотреть применение оператора USE, но прежде чем проверить это предположение, необходимо удалить старую (вернее, не такую уж старую) базу данных:

USE MASTER

DROP DATABASE Test

Теперь попытаемся вызвать на вьшолнение сценарий с внесенными в него изменениями:

CREATE DATABASE Test USE Test

CREATE TABLE TestTable

coll int, col2 int



1 ... 106 107 108 [ 109 ] 110 111 112 ... 346

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика