Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык SQL программирование Ред.doc
Скачиваний:
10
Добавлен:
26.08.2019
Размер:
702.46 Кб
Скачать

Преобразование типов.

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

  • Выражения содержат данные одинаковых типов.

  • Тип данных с более низким приоритетом может быть неявно преобразован в тип данных с более высоким приоритетом.

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

Если неявное или явное преобразование не поддерживается, эти два операнда объединить невозможно.

Матрица преобразования.

Конвертирование чисел в символьные данные, для этого используется специализированная функция STR.

Возвращает символьные данные, преобразованные из числовых данных.

Синтаксис:

STR ( float_expression [ , length [ , decimal ] ] )

Аргументы:

float_expression - Выражение приближенного числового (float) типа данных с десятичной запятой.

length - Общая длина. Она включает десятичную запятую, знак, цифры и пробелы. Значение по умолчанию 10.

decimal - Количество знаков справа от десятичной запятой. Аргумент decimal должен быть меньше или равен 16. Если аргумент decimal больше 16, результат усекается до 16 знаков после запятой.

Типы возвращаемых данных: char

Пример:

SELECT STR(123.45, 5, 1)

GO

Результат:

123.5

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

CONVERT и CAST примерно одинаковы и могут быть взаимозаменяемыми. Функция CAST включена в стандарт ANSI, CONVERT- нет.

CAST ( expression AS data_type [ (length ) ])

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

data_type - Целевой тип данных. Псевдонимы типов данных недопустимы.

length - Необязательный параметр для типов данных nchar, nvarchar, char, varchar, binary и varbinary. Если в функции CONVERT аргумент length не указан, его значение по умолчанию — 30 символов.

С помощью аргумента style (стиль) можно управлять стилем представления значений следующих типов данных: дата/время, денежный или нецелочисленный.

style - Стиль формата даты, используемого для преобразования типов datetime и smalldatetime в символьные данные (типов nchar, nvarchar, char, varchar, nchar или nvarchar), либо для преобразования символьных данных известных форматов даты и времени в данные типов datetime и smalldatetime; либо строковый формат, используемый для преобразования данных типов float, real, money и smallmoney в символьные данные (типов nchar, nvarchar, char, varchar, nchar и nvarchar). Если аргумент style имеет значение NULL, возвращаемый результат также будет NULL.

Некоторые допустимые значения этого аргумента приведены в таблицах.

Таблица. Значение аргумента «style» для типов данных DATETIME и SMALLDATETIME.

Стиль

Формат символьного значения

101

mm/dd/yy

102

yy.mm.dd

103

dd/mm/yy

104

dd.mm/yy

105

dd-mm-yy

108

hh:mm:ss

110

mm-dd-yy

111

yy/mm/dd

Таблица. Значение аргумента «стиль» для типов данных FLOAT и REAL.

Стиль

Поведение

0

Максимум 6 цифр

1

Всегда 8 цифр

2

Всегда 16 цифр

Дополнительно см. документацию.

SET QUOTED_IDENTIFIER on

SET DATEFORMAT dmy

DECLARE @d DateTime, @str char(20)

SET @str= 'asdfghjklasdfghjklhg'

SELECT @str

Результат: asdfghjklasdfghjklhg

set @d ='31.01.2005'

SELECT @d

Результат: 2005-01-31 00:00:00.000

SET @d = @d+1

SELECT @d

Результат: 2005-02-01 00:00:00.000

SET @str = CAST(@d AS Char(20))

SELECT @str

Результат: Feb 1 2005 12:00AM

SET @str= '31.01.2005'

SET @d = CAST(@str AS DateTime)

SELECT @d

Результат: 2005-01-31 00:00:00.000

CONVERT:

SET QUOTED_IDENTIFIER on

DECLARE @myval decimal (5, 2)

SET @myval = 193.57

SELECT CONVERT(decimal(10,5), @myval)

Результат: 193.57000

DECLARE @d DateTime, @str char(20)

SET @d = '31.01.2005 13:23:15'

SET @str = Convert(Char(20), @d )

SELECT @str

Результат: Jan 31 2005 1:23PM

DECLARE @d DateTime, @str char(20)

SET @str = '31.01.2005 13:23:15'

SET @d = Convert(DateTime, @str )

SELECT @str

Результат:

31.01.2005 13:23:15

Пример: измененный SET DATEFORMAT mdy

SET QUOTED_IDENTIFIER on

SET DATEFORMAT mdy

DECLARE @d DateTime, @str char(20)

