Хранимая процедура обеспечивает сборку объекта,т.е позволяет отобразить не только
отдельные таблицы , но и результат выборки по оператору SELECT или вообще собирает данные нереляционным способом , отвечая при этом за
добавление удаление и изменение данных в исходных таблицах , которые участвуют в выборке.
   При этом процедура "менеджер" может проверять права доступа пользователя , вести журналы,
вплоть до того , что может отдавать разным пользователям разные данные.
    Кроме того она отвечает за перемещение по набору данных на сервере и
ответы на запросы пользовательского интерфейса.
Буквально она "умеет" следующее :
1.Выбрать пакет данных с начала набора.
2.Выбрать пакет данных с конца набора.
3.Выбрать пакет данных с определенного места.
4.Выбрать запись набора данных по критерию поиска.
5.Обеспечить сортировку данных.
6.Отфильтровать данные.
7.Удалить,добавить и изменить запись в наборе данных.
Все это она делает только пакетами,т.е допустим ищет запись и с этого места
в наборе данных формируется пакет записей,
например 10,который и передается интерфейсу.
Такая процедура генерируется по шаблону и может быть откорректирована средствами SQL.
В настоящее время это работает на MS SQL Server.Исследовалась возможность переноса на другие
СУБД,
в частности на PostGreeSQL принципиальных трудностей не видно.
Вот текст подобной процедуры :
CREATE PROCEDURE [Валюты_таб]
/*----Parameters------*/
(
@Action Integer = 0,
@Packet Integer = 0,
@G_Ид uniqueidentifier='{00000000-0000-0000-0000-000000000000}',
@G_Валюта nvarchar(20)='',
@G_ISO nvarchar(3)='',
@G_Курс float=0,
@G_Код_валюты nvarchar(5)='',
@G_ИдRet uniqueidentifier OUTPUT,
@G_ВалютаRet nvarchar(20) OUTPUT,
@G_ISORet nvarchar(3) OUTPUT,
@Addon nvarchar(500)='',
@Filter nvarchar(500)='',-- фильтр
@Range nvarchar(500)='' -- дополнительный фильтр
)
AS
/* Вспомогательные строки */
DECLARE @SqlString NVARCHAR(4000)
DECLARE @ParamDefinition NVARCHAR(1000)
DECLARE @SqlAdd NVARCHAR(1000)
DECLARE @SortMode int
/* Количество выбираемых строк*/
DECLARE @RowPacket NVARCHAR(200)
DECLARE @Row1 NVARCHAR(200)
/* Разделы оператора SELECT */
DECLARE @Select_clause NVARCHAR(2000)
DECLARE @Select_par_clause NVARCHAR(2000)
DECLARE @Where_clause NVARCHAR(2000)
DECLARE @Order_clause NVARCHAR(1000)
DECLARE @Order_desc_clause NVARCHAR(1000)
DECLARE @Order_clause1 NVARCHAR(1000)
DECLARE @Order_desc_clause1 NVARCHAR(1000)
DECLARE @Order_clause2 NVARCHAR(1000)
DECLARE @Order_desc_clause2 NVARCHAR(1000)
DECLARE @From_clause NVARCHAR(1000)
/* Виды условий */
DECLARE @Pref NVARCHAR(100)
DECLARE @CondGE NVARCHAR(3000)
DECLARE @CondG NVARCHAR(3000)
DECLARE @CondLE NVARCHAR(3000)
DECLARE @CondL NVARCHAR(3000)
DECLARE @CondGG NVARCHAR(3000)
DECLARE @CondGG1 NVARCHAR(3000)
DECLARE @CondGG2 NVARCHAR(3000)
DECLARE @CondE NVARCHAR(1000)
/* Инициализация */
SET @RowPacket =' SET ROWCOUNT @Packet '
SET @Row1 =' SET ROWCOUNT 1 '
SET @ParamDefinition='@G_Ид uniqueidentifier,@G_Валюта nvarchar(20),@G_ISO nvarchar(3),@Packet int '
SET @Select_clause=' SELECT G.ИД ,G.ВАЛЮТА,G.ISO,G.КУРС,G.КОД_ВАЛЮТЫ '
SET @Select_par_clause=' SELECT '+
'@G_Ид = G.Ид , '+
'@G_Валюта = G.Валюта , '+
'@G_ISO = G.ISO '
SET @Where_clause = ' WHERE 1=1 '
-- Возможные сортировки
SET @Order_clause = ' ORDER BY G.ИД ,G.ВАЛЮТА '
SET @Order_desc_clause =' ORDER BY G.ИД DESC , G.ВАЛЮТА DESC '
SET @Order_clause1 =' ORDER BY G.Валюта,G.Ид'
SET @Order_desc_clause1 =' ORDER BY G.Валюта DESC ,G.Ид DESC '
SET @Order_clause2 =' ORDER BY G.ISO,G.Ид'
SET @Order_desc_clause2 =' ORDER BY G.ISO DESC ,G.Ид DESC '
SET @From_clause = ' FROM ВАЛЮТЫ G '
SET @CondE=
' ('+
'@G_Ид = G.Ид AND '+
'@G_Валюта = G.Валюта'+
') '
SET @Pref=
' AND '+
' ( '
SET @CondGG =
' ('+
' ('+
' @G_Ид < G.Ид'+
') OR '+
' ('+
' @G_Ид = G.Ид'+
' AND '+
' @G_Валюта < G.Валюта'+
')'+
') '
SET @CondGG1 =
' ('+
' ('+
' @G_Валюта < G.Валюта'+
') OR '+
' ('+
' @G_Валюта = G.Валюта'+
' AND '+
' @G_Ид < G.Ид'+
')'+
') '
SET @CondGG2 =
' ('+
' ('+
' @G_ISO < G.ISO'+
') OR '+
' ('+
' @G_ISO = G.ISO'+
' AND '+
' @G_Ид < G.Ид'+
')'+
') '
SET @SortMode = FLOOR(@Action/100)
SET @Action = @Action-FLOOR(@Action/100)*100
IF (@SortMode=1) BEGIN
SET @CondE=
' ('+
'@G_Валюта = G.Валюта AND '+
'@G_Ид = G.Ид'+
') '
SET @Order_Clause = @Order_Clause1
SET @Order_Desc_Clause = @Order_Desc_Clause1
SET @CondGG = @CondGG1
END
IF (@SortMode=2) BEGIN
SET @CondE=
' ('+
'@G_ISO = G.ISO AND '+
'@G_Ид = G.Ид'+
') '
SET @Order_Clause = @Order_Clause2
SET @Order_Desc_Clause = @Order_Desc_Clause2
SET @CondGG = @CondGG2
END
SET @CondG = @Pref+@CondGG +' ) '
SET @CondGE = @Pref+@CondE+' OR '+ @CondGG +' ) '
SET @CondL = @Pref+REPLACE(@CondGG,'<','>')+' ) '
SET @CondLE = @Pref+@CondE+REPLACE(@CondGG,'<','>')+' ) '
/* Начало таблицы */
if @Action=0 begin
SET @SqlString=@RowPacket+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
end
/* Конец таблицы */
if @Action=1 begin
SET @SqlString = @RowPacket+@Select_Par_clause+@From_clause+@Where_clause+@Filter+@Range+@Order_desc_clause+
@RowPacket+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@CondGE+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
end
/* Следующие записи */
if @Action=2 begin
SET @SqlString = @Row1+@Select_Par_clause+@From_clause+@Where_clause+@Filter+@Range+@CondG+@Order_clause+
@RowPacket+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@CondGE+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
end
/* Предыдущие записи */
if @Action=3 begin
SET @SqlString=@RowPacket+@Select_par_clause+@From_clause+@Where_clause+@Filter+@Range+@CondL+@Order_desc_clause+
@RowPacket+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@CondGE+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
SET @SqlString=@RowPacket+@Select_par_clause+@From_clause+@Where_clause+@Filter+@Range+@CondL+@Order_desc_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
RETURN @@ROWCOUNT
end
/* Записи с текущей позиции*/
if @Action=4 begin
SET @SqlString=@RowPacket+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@CondGE+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
end
/* Изменение записи */
-- Здесь можно начинать и откатывать транзакции
if @Action=5 begin
UPDATE ВАЛЮТЫ SET
Ид=@G_Ид,
Валюта=@G_Валюта,
ISO=@G_ISO,
Курс=@G_Курс,
Код_валюты=@G_Код_валюты
WHERE
Ид=@G_Ид
SET @G_ИдRet=@G_Ид
SET @G_ВалютаRet=@G_Валюта
SET @G_ISORet=@G_ISO
end
/* Добавление записи */
-- Здесь можно начинать и откатывать транзакции
if @Action=6 begin
SET @G_Ид=NEWID()
INSERT INTO ВАЛЮТЫ ( Ид,Валюта,ISO,Курс,Код_валюты )
VALUES ( @G_Ид,@G_Валюта,@G_ISO,@G_Курс,@G_Код_валюты )
SET @G_ИдRet=@G_Ид
SET @G_ВалютаRet=@G_Валюта
SET @G_ISORet=@G_ISO
end
/* Удаление записи */
if @Action=7 begin
-- Здесь можно начинать и откатывать транзакции
DELETE FROM Валюты WHERE Ид=@G_Ид
SET @SqlString=@Row1+@Select_par_clause+@From_clause+@Where_clause+@Filter+@Range+@CondG+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
IF @@ROWCOUNT=1 RETURN 0
ELSE RETURN 1
end
/* Поиск первой записи */
if @Action=8 begin
SET @SqlString=@Row1+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@Addon+@Order_Clause
exec sp_executesql @SqlString
IF @@ROWCOUNT=0 RETURN 1
ELSE RETURN 0
end
/* Поиск следующей записи */
if @Action=9 begin
SET @SqlString=@Row1+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@Addon+@CondG+@Order_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
IF @@ROWCOUNT=0 RETURN 1
ELSE RETURN 0
end
/* Поиск предыдущей записи */
if @Action=10 begin
SET @SqlString=@Row1+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@Addon+@CondL+@Order_desc_clause
exec sp_executesql @SqlString,@Paramdefinition,@G_Ид ,@G_Валюта ,@G_ISO ,@Packet
IF @@ROWCOUNT=0 RETURN 1
ELSE RETURN 0
end
/* Поиск последней записи */
if @Action=11 begin
SET @SqlString=@Row1+@Select_clause+@From_clause+@Where_clause+@Filter+@Range+@Addon+@Order_desc_clause
exec sp_executesql @SqlString
IF @@ROWCOUNT=0 RETURN 1
ELSE RETURN 0
end
/* Дополнительная функция */
if @Action=12 begin
exec sp_executesql @Addon
RETURN @@ROWCOUNT
end