Spec-Zone.ru › MariaDB

ROW

MariaDB, начиная с 10.3.0

Тип данных ROW был представлен в MariaDB 10.3.0.

Синтаксис

ROW (<field name> <data type> [{, <field name> <data type>}... ])

Описание

ROW — это тип данных для переменных хранимых процедур.

Возможности

Поля ROW как обычные переменные

Поля (члены) типа ROW действуют как обычные переменные и могут использоваться во всех частях запроса, где разрешено использование переменных хранимой процедуры:

  • Присваивание с использованием оператора := и команды SET:
a.x:= 10;
a.x:= b.x;
SET a.x= 10, a.y=20, a.z= b.z;
  • Передача в функции и операторы:
SELECT f1(rec.a), rec.a<10;
  • Операторы (список выбора, WHERE, HAVING, LIMIT и т. д.):
SELECT var.a, t1.b FROM t1 WHERE t1.b=var.b LIMIT var.c;
  • INSERT значения:
INSERT INTO t1 VALUES (rec.a, rec.b, rec.c);
  • SELECT .. INTO цели
SELECT a,b INTO rec.a, rec.b FROM t1 WHERE t1.id=10;
  • Динамические параметры SQL (EXECUTE и EXECUTE IMMEDIATE)
EXECUTE IMMEDIATE 'CALL proc_with_out_param(?)' USING rec.a;

Переменные типа ROW в качестве целей FETCH

Переменные типа ROW допускаются в качестве целей FETCH:

FETCH cur INTO rec;

где cur — CURSOR, а rec — переменная хранимой процедуры типа ROW.

Обратите внимание, что в настоящее время попытка использовать FETCH для переменной типа ROW возвращает следующую ошибку:

ERROR 1328 (HY000): Incorrect number of FETCH variables

FETCH данных из курсора cur в переменную типа ROW rec выполняется следующим образом:

  • Количество полей в cur должно совпадать с количеством полей в rec. В противном случае будет сообщено об ошибке.
  • Присваивание выполняется слева направо. Первое поле курсора присваивается первому полю переменной, второе поле курсора — второму полю переменной и т. д.
  • Имена полей в rec не имеют значения и могут отличаться от имен полей в cur.

См. примеры FETCH (ниже) для примеров использования с sql_mode=ORACLE и sql_mode=DEFAULT.

Переменные типа ROW в качестве целей SELECT...INTO

Переменные типа ROW допускаются в качестве целей SELECT..INTO с некоторыми отличиями в зависимости от используемого sql_mode.

  • При использовании sql_mode=ORACLE, переменные table%ROWTYPE и cursor%ROWTYPE могут использоваться в качестве целей SELECT...INTO.
  • Использование нескольких переменных ROW в списке SELECT..INTO приведет к ошибке.
  • Использование переменных ROW с количеством столбцов, отличным от количества в списке SELECT..INTO, приведет к ошибке.

См. примеры SELECT...INTO (ниже) для примеров использования с sql_mode=ORACLE и sql_mode=DEFAULT.

Не реализованные возможности

Следующие возможности запланированы, но пока не реализованы:

  • Возврат выражения типа ROW из хранимой функции (см. MDEV-12252). Для этого потребуется изменение грамматики, чтобы поддерживать имена полей после скобок:
SELECT f1().x FROM DUAL;
  • Возврат выражения типа ROW из встроенной функции гибридного типа, такой как CASE, IF, и т. д.
  • ROW из ROWs

Примеры

Объявление ROW в хранимой процедуре

DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE r ROW (c1 INT, c2 VARCHAR(10));
  SET r.c1= 10;
  SET r.c2= 'test';
  INSERT INTO t1 VALUES (r.c1, r.c2);
END;
$$
DELIMITER ;
CALL p1();

Примеры FETCH

Полный пример FETCH для sql_mode=ORACLE:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=oracle;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec ROW(a INT, b VARCHAR(32));
  CURSOR c IS SELECT a,b FROM t1;
BEGIN
  OPEN c;
  LOOP
    FETCH c INTO rec;
    EXIT WHEN c%NOTFOUND;
    SELECT ('rec=(' || rec.a ||','|| rec.b||')');
  END LOOP;
  CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

Полный пример FETCH для sql_mode=DEFAULT:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=DEFAULT;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE rec ROW(a INT, b VARCHAR(32));
  DECLARE c CURSOR FOR SELECT a,b FROM t1;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  OPEN c;
read_loop:
  LOOP
    FETCH c INTO rec;
    IF done THEN
      LEAVE read_loop;
    END IF;
    SELECT CONCAT('rec=(',rec.a,',',rec.b,')');
  END LOOP;
  CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

Примеры SELECT...INTO

Пример SELECT...INTO для sql_mode=DEFAULT:

SET sql_mode=DEFAULT;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE rec1 ROW(a INT, b VARCHAR(32));
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

Результат приведённого выше примера:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

Пример SELECT...INTO для sql_mode=ORACLE:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec1 ROW(a INT, b VARCHAR(32));
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

Результат приведённого выше примера:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

Пример для sql_mode=ORACLE, использующий переменные table%ROWTYPE в качестве целей SELECT..INTO:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec1 t1%ROWTYPE;
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

Результат приведённого выше примера:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

Пример для sql_mode=ORACLE, использующий переменные cursor%ROWTYPE в качестве целей SELECT..INTO:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  CURSOR cur1 IS SELECT * FROM t1;
  rec1 cur1%ROWTYPE;
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

Результат приведённого выше примера:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

См. также

  • ХРАНИМЫЕ ПРОЦЕДУРЫ
  • Объявление переменной
Содержимое, воспроизведённое на этом сайте, является собственностью соответствующих владельцев, и это содержание не проверяется компанией MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точку зрения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/row/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API