SET @str= 'asdfghjklasdfghjklhg'

SELECT @str

Результат: asdfghjklasdfghjklhg

set @d ='01.31.2005'

SELECT @d

Результат: 2005-01-31 00:00:00.000

SET @d = @d+1

SELECT @d

Результат: 2005-02-01 00:00:00.000

Преобразование двоичных строковых данных

Если при преобразовании данных типа binary или varbinary в символьные после х указано нечетное число значений, SQL Server добавит ноль (0) после х для получения четного числа значений.

Двоичные данные составлены из двухсимвольных групп, где символы принимают значения от 0 до 9 и от A до F (или от a до f). Двоичные строки должны начинаться с 0x. Например, чтобы ввести FF, введите 0xFF. Максимальным значением будет двоичное значение длиной 8 000 байт, каждый из них представляет собой FF. Типы данных binary предназначены не для шестнадцатеричных данных, а для битовых шаблонов. Преобразования и вычисления с использованием шестнадцатеричных чисел, хранящихся в виде двоичных данных, ненадежны.

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

Пустые двоичные строки представляются в виде 0x и могут храниться в виде двоичных данных.

DECLARE @d binary(5), @number decimal(38)

SET @number = 1234567890

SET @d = Convert(binary(5), @number )

SELECT @d

SET @d = 0x26000001D2

SET @number = Convert(decimal(38), @d )

SELECT @number

Блок операторов.

Группировка двух и более команд в единый блок осуществляется с использованием ключевых слов BEGIN и END:

<блок_операторов>::=

BEGIN

{ sql_оператор | блок_операторов }

END

Инструкция BEGIN занимает одну строку; за ней следует блок инструкций. В конце инструкция END также занимает одну строку, указывая на завершение блока.

Блоки BEGIN...END могут быть вложенными.

Блок инструкций BEGIN и END должен содержать минимум одну инструкцию (оператор).

Инструкции BEGIN и END используются, когда:

  • в цикл WHILE необходимо включить блок инструкций;

  • в элемент функции CASE необходимо включить блок инструкций;

  • в предложение IF или ELSE необходимо включить блок инструкций.

В блок инструкций BEGIN и END нельзя помещать команды, изменяющие структуры объектов БД.

Сгруппированные команды воспринимаются интерпретатором SQL как одна команда.

Некоторые команды SQL не должны выполняться вместе с другими командами (речь идет о командах резервного копирования, изменения структуры таблиц, хранимых процедур и им подобных), поэтому их совместное включение в конструкцию BEGIN...END не допускается.

Синтаксис условного оператора:

<условный_оператор>::=

IF лог_выражение

{ sql_оператор | блок_операторов }

[ ELSE

{sql_оператор | блок_операторов } ]

Пример:

DECLARE @a INT

DECLARE @str CHAR(30)

SET @a = (SELECT COUNT(*) FROM Authors)

IF @a >10

BEGIN

SET @str = 'Количество авторов больше 10'

SELECT @str

END ELSE

BEGIN

SET @str = 'Количество авторов = ' + str(@a)

SELECT @str

END

Результат:

Циклы организуются с помощью следующей конструкции:

<оператор_цикла>::=

WHILE лог_выражение

{ sql_оператор | блок_операторов }

[ BREAK ]

{ sql_оператор | блок_операторов }

[ CONTINUE ]

Цикл можно принудительно остановить, если в его теле выполнить команду BREAK.

Если же нужно начать цикл заново, не дожидаясь выполнения всех команд в теле, необходимо выполнить команду CONTINUE.

Пример:

DECLARE @a INT

SET @a = 1

WHILE @a <100

BEGIN

PRINT @a -- вывод на экран значения переменной

IF (@a>40) AND (@a<50)

BREAK -- выход и выполнение 1-й команды за циклом

ELSE

SET @a = @a+rand()*10

CONTINUE

END

PRINT @a

Результат:

1

7

11

11

13

22

26

31

37

45

45

Пример программы заполнения таблицы датами в заданном диапазоне (от 1 января 2000 года до 1 января 2001):

IF OBJECT_ID('dbo.Nums1', 'U') IS NOT NULL DROP TABLE dbo.Nums1;

CREATE TABLE dbo.Nums1(d datetime PRIMARY KEY)

DECLARE @i AS INT;

SET @i = 1;

WHILE @i <= datediff (day, '20000101', '20010101')

BEGIN

INSERT INTO dbo.Nums1 VALUES(DATEADD(day, @i-1, '20000101'));

SET @i = @i + 1;

END

GO

