<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://iu5bmstu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=109.252.52.180</id>
	<title>Кафедра ИУ5 МГТУ им. Н.Э.Баумана, студенческое сообщество - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://iu5bmstu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=109.252.52.180"/>
	<link rel="alternate" type="text/html" href="https://iu5bmstu.ru/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/109.252.52.180"/>
	<updated>2026-04-30T05:35:29Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://iu5bmstu.ru/index.php?title=%D0%9F%D0%91%D0%94_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%967_-_SQL_(%D0%BF%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5)&amp;diff=2203</id>
		<title>ПБД (9) - Лекция №7 - SQL (продолжение)</title>
		<link rel="alternate" type="text/html" href="https://iu5bmstu.ru/index.php?title=%D0%9F%D0%91%D0%94_(9)_-_%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_%E2%84%967_-_SQL_(%D0%BF%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5)&amp;diff=2203"/>
		<updated>2012-11-21T06:17:04Z</updated>

		<summary type="html">&lt;p&gt;109.252.52.180: /* Рекурсия */ поправка&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SQL ==&lt;br /&gt;
&lt;br /&gt;
=== Хранимые процедуры ===&lt;br /&gt;
&lt;br /&gt;
Описание процедуры:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create procedure Proc1 (&amp;lt;in, out, inout&amp;gt;, имя тип)&lt;br /&gt;
declare имя тип -- объявление процедуры&lt;br /&gt;
begin&lt;br /&gt;
    -- объявление переменных&lt;br /&gt;
    set a = 10;&lt;br /&gt;
    set b = NULL;&lt;br /&gt;
    set c = (select count(*) from таблица);&lt;br /&gt;
    &lt;br /&gt;
    -- условия&lt;br /&gt;
    if a &amp;gt; 10 then a = 4 elseif a &amp;lt; 10 then a = 16 else a = 9000 endif;&lt;br /&gt;
    &lt;br /&gt;
    -- цикл&lt;br /&gt;
    while условие do&lt;br /&gt;
        -- тело цикла&lt;br /&gt;
    end while;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вызов процедуры:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
