Базовая процедура SQL Server

Для разработки базовой процедуры приведена таблица с базовыми типами данных SQL Server и соответствующими внутренними типами платформы:

Базовый скалярный тип SQL Server Псевдонимы для типа SQL Server Внутренний тип платформы
int integer bigint
bigint - bigint
decimal[(p[, s]] Dec[(p[, s]] double
numeric[(p[, s]] - double
float[(n)] - double
datetimeoffset - text
varchar[(n | max)] char varying
character varying (n)
text
text - text
nvarchar[(n | max)] national character varying (n)
national char varying (n)
text
ntext national text text
varbinary[(n | max)] binary varying (n) bytea

Подробное описание типов SQL Server можно найти в описании Data Types, Data Type Synonyms.

Базовый табличный тип

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

CREATE TYPE <наименование типаAS TABLE (
    <имя столбца> <тип столбца>
);

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

Базовая хранимая процедура

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

Для реализации базовых хранимых процедур неудобно использовать функции, так как из-за их ограничения не получится реализовать сценарии с изменением данных. Требуется реализовывать базовые хранимые процедуры на основе процедур. Если есть процедура «some_proc», то должен быть определен базовый табличный тип с именем «some_proc_return_type» для определения структуры выходной таблицы.

Связанный табличный тип для процедуры – это базовый табличный тип, имя которого отличается от имени связанной процедуры суффиксом «_return_type». Этот тип обозначает тип выходной таблицы процедуры.

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

Пример

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

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

Примеры выполнения процедур в зависимости от вида передачи входных параметров:

Для добавления новой записи в таблицу:

  1. Создадим процедуру с наименованием «fruits_add_table_struct»:

CREATE PROCEDURE [fruits_add_table_struct]
@upsert_rows fruits_struct READONLY
AS
    BEGIN
 
   SET NOCOUNT ON;
   SET IDENTITY_INSERT [fruits_struct] ON;
 
   INSERT INTO  [fruits_struct](id, name)
   SELECT id, name FROM @upsert_rows
   WHERE id NOT IN (
      SELECT id FROM [fruits_struct]
   ) AND id IS NOT NULL;
 
   SET IDENTITY_INSERT [fruits_struct] OFF;
 
   INSERT INTO [fruits_struct](name)
   SELECT name FROM @upsert_rows WHERE id IS NULL;
 
   DECLARE @id NVARCHAR(max);
   DECLARE [cursor] CURSOR LOCAL READ_ONLY
   FOR    (
      SELECT id FROM @upsert_rows
   );
 
   OPEN [cursor];
   FETCH NEXT FROM [cursor] INTO @id;
 
   WHILE @@FETCH_STATUS = 0
   BEGIN
      UPDATE [fruits_struct]
      SET NAME = (
         SELECT NAME    FROM @upsert_rows WHERE id = @id
      )
      WHERE id = @id;
      FETCH NEXT FROM [cursor] INTO @id;
   END;
 
   CLOSE [cursor];
   DEALLOCATE [cursor];
   end
 
    SELECT * FROM fruits_struct WHERE id = (SELECT id from @upsert_rows)
go
  1. Создадим базовый табличный тип «fruits_add_table_struct_return_type»:

create type fruits_add_table_struct_return_type as table
(
    id   int,
    name nvarchar(max)
)
go
  1. Выполним созданную процедуру с помощью API-метода rpc:

curl -v '<IP-адрес или DNS-имя сервера>/api/v1/rpc/<название ресурса>/' -H "Authorization: Bearer <токен пользователя>" -H "Content-Type: application/json" -d "{"<идентификатор записи>": <название фрукта>}"

Для добавления новой записи в таблицу:

  1. Создадим процедуру с наименованием «fruits_add_enum»:

CREATE PROCEDURE [fruits_add_enum]
@id INT,
@name NVARCHAR (max)
 
as begin
    Set nocount on;
    SET IDENTITY_INSERT [fruits_struct] ON;
    IF NOT EXISTS(select * from fruits_struct where id=@id)
    INSERT INTO fruits_struct (id,name) VALUES (@id,@name);
    ELSE IF EXISTS(select * from fruits_struct where id=@id)
    UPDATE [fruits_struct] SET name = @name
    WHERE id=@id;
 
   SELECT * from fruits_struct WHERE id=@id
 
end
go
  1. Создадим базовый табличный тип «fruits_add_enum_return_type»:

create type fruits_add_enum_return_type as table
(
    id   int,
    name nvarchar(max)
)
go
  1. Выполним созданную процедуру с помощью API-метода rpc:

curl -v '<IP-адрес или DNS-имя сервера>/api/v1/rpc/<название ресурса>/' -H "Authorization: Bearer <токен пользователя>" -H "Content-Type: application/json" -d '{"@id": <идентификатор записи>,"@name": "<название фрукта>"}'

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

См. также:

Настройка интеграции с табличными источниками данных | Базовая процедура SOAP/XML