select * from dbo.Nums1

Результат:

Пример программы подсчета количества вхождения символа d в заданную строку символов:

DECLARE @a INT, @beginind int, @n int, @perem1 varchar(30)

SET @perem1 ='dsdqwddfgerd'

SET @n = 0

WHILE PATINDEX('%d%',@perem1) > 0

BEGIN

SET @beginind = PATINDEX('%d%',@perem1)

SET @perem1 =RIGHT(@perem1, len(@perem1)- @beginind)

SET @n=@n +1

end

PRINT @n

Результат: 5

PATINDEX -Выполняет поиск подстроки в строке по указанному шаблону

Выражение CASE

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

Выражение CASE имеет два формата:

  • простое выражение CASE для определения результата, которое сравнивает выражение с набором простых выражений;

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

Оба формата поддерживают дополнительный аргумент ELSE.

Простое выражение CASE

CASE input_expression

     WHEN when_expression THEN result_expression [ ...n ]

     [ ELSE else_result_expression ]

END

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

Поисковое выражение CASE:

CASE

     WHEN Boolean_expression THEN result_expression [ ...n ]

     [ ELSE else_result_expression ]

END

Предложение CASE в поисковом формате отличается от CASE в простом формате тем, что в поисковом формате после ключевого слова CASE нет входного выражения, а после ключевых слов WHEN следуют булевы выражения, которые проверяются на значение TRUE или FALSE (а не на равенство).

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

Аргументы:

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

WHEN when_expression - Простое выражение, с которым сравнивается аргумент input_expression при использовании простого формата функции CASE. Аргумент when_expression представляет собой любое допустимое выражение. Типы данных аргумента input_expression и каждого из выражений when_expression должны быть одинаковыми или неявно приводимыми друг к другу.

THEN result_expression - Выражение, возвращаемое, если сравнение выражений input_expression и when_expression дает в результате TRUE или выражение Boolean_expression вычисляется в TRUE. Аргумент result expression представляет собой любое допустимое выражение.

ELSE else_result_expression - Это выражение, возвращаемое, если ни одна из операций сравнения не дает в результате TRUE. Если этот аргумент опущен и ни одна из операций сравнения не дает в результате TRUE, функция CASE возвращает NULL. Аргумент else_result_expression представляет собой любое допустимое выражение. Типы данных аргумента else_result_expression и любого из аргументов result_expression должны быть одинаковыми или неявно приводимыми друг к другу.

WHEN Boolean_expression - Это логическое выражение, полученное при использовании поискового формата функции CASE. Аргумент Boolean_expression представляет собой любое допустимое логическое выражение.

Результирующие значения

Простое выражение CASE

Простое выражение сравнивает первое выражение с выражением в каждом предложении WHEN. Если эти выражения эквивалентны, то возвращается выражение в предложении THEN.

Допускается только проверка равенства.

Вычисляет выражение input_expression, затем в указанном порядке сравнивает значения выражений input_expression и when_expression для каждого предложения WHEN.

Возвращает выражение result_expression, соответствующее первому предложению WHEN, для которого операция сравнения input_expression = when_expression вычисляется в TRUE.

Если ни одна из операций input_expression = when_expression не вычисляется в TRUE, компонент SQL Server Database Engine возвращает выражение else_result_expression, если указано предложение ELSE, или значение NULL, если предложение ELSE не указано.

Поисковое выражение CASE

Вычисляет в указанном порядке выражения Boolean_expression для каждого предложения WHEN.

Возвращает выражение result_expression, соответствующее первому предложению WHEN, для которого выражение Boolean_expression вычисляется в TRUE.

Если ни одно выражение Boolean_expression не вычисляется в TRUE, компонент Database Engine возвращает выражение else_result_expression, если указано предложение ELSE, или значение NULL, если предложение ELSE не указано.

SQL Server допускает применение в выражениях CASE не более 10 уровней вложенности.

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

Пример с простым выражением CASE:

USE AdventureWorks;

GO

SELECT ProductNumber, Category =

CASE ProductLine -- input_expression

WHEN 'R' THEN 'Road'

WHEN 'M' THEN 'Mountain'

WHEN 'T' THEN 'Touring'

WHEN 'S' THEN 'Other sale items'

ELSE 'Not for sale'

END,

Name

FROM Production.Product

ORDER BY ProductNumber;

GO

Пример с поисковым выражением CASE:

USE AdventureWorks;

GO

SELECT ProductNumber, Name, 'Price Range' =

CASE

WHEN ListPrice = 0 THEN 'Mfg item - not for resale'

