Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Новые возможности языка SQL в Firebird 3.0

5,431 views

Published on

Описание новых возможностей SQL в СУБД Firebird 3.0 с примерами.

Published in: Software
  • Be the first to comment

Новые возможности языка SQL в Firebird 3.0

  1. 1. www.ibase.ru НОВЫЕ ВОЗМОЖНОСТИ ЯЗЫКА SQL В FIREBIRD 3.0 Alexey Kovyazin Dmitry Kuzmenko Denis Simonov www.ibase.ru www.ib-aid.com
  2. 2. www.ibase.ru Что нового в Firebird 3.0 •Common SQL • Оконные (аналитические) функции • Статистические функции • Функции линейной регрессии • Полный синтаксис оператора MERGE согласно SQL- 2008 • MERGE … RETURNING • Алиасы в RETURNING • OFFSET … FETCH
  3. 3. www.ibase.ru Что нового в Firebird 3.0 •Common SQL (продолжение) • SUBSTRING с регулярными выражениями • Альтернативы для экранирования кавычек • Тип BOOLEAN • Псевдо столбец RDB$RECORD_VERSION • Стабильность курсора в запросах на модификацию данных • Запрет смешения явных и неявных JOIN • Внутреннее соединения с ХП
  4. 4. www.ibase.ru Что нового в Firebird 3.0 •Procedural SQL • SQL функции • Подпрограммы • Внешние процедуры, функции и триггеры • Пакеты • Исключения с параметрами: EXCEPTION … USING(…) • SQLSTATE в обработчике WHEN • CONTNINUE в циклах • Ссылки на курсоры как переменные типа запись • Двунаправленные курсоры
  5. 5. www.ibase.ru Что нового в Firebird 3.0 •DDL • Управление допустимостью NULL значений • ALTER DOMAIN … {SET | DROP} NOT NULL • ALTER COLUMN … {SET | DROP} NOT NULL • IDENTITY столбцы • SEQUENCE и GENERATOR • теперь синонимы • RECREATE …, CREATE OR ALTER … • INCREMENT [BY] • CREATE DATABASE … ROLE …
  6. 6. www.ibase.ru Что нового в Firebird 3.0 •DDL (продолжение) • ALTER DATABASE … • SET DEFAULT CHARATER SET • {SET | DROP} LINGER • {ENCRYPT WITH … | DECRYPT} • DROP SHADOW … [{PRESERVE | DELETE} FILE] • DDL триггеры
  7. 7. www.ibase.ru Что нового в Firebird 3.0 •Security • Управление пользователями • ACTIVE | INACTIVE • USING PLUGIN … • TAGS (…) • CREATE OR ALTER • ALTER CURRENT USER • SEC$USERS, SEC$USER_ATTRIBUTES … • Привилегия USAGE • Привилегия EXECUTE
  8. 8. www.ibase.ru Что нового в Firebird 3.0 •Security (продолжение) • DDL привилегии • Уровня базы данных • SET ROLE …, SET TRUSTED ROLE • Отображение объектов безопасности ({CREATE | ALTER | DROP} [GLOBAL] MAPPING …) • Шифрование базы данных
  9. 9. www.ibase.ru НОВОЕ В DML
  10. 10. www.ibase.ru DML: Оконные функции Синтаксис <window_function> ::= <window_function_name> OVER (<window_specification>) <window_function_name> ::= <aggregate_function> | <ranking_function> | <navigational_function> <window_specification> ::= [PARTITION BY <expr> [, <expr> ...]] [ORDER BY <order_expr> [, <order_expr> …]] <order_expr> ::= <expr> [ASC | DESC] [NULLS {FIRST | LAST}]
  11. 11. www.ibase.ru DML: Оконные функции Синтаксис (продолжение) <aggregate_function> ::= {AVG | MAX | MIN | SUM} (<expr>) | COUNT( * | <expr>) | LIST(<expr> [, <expr>]) | <statistical_function> | <regression_function> <ranking_function> ::= {ROW_NUMBER | RANK | DENSE_RANK} ()
  12. 12. www.ibase.ru DML: Оконные функции Синтаксис (продолжение) <navigational_function> ::= {LEAD | LAG} (<expr> [, <offset> [, <default>]]) | {FIRST_VALUE | LAST_VALUE} (<expr>) | NTH_VALUE(<expr>, <offset>) [FROM_FIRST | FROM_LAST] Замечание: Функции FIRST_VALUE, LAST_VALUE и NTH_VALUE оперируют на кадрах окна. В настоящее время в Firebird кадры всегда определены с первой до текущей строки, но не последней, т.е. ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW В настоящее время предложение фрейма не реализовано см. CORE-3647.
  13. 13. www.ibase.ru DML: Оконные функции Чего не хватает (CORE-3647) <window frame clause> ::= {ROWS | RANGE} <window frame extent> <window frame extent> ::= <window frame start> | <window frame between> <window frame start> ::= UNBOUNDED PRECEDING | <value> PRECEDING | CURRENT ROW <window frame between> ::= BETWEEN <window frame bound> AND <window frame bound> <window frame bound> ::= <window frame start> | UNBOUNDED FOLLOWING | <value> FOLLOWING
  14. 14. www.ibase.ru DML: Оконные функции Агрегатные функции: Без оконных функций SELECT id, name, department, salary, salary / (SELECT SUM(salary) FROM employee) percentage FROM employee ORDER BY name; Select Expression -> Singularity Check -> Aggregate -> Table "EMPLOYEE" Full Scan Select Expression -> Sort (record length: 140, key length: 36) -> Table "EMPLOYEE" Full Scan
  15. 15. www.ibase.ru DML: Оконные функции Агрегатные функции: С оконными функциями SELECT id, name, department, salary, salary / SUM(salary) OVER () percentage FROM employee ORDER BY name; Select Expression -> Sort (record length: 84, key length: 8) -> Window -> Record Buffer (record length: 65) -> Table "EMPLOYEE" Full Scan
  16. 16. www.ibase.ru DML: Оконные функции Агрегатные функции (секционирование): SELECT id, department, salary, salary / SUM(salary) OVER (PARTITION BY department) percentage FROM employee ORDER BY id; id department salary percentage -- ---------- ------ ---------- 1 R & D 10.00 0.3448 2 SALES 12.00 0.6000 3 SALES 8.00 0.4000 4 R & D 9.00 0.3103 5 R & D 10.00 0.3448
  17. 17. www.ibase.ru DML: Оконные функции Агрегатные функции (сортировка): SELECT payments.id AS id, payments.bydate AS bydate, credit.amount AS credit_amount, payments.amount AS pay, SUM(payments.amount) OVER(ORDER BY payments.bydate) AS s_amount, SUM(payments.amount) OVER(ORDER BY payments.bydate, payments.id) AS s_amount2, credit.amount - SUM(payments.amount) OVER(ORDER BY payments.bydate, payments.id) AS balance FROM credit JOIN payments ON payments.credit_id = credit.id WHERE credit.id = 1 ORDER BY payments.bydate
  18. 18. www.ibase.ru DML: Оконные функции Результат: ID BYDATE CREDIT_AMOUNT PAY S_AMOUNT S_AMOUNT2 BALANCE ----------------------------------------------------------------------- 1 15.01.2015 1000000 100000 100000 100000 900000 2 15.02.2015 1000000 150000 250000 250000 750000 3 15.03.2015 1000000 130000 400000 380000 620000 4 15.03.2015 1000000 20000 400000 400000 600000 5 15.04.2015 1000000 200000 600000 600000 400000 6 15.05.2015 1000000 150000 750000 750000 250000 7 15.06.2015 1000000 150000 1000000 900000 100000 8 15.06.2015 1000000 100000 1000000 1000000 0
  19. 19. www.ibase.ru DML: Оконные функции Ранжирующие функции: SELECT id, salary, DENSE_RANK() OVER(ORDER BY salary), RANK() OVER(ORDER BY salary), ROW_NUMBER() OVER(ORDER BY salary), SUM(1) OVER(ORDER BY salary) FROM employee ORDER BY salary; id salary dense_rank rank row_number sum -- ------ ---------- ---- ---------- --- 3 8.00 1 1 1 1 4 9.00 2 2 2 2 1 10.00 3 3 3 4 5 10.00 3 3 4 4 2 12.00 4 5 5 5
  20. 20. www.ibase.ru DML: Оконные функции Навигационные функции: SELECT id, salary, FIRST_VALUE(salary) OVER(ORDER BY salary), LAST_VALUE(salary) OVER(ORDER BY salary), NTH_VALUE(salary, 2) OVER(ORDER BY salary), LAG(salary) OVER(ORDER BY salary), LEAD(salary) OVER(ORDER BY salary) FROM employee ORDER BY salary; Используется окно ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW id salary first_value last_value nth_value lag lead -- ------ ----------- ---------- --------- ------ ------ 3 8.00 8.00 8.00 <null> <null> 9.00 4 9.00 8.00 9.00 9.00 8.00 10.00 1 10.00 8.00 10.00 9.00 9.00 10.00 5 10.00 8.00 10.00 9.00 10.00 12.00 2 12.00 8.00 12.00 9.00 10.00 <null>
  21. 21. www.ibase.ru DML: Оконные функции Навигационные функции (c CORE-3647): SELECT id, salary, FIRST_VALUE(salary) OVER(ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), LAST_VALUE(salary) OVER(ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), NTH_VALUE(salary, 2) OVER(ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), LAG(salary) OVER(ORDER BY salary), LEAD(salary) OVER(ORDER BY salary) FROM employee ORDER BY salary; id salary first_value last_value nth_value lag lead -- ------ ----------- ---------- --------- ------ ------ 3 8.00 8.00 12.00 9.00 <null> 9.00 4 9.00 8.00 12.00 9.00 8.00 10.00 1 10.00 8.00 12.00 9.00 9.00 10.00 5 10.00 8.00 12.00 9.00 10.00 12.00 2 12.00 8.00 12.00 9.00 10.00 <null>
  22. 22. www.ibase.ru DML: Оконные функции Навигационные функции (применение LAG): SELECT bydate, cost, cost - LAG(cost) OVER(ORDER BY bydate) AS change, 100 * (cost - LAG(cost) OVER(ORDER BY bydate)) / LAG(cost) OVER(ORDER BY bydate) AS percent_change FROM rate WHERE bydate BETWEEN DATEADD(-4 DAY TO current_date) AND current_date ORDER BY bydate bydate cost change percent_change ---------- ------ ------- -------------- 27.10.2014 31.00 <null> <null> 28.10.2014 31.53 0.53 1.7096 29.10.2014 31.40 -0.13 -0.4123 30.10.2014 31.67 0.27 0.8598 31.10.2014 32.00 0.33 1.0419
  23. 23. www.ibase.ru DML: Статистические функции Синтаксис • CORR(<expr1>, <expr2>) -- коэффициент корреляции • COVAR_POP(<expr1>, <expr2>) -- ковариация совокупности • COVAR_SAMP(<expr1>, <expr2>) -- выборочная ковариация • STDDEV_POP(<expr>) -- среднеквадратичное отклонение • STDDEV_SAMP(<expr>) -- стандартное отклонение • VAR_POP(<expr>) -- выборочная дисперсия • VAR_SAMP(<expr>) -- несмещённая дисперсия Особенности: • являются агрегатными • не учитывают NULL • не применимы ALL и DISTINCT
  24. 24. www.ibase.ru DML: Статистические функции Примеры SELECT CORR(alength, aheight) AS c_corr FROM measure; SELECT dept_no, VAR_POP(salary) FROM employee GROUP BY dept_no;
  25. 25. www.ibase.ru DML: Функции регрессии Синтаксис • REGR_AVGX(y, x) -- среднее независимой переменной • REGR_AVGY(y, x) -- среднее зависимой переменной • REGR_COUNT(y, x) -- количество непустых пар • REGR_INTERCEPT(y, x) -- точка пересечения линии регрессии с осью Y • REGR_R2(y, x) -- коэффициент детерминации • REGR_SLOPE(y, x) -- угол наклона линии регрессии • REGR_SXX(y, x) -- диагностическая • REGR_SXY(y, x) -- диагностическая • REGR_SYY(y, x) -- диагностическая
  26. 26. www.ibase.ru DML: Функции регрессии Пример WITH RECURSIVE years(byyear) AS ( SELECT 1991 FROM rdb$database UNION ALL SELECT byyear+1 FROM years WHERE byyear < 2020 ), s AS ( SELECT EXTRACT(YEAR FROM order_date) AS byyear, SUM(total_value) AS total_value FROM sales GROUP BY 1 ), regr AS ( SELECT REGR_INTERCEPT(total_value, byyear) as intercept, REGR_SLOPE(total_value, byyear) as slope FROM s) SELECT years.byyear AS byyear, intercept + (slope * years.byyear) AS total_value FROM years CROSS JOIN regr
  27. 27. www.ibase.ru DML: Функции регрессии Результат BYYEAR TOTAL_VALUE ------------------------------------ 1991 118377,35 1992 414557,62 1993 710737,89 1994 1006918,16 1995 1303098,43 1996 1599278,69 1997 1895458,96 1998 2191639,23 1999 2487819,50 2000 2783999,77 ...
  28. 28. www.ibase.ru DML: MERGE согласно SQL:2008 Синтаксис MERGE INTO target [[AS] target_alias] USING <source> [[AS] source_alias] ON <join condition> <merge when> [<merge when> ...] [RETURNING <returning_list> [INTO <variable_list>]] <merge when> ::= <merge when matched> | <merge when not matched> <merge when matched> ::= WHEN MATCHED [ AND <condition> ] THEN { UPDATE SET fieldname = <value> [fieldname = <value>] | DELETE } <merge when not matched> ::= WHEN NOT MATCHED [ AND <condition> ] THEN INSERT [ (<column_list>) ] VALUES (<value_list>)
  29. 29. www.ibase.ru DML: MERGE согласно SQL:2008 Множество WHEN [NOT] MATCHED и DELETE MERGE INTO PRODUCT_IVENTORY AS TARGET USING (SELECT SL.ID_PRODUCT, SUM(SL.QUANTITY) FROM SALES_ORDER_LINE SL JOIN SALES_ORDER S ON S.ID = SL.ID_SALES_ORDER WHERE S.BYDATE = CURRENT_DATE GROUP BY 1 ) AS SRC(ID_PRODUCT, QUANTITY) ON TARGET.ID_PRODUCT = SRC.ID_PRODUCT WHEN MATCHED AND TARGET.QUANTITY - SRC.QUANTITY <= 0 THEN DELETE WHEN MATCHED THEN UPDATE SET TARGET.QUANTITY = TARGET.QUANTITY - SRC.QUANTITY, TARGET.BYDATE = CURRENT_DATE
  30. 30. www.ibase.ru DML: MERGE согласно SQL:2008 RETURNING MERGE INTO PRODUCT_IVENTORY AS TARGET USING (SELECT SL.ID_PRODUCT, SUM(SL.QUANTITY) FROM SALES_ORDER_LINE SL JOIN SALES_ORDER S ON S.ID = SL.ID_SALES_ORDER WHERE S.BYDATE = CURRENT_DATE AND SL.ID_PRODUCT = :ID_PRODUCT GROUP BY 1 ) AS SRC(ID_PRODUCT, QUANTITY) ON TARGET.ID_PRODUCT = SRC.ID_PRODUCT WHEN MATCHED AND TARGET.QUANTITY - SRC.QUANTITY <= 0 THEN DELETE WHEN MATCHED THEN UPDATE SET TARGET.QUANTITY = TARGET.QUANTITY - SRC.QUANTITY, TARGET.BYDATE = CURRENT_DATE RETURNING OLD.QUANTITY, NEW.QUANTITY, SRC.QUANTITY
  31. 31. www.ibase.ru DML: Алиасы в RETURNING Пример -- without aliases UPDATE T1 SET F2 = F2 * 10 RETURNING OLD.F2, NEW.F2; -- with aliases UPDATE T1 SET F2 = F2 * 10 RETURNING OLD.F2 OLD_F2, NEW.F2 AS NEW_F2;
  32. 32. www.ibase.ru DML: OFFSET … FETCH Синтаксис (согласно SQL:2008) SELECT ... FROM ... [...] [ORDER BY <expr_order_list>] [OFFSET <simple_value_expr> {ROW | ROWS}] [FETCH {FIRST | NEXT} [<simple_value_expr>] {ROW | ROWS} [ONLY]]
  33. 33. www.ibase.ru DML: OFFSET … FETCH Пример SELECT * FROM T1 ORDER BY COL1 OFFSET 10 ROWS; SELECT * FROM ( SELECT * FROM T1 ORDER BY COL1 DESC OFFSET 1 ROW FETCH NEXT 10 ROWS ONLY ) a ORDER BY a.COL1 FETCH FIRST ROW ONLY
  34. 34. www.ibase.ru DML: SUBSTRING c RegExp Синтаксис SUBSTRING (str SIMILAR <similar_pattern> ESCAPE <escape>) <similar_pattern> ::= <similar pattern: R1> <escape>"<similar pattern: R2><escape>" <similar pattern: R3> Особенности: • Возвращается часть строки соответствующая выражению R2 • Для возвращаемого значения истинно выражение str SIMILAR TO R1 || R2 || R3 ESCAPE <escape>
  35. 35. www.ibase.ru DML: SUBSTRING c RegExp Примеры SUBSTRING('abcabc' SIMILAR 'a#"bcab#"c' ESCAPE '#') -- bcab SUBSTRING('abcabc' SIMILAR 'a#"%#"c' ESCAPE '#') -- bcab SUBSTRING('abcabc' SIMILAR '_#"%#"_' ESCAPE '#') -- bcab SUBSTRING('abcabc' SIMILAR '#"(abc)*#"' ESCAPE '#') -- abcabc SUBSTRING('abcabc' SIMILAR '#"abc#"' ESCAPE '#') -- <null>
  36. 36. www.ibase.ru DML: Альтернативное экранирование кавычек Синтаксис Q <quote> <alternate start char> [{ <char> }...] <alternate end char> <quote> Особенности: • Если <alternate start char> является одним из символов '(', '{', '[' или '<', то <alternate end char> должен быть использован в паре с соответствующим "партнёром", а именно ')', '}', ']' или '>'. В других случаях <alternate end char> совпадает с <alternate start char>.
  37. 37. www.ibase.ru DML: Альтернативное экранирование кавычек Примеры -- result: a'bc{def}ghi SELECT Q'{a'bc{def}ghi}' FROM rdb$database; -- result: That's a string SELECT Q'!That's a string!' FROM rdb$database;
  38. 38. www.ibase.ru DML: Тип BOOLEAN Синтаксис <data_type> ::= BOOLEAN <boolean_literal> ::= TRUE | FALSE | UNKNOWN Хранение: • 1 байт Поддержка в клиенте (XSQLDA): • #define SQL_BOOLEAN 32764
  39. 39. www.ibase.ru DML: Тип BOOLEAN Таблицы истинности AND TRUE FALSE UNKNOWN TRUE TRUE FALSE UNKNOWN FALSE FALSE FALSE FALSE UNKNOWN UNKNOWN FALSE UNKNOWN OR TRUE FALSE UNKNOWN TRUE TRUE TRUE TRUE FALSE TRUE FALSE UNKNOWN UNKNOWN TRUE UNKNOWN UNKNOWN IS TRUE FALSE UNKNOWN TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE UNKNOWN FALSE FALSE TRUE NOT TRUE FALSE FALSE TRUE UNKNOWN UNKNOWN
  40. 40. www.ibase.ru DML: Тип BOOLEAN Примеры CREATE TABLE TBOOL (ID INT, BVAL BOOLEAN); COMMIT; INSERT INTO TBOOL VALUES (1, TRUE); INSERT INTO TBOOL VALUES (2, 2 = 4); INSERT INTO TBOOL VALUES (3, NULL = 1); COMMIT; SELECT * FROM TBOOL ID BVAL ---- ------- 1 <true> 2 <false> 3 <null>
  41. 41. www.ibase.ru DML: Тип BOOLEAN Примеры (продолжение) -- Проверка TRUE значения SELECT * FROM TBOOL WHERE BVAL -- Проверка UNKNOWN значения SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN -- Логические значения в SELECT списке SELECT ID, BVAL, BVAL AND ID < 2 FROM TBOOL -- PSQL объявления с начальным значением DECLARE VARIABLE VAR1 BOOLEAN = TRUE; -- Допустимый синтаксис, но как и сравнение -- с NULL, никогда не вернёт ни одной записи SELECT * FROM TBOOL WHERE BVAL = UNKNOWN SELECT * FROM TBOOL WHERE BVAL <> UNKNOWN
  42. 42. www.ibase.ru DML: Стабильность курсора Проявление • Бесконечный цикл вставки (CORE-92) INSERT INTO T SELECT * FROM T • DELETE удалит все записи (CORE-634) DELETE FROM T WHERE ID IN (SELECT FIRST 1 ID FROM T) • Подвержены все DML операторы (INSERT, UPDATE, DELETE, MERGE) • Общий билет в трекере CORE-3362
  43. 43. www.ibase.ru DML: Стабильность курсора PSQL • PSQL курсоры содержащие SUSPEND не стабильны FOR SELECT NAME FROM T INTO :NAME DO BEGIN INSERT INTO T (NAME) VALUES (:NAME); SUSPEND; END • PSQL курсоры не содержащие SUSPEND стабильны FOR SELECT ID FROM T WHERE VAL IS NULL INTO :ID DO BEGIN UPDATE T SET VAL = 1 WHERE ID = :ID; END
  44. 44. www.ibase.ru DML: Смешение явных и неявных JOIN (TA, TB JOIN TC) эквивалентно TA, (TB JOIN C) и не эквивалентно (TA, TB) JOIN C Вызовет ошибку «Column does not belong to referenced table» SELECT * FROM TA, TB JOIN TC ON TA.COL1 = TC.COL1 WHERE TA.COL2 = TB.COL2 Отработает без ошибок SELECT * FROM TA, TB JOIN TC ON TB.COL1 = TC.COL1 WHERE TA.COL2 = TB.COL2
  45. 45. www.ibase.ru DML: Внутренние JOIN с хранимыми процедурами Примеры SELECT * FROM T JOIN MY_PROC(T.F1) P ON T.F2 = P.F2 • До Firebird 3.0 такой запрос вызывал ошибку «no current record for fetch operation». Эту проблему решали так: SELECT * FROM T LEFT JOIN MY_PROC(T.F1) P ON 1=1 WHERE T.F2 = P.F2
  46. 46. www.ibase.ru НОВОЕ В PSQL
  47. 47. www.ibase.ru PSQL: SQL функции Синтаксис {CREATE [OR ALTER] | ALTER | RECREATE} FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] { EXTERNAL NAME '<extname>' ENGINE <engine> } | { AS [<declarations>] BEGIN [<PSQL_statements>] END } DROP FUNCTION funcname
  48. 48. www.ibase.ru PSQL: SQL функции Особенности • Возвращает скалярный результат • Для возврата значения функции используется RETURN <value> • Флаг DETERMINISTIC работает только для функций без параметров
  49. 49. www.ibase.ru PSQL: SQL функции Примеры CREATE FUNCTION ADD_INT(A INT, B INT DEFAULT 0) RETURNS INT AS BEGIN RETURN A+B; END Вызов SELECT ADD_INT(2, 3) AS R FROM RDB$DATABASE В PSQL … C = ADD_INT(A, B); …
  50. 50. www.ibase.ru PSQL: SQL функции Флаг DETERMINISTIC CREATE FUNCTION FN_T RETURNS DOUBLE PRECISION DETERMINISTIC AS BEGIN RETURN rand(); END -- функция будет вычислена дважды и вернёт 2 разных значения SELECT fn_t() FROM rdb$database UNION ALL SELECT fn_t() FROM rdb$database -- функция будет вычислена единожды и вернёт одинаковые значения WITH t(n) AS ( SELECT 1 FROM rdb$database UNION ALL SELECT 2 FROM rdb$database) SELECT n, fn_t() FROM t
  51. 51. www.ibase.ru PSQL: Внешние процедуры, функции, триггеры Синтаксис (README.external_routines) CREATE PROCEDURE procname [(<inparam> [, <inparam> ...])] RETURNS (<outparam> [, <outparam> ...]) EXTERNAL NAME '<extname>' ENGINE <engine>; CREATE FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] EXTERNAL NAME '<extname>' ENGINE <engine>; CREATE TRIGGER trigname { <relation_trigger_legacy> | <relation_trigger_sql2003> | <database_trigger> | <ddl_trigger> } EXTERNAL NAME '<extname>' ENGINE <engine>; <extname> ::= '<module name>!<routine name>[!<misc info>]'
  52. 52. www.ibase.ru PSQL: Внешние процедуры, функции, триггеры Примеры (examples/udr/*) CREATE PROCEDURE gen_rows ( start_n INTEGER NOT NULL, end_n INTEGER NOT NULL) RETURNS (n INTEGER NOT NULL) EXTERNAL NAME 'udrcpp_example!gen_rows' ENGINE udr; CREATE FUNCTION wait_event ( event_name varchar(31) CHARACTER SET ascii ) RETURNS INTEGER EXTERNAL NAME 'udrcpp_example!wait_event' ENGINE udr; CREATE TRIGGER PERSONS_REPLICATE AFTER INSERT ON PERSONS EXTERNAL NAME 'udrcpp_example!replicate!ds1' ENGINE UDR;
  53. 53. www.ibase.ru PSQL: Подпрограммы Синтаксис • Подпроцедура DECLARE PROCEDURE procname [(<inparam> [, <inparam> ...])] [RETURNS (<outparam> [, <outparam> ...])] AS … • Подфункция DECLARE FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] AS …
  54. 54. www.ibase.ru PSQL: Подпрограммы Особенности • Подпрограмма не может быть вложена в другую подпрограмму. Они поддерживаются только в основном модуле. • В настоящее время подпрограмма не имеет прямого доступа для использования переменных, курсоров и других подпрограмм из основного модуля. Кроме того, подпрограмма не может вызывать себя рекурсивно. Это может быть разрешено в будущем.
  55. 55. www.ibase.ru PSQL: Подпрограммы Пример EXECUTE BLOCK RETURNS (N INT) AS DECLARE FUNCTION F(X INT, Y INT) RETURNS INT AS BEGIN RETURN X + Y; END BEGIN N = F(5, 6); SUSPEND; END
  56. 56. www.ibase.ru PSQL: Пакеты Преимущества • Модульность • Упрощение отслеживания зависимостей • Упрощение управления разрешениями • Частные области видимости
  57. 57. www.ibase.ru PSQL: Пакеты Синтаксис {CREATE [OR ALTER] | ALTER | RECREATE} PACKAGE package_name AS BEGIN [<package_item> ...] END {CREATE | ALTER | RECREATE} PACKAGE BODY package_name AS BEGIN [<package_item> ...] [<package_body_item> ...] END <package_item> ::= <function_decl>; | <procedure_decl>;
  58. 58. www.ibase.ru PSQL: Пакеты Синтаксис (продолжение) <function_decl> ::= FUNCTION func_name [(<in_params>)] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <procedure_decl> ::= PROCEDURE proc_name [(<in_params>)] [RETURNS (<out_params>)] <package_body_item> ::= <function_impl> | <procedure_impl> <function_impl> ::= FUNCTION func_name [(<in_impl_params>)] RETURNS <type> [COLLATE collation] [DETERMINISTIC] { EXTERNAL NAME '<extname>' ENGINE <engine> } | { AS [<declarations>] BEGIN [<PSQL_statements>] END }
  59. 59. www.ibase.ru PSQL: Пакеты Синтаксис (продолжение) <procedure_impl> ::= PROCEDURE proc_name [(<in_impl_params>)] [RETURNS (<out_params>)] { EXTERNAL NAME '<extname>' ENGINE <engine> } | { AS [<declarations>] BEGIN [<PSQL_statements>] END } Правила • В теле пакеты должны быть реализованы все подпрограммы, стой же сигнатурой, что и объявленные в заголовке и в начале тела пакета. • Значения по умолчанию для параметров процедур не могут быть переопределены (которые указываются в <package_item>). Это означает, что они могут быть в <package_body_item> только для частных процедур, которые не были объявлены.
  60. 60. www.ibase.ru PSQL: Пакеты (примеры) -- заголовок пакета CREATE OR ALTER PACKAGE TEST AS BEGIN PROCEDURE P1(I INT = 1) RETURNS (O INT); -- публичная процедура END^ -- тело пакета, реализация RECREATE PACKAGE BODY TEST AS BEGIN FUNCTION F1(I INT) RETURNS INT; -- частная функция PROCEDURE P1(I INT) RETURNS (O INT) AS BEGIN O = F1(I); SUSPEND; END FUNCTION F1(I INT) RETURNS INT AS BEGIN RETURN I * I; END END^
  61. 61. www.ibase.ru PSQL: Пакеты (примеры) CREATE OR ALTER PACKAGE REGEXP AS BEGIN PROCEDURE preg_match(Pattern VARCHAR(8192), Subject VARCHAR(8192)) RETURNS (Matches VARCHAR(8192)); FUNCTION preg_is_match(Pattern VARCHAR(8192), Subject VARCHAR(8192)) RETURNS BOOLEAN; FUNCTION preg_replace(Pattern VARCHAR(8192), Replacement VARCHAR(8192), Subject VARCHAR(8192)) RETURNS VARCHAR(8192); … END
  62. 62. www.ibase.ru PSQL: Пакеты (примеры) RECREATE PACKAGE BODY REGEXP AS BEGIN PROCEDURE preg_match(Pattern varchar(8192), Subject varchar(8192)) RETURNS (Matches varchar(8192)) EXTERNAL name 'PCRE!preg_match' ENGINE UDR; FUNCTION preg_is_match(Pattern varchar(8192), Subject varchar(8192)) RETURNS BOOLEAN AS BEGIN RETURN EXISTS(SELECT * FROM preg_match(:Pattern, :Subject)); END … END
  63. 63. www.ibase.ru PSQL: Пакеты Синтаксис комментариев COMMENT ON PACKAGE package_name IS {'sometext' | NULL} COMMENT ON PROCEDURE package_name.proc_name IS {'sometext' | NULL} COMMENT ON FUNCTION package_name.func_name IS {'sometext' | NULL}
  64. 64. www.ibase.ru PSQL: Исключения с параметрами Синтаксис • Исключения со слотами (@1, @2, ...). Нумерация начинается с 1. Максимальный номер слота равен 9. CREATE EXCEPTION EX_WITH_PARAMS 'Error @1 : @2'; • При возбуждении исключения с параметрами используется предложение USING EXEPTION EX_WITH_PARAMS USING (1, 'You can not do it'); • Замечание: Если в тексте сообщения, встретится номер слота больше 9, то второй и последующий символ будут восприняты как литералы. Например, @10 будет воспринято как @1, после которого следует литерал 0.
  65. 65. www.ibase.ru PSQL: SQLSTATE в обработчике WHEN Пример EXECUTE BLOCK AS DECLARE VARIABLE I INT; BEGIN BEGIN I = 1 / 0; WHEN SQLSTATE '22003' DO EXCEPTION E_CUSTOM_EXCEPTION 'Numeric value out of range.'; WHEN SQLSTATE '22012' DO EXCEPTION E_CUSTOM_EXCEPTION 'Division by zero.'; END END
  66. 66. www.ibase.ru PSQL: CONTINUE в циклах Синтаксис [label:] {FOR <select_stmt> | WHILE (<condition>)} DO BEGIN ... CONTINUE [label]; ... END Пример FOR SELECT A, D FROM ATABLE INTO :achar, :ddate DO BEGIN IF (ddate < current_data - 30) THEN CONTINUE; ELSE /* do stuff */ ... END
  67. 67. www.ibase.ru PSQL: Ссылки на курсоры Пример FOR SELECT A, B, C FROM ... AS CURSOR C1 -- предложение INTO необязательно DO BEGIN ... INSERT INTO T(A, B, C) VALUES (C1.A, C1.B, C1.C, …); -- ссылка на курсор END
  68. 68. www.ibase.ru Замечания • Для разрешения конфликтов используется символ «:» • В операторе FOR SELECT без предложения AS CURSOR необходимо использовать предложение INTO. Если указано предложение AS CURSOR, предложение INTO не требуется, но разрешено. • В операторе FETCH предложение INTO необязательное. • Чтение из переменной курсора возвращает текущие значения полей. Поэтому UPDATE с WHERE CURRENT OF обновит значения полей в курсоре, а DELETE установит их в NULL. PSQL: Ссылки на курсоры
  69. 69. www.ibase.ru PSQL: Ссылки на курсоры Разрешение конфликтов EXECUTE BLOCK RETURNS (o1 CHAR(31), o2 CHAR(31)) AS BEGIN FOR SELECT rdb$relation_name FROM rdb$relations WHERE rdb$relation_name = 'RDB$RELATIONS' AS CURSOR c DO BEGIN FOR SELECT -- с префиксом разрешается как курсор :c.rdb$relation_name x1, -- без префикса как псевдоним таблицы rdb$relations c.rdb$relation_name x2 FROM rdb$relations c WHERE rdb$relation_name = 'RDB$DATABASE' AS CURSOR d DO BEGIN ... END END END
  70. 70. www.ibase.ru PSQL: Ссылки на курсоры Обратная совместимость EXECUTE BLOCK AS DECLARE VARIABLE BYYEAR SMALLINT; DECLARE VARIABLE PO_NUMBER PONUMBER; BEGIN FOR SELECT EXTRACT(YEAR FROM sales.order_date), -- нужен алиас PO_NUMBER FROM sales INTO :BYYEAR, :PO_NUMBER AS CURSOR c DO BEGIN IF (BYYEAR > 2000) THEN UPDATE sales SET order_date = '31.12.2000' WHERE CURRENT OF c; END END Вернёт ошибку: «no column name specified for column number 1 in derived table C».
  71. 71. www.ibase.ru PSQL: Двунаправленные курсоры Синтаксис DECLARE [VARIABLE] cursor_name [SCROLL | NO SCROLL] CURSOR FOR (<select_statement>); FETCH cursor_name [INTO [:]var_name [, [:]var_name ...]]; FETCH {NEXT | PRIOR | FIRST | LAST | ABSOLUTE n | RELATIVE n} FROM cursor_name [INTO [:]var_name [,[:]var_name ...]];
  72. 72. www.ibase.ru PSQL: Двунаправленные курсоры Пример EXECUTE BLOCK RETURNS (N INT) AS DECLARE C SCROLL CURSOR FOR ( SELECT ROW_NUMBER() OVER(ORDER BY RDB$RELATION_NAME) AS N FROM RDB$RELATIONS ORDER BY RDB$RELATION_NAME); BEGIN -- после открытия курсора мы на 1 записи (N=1) OPEN C; N = C.N; SUSPEND; -- перемещаемся на 1 запись вперёд (N=2) FETCH NEXT FROM C; N = C.N; SUSPEND; -- перемещаемся на пятую запись (N=5) FETCH ABSOLUTE 5 FROM C; N = C.N; SUSPEND; -- перемещаемся на 1 запись назад (N=4) FETCH PRIOR FROM C; N = C.N; SUSPEND; -- перемещаемся на последнюю запись (N=61) FETCH LAST FROM C; N = C.N; SUSPEND; -- перемещаемся на 5 записей назад (N=56) FETCH RELATIVE -5 FROM C; N = C.N; SUSPEND; -- перемещаемся на первую запись (N=1) FETCH FIRST FROM C; N = C.N; SUSPEND; CLOSE C; END
  73. 73. www.ibase.ru НОВОЕ В DDL
  74. 74. www.ibase.ru DDL: Управление допустимостью NULL Синтаксис • Для столбцов таблиц ALTER TABLE tablename ALTER [COLUMN] colname {SET | DROP} NOT NULL • Для доменов ALTER DOMAIN domainname {SET | DROP} NOT NULL Замечание: Теперь при добавлении NOT NULL столбца предложение DEFAULT обязательное
  75. 75. www.ibase.ru DDL: Управление допустимостью NULL Примеры ALTER TABLE OBJECTS ADD QUANTITY INT DEFAULT 1 NOT NULL; ALTER TABLE STOCK ALTER COLUMN MODEL SET NOT NULL, ALTER COLUMN ITEMID DROP NOT NULL; ALTER DOMAIN D_FIRSTNAME SET NOT NULL;
  76. 76. www.ibase.ru DDL: IDENTITY столбцы Синтаксис <column definition> ::= <name> <type> GENERATED BY DEFAULT AS IDENTITY [STARTS WITH number] <constraints> <alter column definition> ::= <name> RESTART [WITH number] При создании автоинкрементного столбца создаётся системная последовательность (RDB$GENERATORS.RDB$SYSTEM_FLAG = 6). А в свойствах поля (RDB$RELATION_FIELDS. RDB$GENERATOR_NAME) имя этого системного генератора.
  77. 77. www.ibase.ru DDL: IDENTITY столбцы Правила • Тип столбца INTEGER, BIGINT или NUMERIC(p, 0) • Неявно накладывается ограничение NOT NULL • Уникальность не гарантируется • Не может содержать предложение DEFAULT • Не может быть COMPUTED BY • Не может быть изменён на не IDENTITY
  78. 78. www.ibase.ru DDL: IDENTITY столбцы Примеры CREATE TABLE objects ( id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(15) ); INSERT INTO objects (name) VALUES ('Table'); INSERT INTO objects (name) VALUES ('Book'); INSERT INTO objects (id, name) VALUES (10, 'Computer'); SELECT * FROM objects; ID NAME ---- ------- 1 Table 2 Book 10 Computer
  79. 79. www.ibase.ru DDL: Последовательности Синтаксис CREATE {SEQUENCE | GENERATOR} seq_name [START WITH value] [INCREMENT [BY] increment]; ALTER {SEQUENCE | GENERATOR} seq_name [RESTART [WITH new_val]] [INCREMENT [BY] increment]; CREATE OR ALTER {SEQUENCE | GENERATOR} seq_name [{START WITH value | RESTART}] [INCREMENT [BY] increment]; RECREATE {SEQUENCE | GENERATOR} seq_name [START WITH value] [INCREMENT [BY] increment]; Начальное значение генератора хранится в поле RDB$INITIAL_VALUE таблицы RDB$GENERATORS, а значение приращения в поле RDB$GENERATOR_INCREMENT.
  80. 80. www.ibase.ru DDL: Последовательности Примеры CREATE SEQUENCE EMP_NO_GEN; CREATE SEQUENCE EMP_NO_GEN START WITH 5; ALTER SEQUENCE EMP_NO_GEN RESTART WITH 145; ALTER SEQUENCE EMP_NO_GEN RESTART; ALTER SEQUENCE EMP_NO_GEN INCREMENT BY 10;
  81. 81. www.ibase.ru DDL: DDL триггеры Синтаксис <ddl-trigger> ::= {CREATE | RECREATE | CREATE OR ALTER} TRIGGER name [ACTIVE | INACTIVE] {BEFORE | AFTER} <ddl event> [POSITION n] <ddl event> ::= ANY DDL STATEMENT | <ddl event item> [{OR <ddl event item>} ...] <ddl event item> ::= {CREATE | ALTER | DROP} {TABLE | PROCEDURE | FUNCTION | TRIGGER | EXCEPTION | VIEW | DOMAIN | SEQUENCE | INDEX | ROLE | FILTER | USER | COLLATION | PACKAGE | PACKAGE BODY | CHARACTER SET | MAPPING}
  82. 82. www.ibase.ru DDL: DDL триггеры Новые контекстные переменные (RDB$GET_CONTEXT) • Пространство имён DDL_TRIGGER • Существуют только внутри DDL триггеров и процедур/функций вызываемых из этих триггеров • Только для чтения • Предопределённые переменные: • EVENT_TYPE - тип события (CREATE, ALTER, DROP) • OBJECT_TYPE - тип объекта (TABLE, VIEW и д.р.) • DDL_EVENT - имя события = EVENT_TYPE || ' ' || OBJECT_TYPE • OBJECT_NAME - имя объекта метаданных • OLD_OBJECT_NAME - имя объекта метаданных до переименования • NEW_OBJECT_NAME - имя объекта метаданных после переименования • SQL_TEXT - текст SQL запроса
  83. 83. www.ibase.ru DDL: DDL триггеры Пример 1 CREATE EXCEPTION EX_BAD_SP_NAME 'Name of procedures must start with ''@1'' : ''@2'''; CREATE TRIGGER TRG_SP_CREATE BEFORE CREATE PROCEDURE AS DECLARE SP_NAME VARCHAR(255); BEGIN SP_NAME = RDB$GET_CONTEXT('DDL_TRIGGER', 'OBJECT_NAME'); IF (SP_NAME NOT STARTING 'SP_') THEN EXCEPTION EX_BAD_SP_NAME USING ('SP_', SP_NAME); END
  84. 84. www.ibase.ru DDL: DDL триггеры Пример 2 CREATE SEQUENCE ddl_seq; CREATE TABLE ddl_log ( id BIGINT NOT NULL PRIMARY KEY, moment TIMESTAMP NOT NULL, user_name VARCHAR(31) NOT NULL, event_type VARCHAR(25) NOT NULL, object_type VARCHAR(25) NOT NULL, ddl_event VARCHAR(25) NOT NULL, object_name VARCHAR(31) NOT NULL, old_object_name VARCHAR(31), new_object_name VARCHAR(31), sql_text BLOB sub_type text NOT NULL, ok CHAR(1) NOT NULL );
  85. 85. www.ibase.ru DDL: DDL триггеры CREATE TRIGGER trig_ddl_log_before BEFORE ANY DDL STATEMENT AS DECLARE id TYPE OF COLUMN ddl_log.id; BEGIN IN AUTONOMOUS TRANSACTION DO BEGIN INSERT INTO ddl_log (id, moment, user_name, event_type, object_type, ddl_event, object_name, old_object_name, new_object_name, sql_text, ok) VALUES (NEXT VALUE FOR ddl_seq, current_timestamp, current_user, rdb$get_context('DDL_TRIGGER', 'EVENT_TYPE'), rdb$get_context('DDL_TRIGGER', 'OBJECT_TYPE'), rdb$get_context('DDL_TRIGGER', 'DDL_EVENT'), rdb$get_context('DDL_TRIGGER', 'OBJECT_NAME'), rdb$get_context('DDL_TRIGGER', 'OLD_OBJECT_NAME'), rdb$get_context('DDL_TRIGGER', 'NEW_OBJECT_NAME'), rdb$get_context('DDL_TRIGGER', 'SQL_TEXT'), 'N') RETURNING id INTO id; rdb$set_context('USER_SESSION', 'trig_ddl_log_id', id); END END!
  86. 86. www.ibase.ru DDL: DDL триггеры CREATE TRIGGER trig_ddl_log_after AFTER ANY DDL STATEMENT AS BEGIN -- Здесь нам требуется автономная транзакция, -- потому что в оригинальной транзакции -- мы не увидим запись, вставленную в -- BEFORE триггере в автономной транзакции, -- если пользовательская транзакции не запущена -- с режимом изоляции READ COMMITTED. IN AUTONOMOUS TRANSACTION DO UPDATE ddl_log SET ok = 'Y' WHERE id = rdb$get_context('USER_SESSION', 'trig_ddl_log_id'); END! COMMIT! SET TERM ;! -- Удаляем запись о создании trig_ddl_log_after. DELETE FROM ddl_log; COMMIT;
  87. 87. www.ibase.ru DDL: DDL триггеры RECREATE TABLE t1 (n1 INT, n2 INT); -- Эта команда будет зарегистрирована единожды -- (т.к. T1 не существует, RECREATE вызовет событие CREATE) с OK = Y. CREATE TABLE t1 (n1 INT, n2 INT); -- Оператор не выполнится, т.к. T1 уже существует, -- таким образом OK будет иметь значение N. DROP TABLE t2; -- T2 не существует. Это действие не будет зарегистрировано. RECREATE TABLE t1 (n INT); -- Это действие будет зарегистрировано дважды -- (т.к. T1 существует, действие RECREATE рассматривается -- как DROP и CREATE) с полем OK = Y. CREATE DOMAIN dom1 AS INT; ALTER DOMAIN dom1 TYPE BIGINT; ALTER DOMAIN dom1 TO dom2; COMMIT;
  88. 88. www.ibase.ru DDL: DDL триггеры ID DDL_EVENT NAME OLD_NAME NEW_NAME SQL_TEXT OK 2 CREATE TABLE T1 <null> <null> RECREATE TABLE t1 (n1 INT, n2 INT) Y 3 CREATE TABLE T1 <null> <null> CREATE TABLE t1 (n1 INT, n2 INT) N 4 DROP TABLE T1 <null> <null> RECREATE TABLE t1 (n1 INT) Y 5 CREATE TABLE T1 <null> <null> RECREATE TABLE t1 (n1 INT) Y 6 CREATE DOMAIN DOM1 <null> <null> CREATE DOMAIN dom1 AS INT Y 7 ALTER DOMAIN DOM1 <null> <null> ALTER DOMAIN dom1 TYPE BIGINT Y 8 ALTER DOMAIN DOM1 DOM1 DOM2 ALTER DOMAIN dom1 TO dom2 Y Результаты журналирования DDL
  89. 89. www.ibase.ru DDL: CREATE DATABASE Пример CREATE USER wizard PASSWORD 'player‘ GRANT ADMIN ROLE; CREATE DATABASE 'inet://baseserver:3050/test' USER wizard PASSWORD 'player' ROLE RDB$ADMIN DEFAULT CHARACTER SET UTF8; Синтаксис строки подключения <filespec> ::= [<server_spec>]{filepath | db_alias} <server_spec> ::= host[port | service]: | host[@port | service] | <protocol>://[host[:port | service]/] <protocol> = inet | wnet | xnet
  90. 90. www.ibase.ru DDL: ALTER DATABASE Синтаксис ALTER {DATABASE | SCHEMA} {<add_sec_clause> [<add_sec_clausee> ...]} | {ADD DIFFERENCE FILE 'diff_file' | DROP DIFFERENCE FILE} | {{BEGIN | END} BACKUP} | {SET DEFAULT CHARACTER SET charset} | {SET LINGER TO seconds | DROP LINGER} | {ENCRYPT WITH plugin_name | DECRYPT};
  91. 91. www.ibase.ru DDL: ALTER DATABASE Примеры ALTER DATABASE SET DEFAULT CHARACTER SET WIN1251; ALTER DATABASE SET LINGER 30; ALTER DATABASE DROP LINGER; ALTER DATABASE ENCRYPT WITH DbCrypt; ALTER DATABASE DECRYPT;
  92. 92. www.ibase.ru DDL: DROP SHADOW Синтаксис DROP SHADOW number [{PRESERVE | DELETE} FILE]; Примеры DROP SHADOW 1; DROP SHADOW 1 PRESERVE FILE; DROP SHADOW 1 DELETE FILE;
  93. 93. www.ibase.ru НОВОЕ В SECURITY
  94. 94. www.ibase.ru Security: Управление пользователями Синтаксис CREATE USER username <option> [, <option> …] [USING PLUGIN 'pluginname'] [GRANT ADMIN ROLE]; <option> ::= [PASSWORD 'password'] [FIRSTNAME 'firstname'] [MIDDLENAME 'middlename'] [LASTNAME 'lastname'] [ACTIVE | INACTIVE] [TAGS (<tag> | DROP tagname [, <tag> | DROP tagname ...] )] <tag> ::= tagname = 'string value'
  95. 95. www.ibase.ru Security: Управление пользователями Синтаксис (продолжение) ALTER {USER username | CURRENT USER} [SET] <option> [, <option> …] [USING PLUGIN 'pluginname'] [{GRANT | REVOKE} ADMIN ROLE]; CREATE OR ALTER USER username [SET] <option> [, <option> …] [USING PLUGIN 'pluginname'] [{GRANT | REVOKE} ADMIN ROLE]; DROP USER username [USING PLUGIN 'pluginname'];
  96. 96. www.ibase.ru Security: Управление пользователями Особенности: • Без указания USING PLUGIN первый плагин из списка в параметре UserManager • Имя тега не может быть больше 31 символа • Значение тега не может превышать 255 символов • При создании нового пользователя пароль обязателен • В Legacy_UserManager пароль урезается до 8 символов • Имена пользователей в двойных кавычках чувствительны к регистру
  97. 97. www.ibase.ru Security: Управление пользователями Примеры: CREATE USER bigshot PASSWORD 'buckshot'; CREATE USER godzilla PASSWORD 'robot' USING PLUGIN Legacy_UserManager; CREATE USER john PASSWORD 'fYe_3Ksw' FIRSTNAME 'John' LASTNAME 'Doe' TAGS (BIRTHYEAR = '1970', CITY = 'New York'); CREATE USER superuser PASSWORD 'kMn8Kjh' INACTIVE GRANT ADMIN ROLE;
  98. 98. www.ibase.ru Security: Управление пользователями Примеры (продолжение): ALTER USER bigshot GRANT ADMIN ROLE; ALTER USER godzilla PASSWORD 'robot12' USING PLUGIN Legacy_UserManager; ALTER CURRENT USER TAGS (BIRTHYEAR = '1973', DROP CITY); ALTER USER superuser SET ACTIVE; DROP USER godzilla USING PLUGIN Legacy_UserManager;
  99. 99. www.ibase.ru Security: Управление пользователями Комментарии для пользователя Синтаксис COMMENT ON USER username IS {'sometext' | NULL}; Пример COMMENT ON USER SUPERUSER IS 'Владелец текущей базы данных';
  100. 100. www.ibase.ru Security: Управление пользователями Новые виртуальные таблицы: CREATE TABLE SEC$USERS ( SEC$USER_NAME RDB$USER, SEC$FIRST_NAME SEC$NAME_PART, SEC$MIDDLE_NAME SEC$NAME_PART, SEC$LAST_NAME SEC$NAME_PART, SEC$ACTIVE BOOLEAN, SEC$ADMIN BOOLEAN, SEC$DESCRIPTION RDB$DESCRIPTION, SEC$PLUGIN RDB$PLUGIN ); CREATE TABLE SEC$USER_ATTRIBUTES ( SEC$USER_NAME RDB$USER, SEC$KEY SEC$KEY, SEC$VALUE SEC$VALUE );
  101. 101. www.ibase.ru Security: Привилегия EXECUTE Синтаксис GRANT EXECUTE ON <object_type> object_name TO <grantee> [WITH GRANT OPTION] [{GRANTED BY | AS} [USER] grantor]; REVOKE [GRANT OPTION FOR] EXECUTE ON <object_type> object_name FROM <grantee> [{GRANTED BY | AS} [USER] grantor]; <object_type> ::= PROCEDURE | FUNCTION | PACKAGE Замечание: Невозможно выдать или отобрать привилегию EXECUTE у отдельных процедур и функций пакета. Привилегия EXECUTE может быть выдана только на весь пакет.
  102. 102. www.ibase.ru Security: Привилегия EXECUTE Примеры -- Привилегия EXECUTE для хранимой процедуры GRANT EXECUTE ON PROCEDURE ADD_EMP_PROJ TO ROLE MANAGER; -- Привилегия EXECUTE для хранимой функции GRANT EXECUTE ON FUNCTION GET_BEGIN_DATE TO ALEX; -- Привилегия EXECUTE для пакета GRANT EXECUTE ON PACKAGE APP_VAR TO PUBLIC; -- Привилегия EXECUTE для функции выданная пакету GRANT EXECUTE ON FUNCTION GET_BEGIN_DATE TO PACKAGE APP_VAR;
  103. 103. www.ibase.ru Security: Привилегия EXECUTE Примеры (продолжение) -- отзыв привилегии EXECUTE на процедуру REVOKE EXECUTE ON PROCEDURE ADD_EMP_PROJ FROM USER IVAN; -- отзыв привилегии EXECUTE на функцию -- и возможности передавать эту привилегию REVOKE GRANT OPTION FOR EXECUTE ON FUNCTION GET_BEGIN_DATE FROM ALEX; -- отзыв привилегии EXECUTE для пакета REVOKE EXECUTE ON PACKAGE DATE_UTILS FROM ROLE MANAGER;
  104. 104. www.ibase.ru Security: Привилегия USAGE Синтаксис GRANT USAGE ON <object_type> object_name TO <grantee> [WITH GRANT OPTION] [{GRANTED BY | AS} [USER] grantor]; REVOKE [GRANT OPTION FOR] USAGE ON <object_type> object_name FROM <grantee> [{GRANTED BY | AS} [USER] grantor]; <object_type> ::= EXCEPTION | GENERATOR | SEQUENCE
  105. 105. www.ibase.ru Security: Привилегия USAGE Примеры -- Привилегия USAGE на последовательность выданная роли GRANT USAGE ON SEQUENCE GEN_AGE TO ROLE MANAGER; -- Привилегия USAGE на последовательность выданная триггеру GRANT USAGE ON SEQUENCE GEN_AGE TO TRIGGER TR_AGE_BI; -- Привилегия USAGE на исключение выданная пакету GRANT USAGE ON EXCEPTION E_ACCESS_DENIED TO PACKAGE PKG_BILL;
  106. 106. www.ibase.ru Security: Привилегия USAGE Примеры (продолжение) -- Отзыв привилегии USAGE на последовательность у роли REVOKE USAGE ON SEQUENCE GEN_AGE FROM ROLE MANAGER; -- Отзыв привилегии USAGE на последовательность у триггера REVOKE USAGE ON SEQUENCE GEN_AGE FROM TRIGGER TR_AGE_BI; -- Отзыв привилегии USAGE на исключение у пакета REVOKE USAGE ON EXCEPTION E_ACCESS_DENIED FROM PACKAGE PKG_BILL;
  107. 107. www.ibase.ru Security: DDL привилегии Синтаксис GRANT <ddl_privileges> <object_type> TO <grantee> [WITH GRANT OPTION] [{GRANTED BY | AS} [USER] grantor]; REVOKE [GRANT OPTION FOR] <ddl_privileges> <object_type> FROM <grantee> [{GRANTED BY | AS} [USER] grantor]; <ddl_privileges> ::= ALL [PRIVILEGES] | <ddl_privilege> [, <ddl_privilege> …] <ddl_privilege> ::= {CREATE | ALTER ANY | DROP ANY} <object_type> ::= TABLE | VIEW | PROCEDURE | FUNCTION | PACKAGE | GENERATOR | SEQUENCE | EXCEPTION | DOMAIN | FILTER | ROLE | CHARACTER SET | COLLATION
  108. 108. www.ibase.ru Security: DDL привилегии Синтаксис (специальная форма для DATABASE) GRANT <ddl_privileges> DATABASE TO <grantee> [WITH GRANT OPTION] [{GRANTED BY | AS} [USER] grantor]; REVOKE [GRANT OPTION FOR] <ddl_privileges> <object_type> FROM <grantee> [{GRANTED BY | AS} [USER] grantor]; <ddl_privileges> ::= ALL [PRIVILEGES] | <ddl_privilege> [, <ddl_privilege> …] <ddl_privilege> ::= {CREATE | ALTER | DROP} Замечания: • Привилегия CREATE DATABASE хранится в SecurityDatabase. Список пользователей которые могут создать новую базу данных можно посмотреть в таблице SEC$DB_CREATORS. • ALL PRIVILEGES не включает привилегию CREATE DATABASE
  109. 109. www.ibase.ru Security: DDL привилегии Примеры -- Разрешение пользователю Joe создавать таблицы GRANT CREATE TABLE TO Joe; -- Разрешение пользователю Joe изменять любые процедуры GRANT ALTER ANY PROCEDURE TO Joe; -- Разрешение пользователю Joe создавать, изменять и удалять любые представления GRANT ALL PRIVILEGES VIEW TO Joe; -- Разрешение пользователю Joe изменять и удалять любые генераторы (последовательности) GRANT ALTER ANY, DROP ANY SEQUENCE TO Joe; -- Разрешение пользователю SuperUser создавать базы данных GRANT CREATE DATABASE TO SuperUser;
  110. 110. www.ibase.ru Security: DDL привилегии Примеры -- Отзыв у Joe привилегии на создание таблиц REVOKE CREATE TABLE FROM Joe; -- Отзыв у Joe привилегии на изменение любых процедур REVOKE ALTER ANY PROCEDURE FROM Joe; -- Отзыв у Joe привилегий на создание, изменение и удаление любых представлений REVOKE ALL PRIVILEGES VIEW FROM Joe; -- Отзыв у Joe привилегий на изменение и удаление любых генераторов (последовательностей) REVOKE ALTER ANY, DROP ANY SEQUENCE FROM Joe; -- Отзыв у SuperUser привилегий на создание и удаление базы данных REVOKE CREATE, DROP DATABASE FROM SuperUser;
  111. 111. www.ibase.ru Security: Изменение текущей роли Синтаксис SET ROLE grantee SET TRUSTED ROLE Примеры SET ROLE MANAGER;
  112. 112. www.ibase.ru Security: Шифрование Синтаксис ALTER DATABASE ENCRYPT WITH plugin_name ALTER DATABASE DECRYPT • Процесс шифрования может быть проконтролирован с помощью поля MON$CRYPT_PAGE в псевдо-таблице MON$DATABASE или смотреть страницу заголовка базы данных с помощью gstat -e.

×