call someProc(10, &#039;abc&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Функции ====&lt;br /&gt;
&lt;br /&gt;
Функции похожи на хранимые процедуры, но отличаются:&lt;br /&gt;
* обязана возвращать значение;&lt;br /&gt;
* все параметры только входящие.&lt;br /&gt;
&lt;br /&gt;
Важно, что &amp;lt;code&amp;gt;return&amp;lt;/code&amp;gt; не возвращает управление.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create function func(a int, b char(2)) returns int&lt;br /&gt;
declare ...&lt;br /&gt;
begin&lt;br /&gt;
    -- тело функции&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Функции вызываются из запросов. Функции могут быть:&lt;br /&gt;
&lt;br /&gt;
* скалярные - возвращают одно значение (обращение к полю):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
select a, func1(a) from T&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* табличные - возвращают набор записей (обращение к таблице);&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
select a, b from func2(&#039;...&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Cursor ====&lt;br /&gt;
&lt;br /&gt;
Это итератор по строкам результата запроса (как QSqlRecord в QSqlQueryModel):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
declare C cursor for&lt;br /&gt;
    select name, year from someTable&lt;br /&gt;
    where city = &#039;Москва&#039;&lt;br /&gt;
begin&lt;br /&gt;
    open C; -- выполнение запроса&lt;br /&gt;
    l: loop&lt;br /&gt;
        fetch from C into ... -- проход по строкам&lt;br /&gt;
        if состояние then leave l endif;&lt;br /&gt;
    end loop;&lt;br /&gt;
    close C;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Перехват исключений в где-то ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
declare &amp;lt;undo, exit, continue&amp;gt; handler&lt;br /&gt;
    for состояние1, состояние2, состояние3&lt;br /&gt;
    -- действие&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Перехват исключений в Microsoft SQL Server ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- ловля исключений&lt;br /&gt;
begin try&lt;br /&gt;
    -- какие-нибудь действия&lt;br /&gt;
end try;&lt;br /&gt;
&lt;br /&gt;
-- блок обработчиков&lt;br /&gt;
begin catch&lt;br /&gt;
    select error_number(), error_message() ...&lt;br /&gt;
end catch;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вызов исключений:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
raiserror(код сообщения, серьёзность, состояние)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Расширения SQL(99) ===&lt;br /&gt;
&lt;br /&gt;
==== Рекурсия ====&lt;br /&gt;
&lt;br /&gt;
Рекурсия выполняет первую итерацию, добавляет её результаты  во вторую, выполняет вторую... и так далее, пока будут просходить изменения.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight highlight=&amp;quot;12&amp;quot; lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- просто таблица&lt;br /&gt;
Road(fr, to, len);&lt;br /&gt;
&lt;br /&gt;
-- рекурсия&lt;br /&gt;
with Recursive R(f, t, l)&lt;br /&gt;
    as(&lt;br /&gt;
        -- база рекурсии&lt;br /&gt;
        select fr, to, len from Road&lt;br /&gt;
        union&lt;br /&gt;
        -- индукция рекурсии&lt;br /&gt;
        select r1.fr, r2.t, r1.len + r2.l&lt;br /&gt;
        from Road r1, R, r2 -- итерационный вызов R&lt;br /&gt;
        where r1.to = r2.f&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
-- теперь можно запросить эту рекурсию&lt;br /&gt;
select * from R;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы рекурсия не выполнялась вечно, должна быть соблюдена &#039;&#039;монотонность&#039;&#039; - на каждом шаге итерации вычисляемое значение должно только пополняться, из него не должны исчезать ранее определённые кортежи. Чтобы это выполнялось, запрещается в вычисляемой части использовать &amp;lt;code&amp;gt;DISTINCT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GROUP BY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;EXCEPT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INTERSECT&amp;lt;/code&amp;gt; и другие функции агрегирования.&lt;br /&gt;
&lt;br /&gt;
==== Преобразование ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;PIVOT&amp;lt;/code&amp;gt; - преобразование столбца в строку&lt;br /&gt;
&lt;br /&gt;
Исходная таблица:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |+ Tab&lt;br /&gt;
 ! year !! mounth !! cnt&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 2007 || Jan || 10&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 2008 || Feb || 20&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Получится:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
select year, Jan, Feb ...&lt;br /&gt;
from (select year, mounth, cnt from Tab) t -- t - это псевдоним подзапроса&lt;br /&gt;
PIVOT(sum(cnt) for mounth in (Jan, Feb ...)) p -- p - это псевдоним PIVOT&#039;а&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 ! year !! Jan !! Feb !! ...&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 2007 || 100 || 250 || ...&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 2008 || ... || ... || ...&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Ранжирование ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
    row_number() over (order by name) as N1,&lt;br /&gt;
    rank()       over (order by name) as N2,&lt;br /&gt;
    dense_rank() over (order by name) as N3,&lt;br /&gt;
    ntile(3)     over (order by name) as N4,&lt;br /&gt;
        name&lt;br /&gt;
    from Tab;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
 |+ Tab&lt;br /&gt;
 ! N1 !! N2 !! N3 !! N4 !! name&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 1&amp;lt;br&amp;gt;2 || 1&amp;lt;br&amp;gt;2 || 1&amp;lt;br&amp;gt;2 || 1&amp;lt;br&amp;gt;1 || A&amp;lt;br&amp;gt;B&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 3&amp;lt;br&amp;gt;4 || 3&amp;lt;br&amp;gt;3 || 3&amp;lt;br&amp;gt;3 || 1&amp;lt;br&amp;gt;2 || C&amp;lt;br&amp;gt;C&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 5&amp;lt;br&amp;gt;6 || 5&amp;lt;br&amp;gt;5 || 4&amp;lt;br&amp;gt;4 || 2&amp;lt;br&amp;gt;3 || D&amp;lt;br&amp;gt;D&lt;br /&gt;
 |- align=&amp;quot;center&amp;quot;&lt;br /&gt;
 | 7 || 7 || 5 || 3 || E&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== DDL-триггеры ====&lt;br /&gt;
&lt;br /&gt;
Триггеры на изменение схемы данных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create trigger имя on &amp;lt;database, all server&amp;gt;&lt;br /&gt;
for событие CREATE_TABLE&lt;br /&gt;
after ...&lt;br /&gt;
as&lt;br /&gt;
    -- тело события&lt;br /&gt;
    ...&lt;br /&gt;
    eventdata(); -- возвращает XML&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Сложные типы данных ====&lt;br /&gt;
&lt;br /&gt;
Объявление:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create teble tab(&lt;br /&gt;
    ia int,&lt;br /&gt;
    ab int array[3],           -- массив&lt;br /&gt;
    mc int multiset,           -- мультимножество&lt;br /&gt;
    r row(r1 int, r2 char(3)); -- структура&lt;br /&gt;
    );    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Добавление значений:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
insert into tab&lt;br /&gt;
values(&lt;br /&gt;
    10,&lt;br /&gt;
    array[1, 2, 3],&lt;br /&gt;
    multiset(1, 1, 5, 7, 7)&lt;br /&gt;
    (15, &#039;abc&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Получение значений:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
select &lt;br /&gt;
    ia,&lt;br /&gt;
    ab[1], ab[2],&lt;br /&gt;
    r.r1, r.r2&lt;br /&gt;
from tab;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для работы со структурами есть множество встроенных функций.&lt;br /&gt;
&lt;br /&gt;
===== Создание нового типа данных =====&lt;br /&gt;
&lt;br /&gt;
Они же пользовательские типы данных (UDT).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
create type Addr as&lt;br /&gt;
    (&lt;br /&gt;
     city char(10),&lt;br /&gt;
     str char(20) defailt &#039;&#039;&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
 -- объявление метода&lt;br /&gt;
 method fulladdr() returns char(30);&lt;br /&gt;
 &lt;br /&gt;
 -- определение метода&lt;br /&gt;
 create method fulladdr() returns char(30)&lt;br /&gt;
 for Addr&lt;br /&gt;
 begin&lt;br /&gt;
    -- туловко метода&lt;br /&gt;
 end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория:Постреляционные базы данных (9 семестр)]]&lt;br /&gt;
[[Категория:Конспекты лекций и семинаров]]&lt;/div&gt;</summary>
		<author><name>109.252.52.180</name></author>
	</entry>
</feed>