WHEN ListPrice < 50 THEN 'Under $50'

WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'

WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'

ELSE 'Over $1000'

END

FROM Production.Product

ORDER BY ProductNumber ;

GO

Процедурные операторы

Процедурное расширение языка Transact-SQL содержит следующие операторы:

  • return;

  • goto;

  • raiseerror;

  • WAITFOR.

Оператор return имеет ту же функциональность внутри пакета, что и оператор break внутри while. Это означает, что оператор return приводит к завер­шению выполнения пакета, после чего будет выполняться первый оператор, следующий сразу после пакета. /

Оператор goto передает управление на метку, которая стоит перед оператором Transact-SQL в этом же пакете.

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

Синтаксис:

Define the label: 

label :

Alter the execution:

GOTO label

Пример:

DECLARE @Counter int;

SET @Counter = 1;

WHILE @Counter < 10

BEGIN

SELECT @Counter

SET @Counter = @Counter + 1

IF @Counter = 4 GOTO Branch_One --Переход к первой метке

IF @Counter = 5 GOTO Branch_Two --Никогда не выполнится

END

Branch_One:

SELECT 'Jumping To Branch One.'

GOTO Branch_Three; -- Переход к третьей метке

Branch_Two:

SELECT 'Jumping To Branch Two.'

Branch_Three:

SELECT 'Jumping To Branch Three.'

Результат:

Оператор raiseerror генерирует сообщение об ошибке, созданное пользователем, и устанавливает флаг системной ошибки. Номер ошибки, определенной пользователем, должен быть больше чем 50 000. (Все номера ошибок, меньше или равные 50 000, определены в системе и резервируются для Database Erigine). Значение кода ошибки сохраняется в глобальной переменной @@error.

Оператор waitfor либо определяет временной интервал (не более 24 часов), который должен пройти до выполнения пакета, хранимой процедуры или продолжения транзакции (если используется опция delay), либо задает время (если указана опция time), в течение которого система должна перейти в состояние ожидания, прежде чем выполнить следующий оператор в пакете. Синтаксис этого оператора:

waitfor { DELAY 'time' | TIME 'time' | TIMEOUT 'timeout' }

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

Обработка событий операторами TRY и CATCH

Версии SQL Server, предшествующие SQL Server 2005, требовали написание кода обработки ошибок после каждого оператора Transact-SQL, который может вызывать ошибки. (Можно обрабатывать ошибки, используя глобальную переменную @@error).

Начиная с SQL Server 2005, можно перехватить и обработать исключения, используя два оператора - try и catch.

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

Роль оператора try заключается в перехватывании исключения. (Поскольку этот процесс, как правило, заключает в себе несколько операторов, то обычно используется термин "блок try" вместо термина "оператор try"). Если исключение появляется внутри блока try, тo часть системы, называемая обработчиком исключений, направляет это исключение другой части программы, которая обработает исключение. Эта часть программы объявляется ключевым словом catch и поэтому называется блоком сатсн.

Замечание: Обработка исключений с использованием операторов try и catch является общим методом, который используют современные языки программирования типа С# и Java для обработки ошибок.

Обработка исключений с использованием блоков try и catch дает программисту множество преимуществ:

  • исключения предоставляют ясный способ обнаружения ошибок;

  • исключения предоставляют механизм прямой сигнализации об ошибке, а не при помощи каких-то посторонних эффектов;

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

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

USE sample;

BEGIN TRY

BEGIN TRANSACTION

insert into employee values(11111, 'Ann', 'Smith', 'd2');

insert into employee values(22222, 'Matthew', 'Jones', 'd4');

-- нарушение ссылочной целостности при вставке

insert into employee values(33333, 'John', 'Barrimore', ' d2');

COMMIT TRANSACTION

PRINT 'Transaction committed'

END TRY

BEGIN CATCH

ROLLBACK

PRINT 'Transaction rolled back'

END CATCH;

Работа примера выполняется следующим образом. Первый оператор insert выполняется успешно. После этого выполнение второго оператора приводит к нарушению ссылочной целостности данных (d4 – нет такого департамента). Поскольку все три оператора записаны внутри блока try, выдается исключение, и обработчик исключений запускает блок catch. catch выполняет отмену всех операторов и выводит соответствующее сообщение. По этой причине содержимое таблицы employee не меняется.

После выполнения пакета в примере все три оператора в пакете не будут выполнены, а выводом этого примера будет:

‘Тransaction rolled back' (Выполнен откат транзакции)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]