Использование хранимых процедур в MySQL (Константин Осипов)

1,948 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,948
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
24
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Использование хранимых процедур в MySQL (Константин Осипов)

  1. 1. Использование хранимых процедур в MySQL Highload++, 26 октября 2010 Константин Осипов, konstantin@mysql.com
  2. 2. Скрипт с примерами для презентации находится по адресу: http://forge.mysql.com/tools/tool.php?id=263 (-> forge.mysql.com, -> “ Newest code examples” в левом правом углу, -> один из последних примеров).
  3. 3. Содержание 0 – Вводный обзор 1 – История синтаксиса 2 – Основные конструкции 3 – Обработка исключений 4 – Привилегии 5 – Dynamic SQL 6 – Основы репликации SQL/PSM 8 – Разрешение проблем 9 – Ссылки
  4. 4. Краткая история языка SQL/PSM <ul><li>Заявка на стандартизацию подана в 1991 г. (Melton, Bauer, Eisenberg)
  5. 5. Синтаксис языка унаследован от Ada
  6. 6. ANSI/ISO стандарт с 1996 г.
  7. 7. Поддерживается IBM DB2 и MySQL. Диалекты Microsoft , Oracle, PostgreSQL отличны. </li></ul>
  8. 8. Ada procedure Demo is type SMALLINT is range 0..256; Idx : SMALLINT; Cnt : SMALLINT:= 10; begin -- Это комментарий Idx := 1; named: loop -- Ещё комментарий Put_Line( &quot;In the loop&quot; ); Idx := Idx + 1; if Idx = Cnt then Idx := - Idx; end if ; if Idx + Cnt = 0 then exit named; end if ; end loop named; exception when Constraint_Error => Put_Line(&quot; Error &quot;); end ; SQL/PSM vs. Ada SQL/PSM create procedure Demo() begin declare Idx SMALLINT UNSIGNED ; declare Cnt SMALLINT UNSIGNED default 10; declare exit handler for sqlstate &quot; 22003 &quot; select &quot; Error &quot;; -- Это комментарий set Idx = 1; named: loop -- Ещё комментарий select &quot; In the loop &quot; as &quot;&quot; ; set Idx = Idx + 1; if Idx = Cnt then set Idx = - Idx; end if ; if Idx + Cnt = 0 then leave named; end if ; end loop ; end |
  9. 9. Ada procedure Demo is type SMALLINT is range 0..256; Idx : SMALLINT; Cnt : SMALLINT:= 10; begin -- Это комментарий Idx := 1; named: loop -- Ещё комментарий Put_Line( &quot;In the loop&quot; ); Idx := Idx + 1; if Idx = Cnt then Idx := - Idx; end if ; if Idx + Cnt = 0 then exit named; end if ; end loop named; exception when Constraint_Error => Put_Line(&quot; Error &quot;); end ; Oracle PL/SQL vs. Ada Oracle PL/SQL create procedure Demo is Idx POSITIVE ; Cnt POSITIVE default 10; begin -- Это комментарий Idx := 1; <<named>> loop -- Ещё комментарий dbms_output.put_line( &quot; In the loop &quot;); Idx := Idx + 1; if Idx = Cnt then set Idx := - Idx; end if ; if Idx + Cnt = 0 then exit named; end if ; end loop ; exception when VALUE_ERROR then dbms_output.put_line( &quot; Error &quot; ); end ;
  10. 10. Основные свойства SQL/PSM <ul><li>императивный язык программирования на стороне СУБД
  11. 11. не чувствителен к регистру, как весь SQL
  12. 12. cтрого типизирован
  13. 13. cтрого декларативен
  14. 14. есть поддержка исключений
  15. 15. нет конструкций ООП
  16. 16. доступен для 4 типов хранимых объектов: </li><ul><li>PROCEDURE, FUNCTION, TRIGGER, EVENT </li></ul></ul>
  17. 17. Грамматика SQL/PSM (1) sp_sql ::= create | drop | call | alter * create ::= CREATE [ DEFINER= user ] PROCEDURE name ( [ param_desc [ , ...]] ) [ characteristic ... ] sp_body drop ::= DROP PROCEDURE name call ::= CALL name ( [ parameter [ , ...]] ) * CALL – лексема name – продукция, идентификатор, литерал [] – необязательный параметр ,... – допустим список
  18. 18. SQL/PSM: процедуры (2) create ::= CREATE [ DEFINER= user ] PROCEDURE name ( [ param_desc [ , ...]] ) [ characteristic ... ] sp_body param_desc ::= [ IN | OUT | INOUT ] name type sp_body ::= sp_stmt sp_stmt ::= simple_sql | if | case | loop | while | repeat | return | leave | open | fetch | close | [ label : ] BEGIN [ sp_decl ; [...]] [ sp_stmt ; [...]] END simple_sql ::= SELECT | INSERT | SET | CALL | ...
  19. 19. SQL/PSM (3): функции sf_sql ::= create | drop | alter create ::= CREATE [ DEFINER= user ] FUNCTION name ( [ func_param_desc [ , ...]] ) RETURNS type <-- [ characteristic [...] ] sp_body * drop ::= DROP FUNCTION name func_param_desc ::= name type * * sp_body обязательно имеет return продукцию * func_param_desc допускает только IN параметры
  20. 20. SQL/PSM (4): декларации sp_stmt ::= ... | BEGIN [sp_decl ; [...]] <-- [ sp_body ; [...]] END sp_decl ::= DECLARE { name [ , ...] type [ default ] | name CONDITION FOR cond_desc | name CURSOR FOR simple_sql | { CONTINUE | EXIT } HANDLER FOR hand_desc sp_stmt } Порядок деклараций строго фиксирован: 1) variables, conditions 2) cursors 3) handlers
  21. 21. SQL/PSM (5): переменные sp_decl ::= DECLARE name [ , ...] type [ DEFAULT expr ] | ... Каждая переменная обладает: <ul><ul><li>типом
  22. 22. значением
  23. 23. областью видимости </li></ul></ul>
  24. 24. SQL/PSM (6): курсоры, исключения sp_decl ::= ... | DECLARE name CURSOR FOR select_sql | <-- DECLARE { CONTINUE | EXIT } HANDLER FOR handler_desc [ , ...] sp_stmt select_sql ::= SELECT ... handler_desc ::= NOT FOUND | SQLWARNING | SQLEXCEPTION | errcode | SQLSTATE [ VALUE ] &quot; sqlstate &quot;
  25. 25. Курсоры (1) Псевдокод 1 OPEN c; 2 fetching: LOOP 3 FETCH c INTO col1, col2; 4 IF flag THEN LEAVE fetching; END IF ; 5 -- работаем с col1, col2 6 END LOOP ; 7 CLOSE c; Объявления 1 DECLARE col1, col2 INTEGER ; 2 DECLARE flag BOOLEAN DEFAULT FALSE ; 3 DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = TRUE ; 4 DECLARE c CURSOR FOR ...
  26. 26. Курсоры (2): FOR for ::= FOR name CURSOR FOR select_sql DO sp_stmt ;[...] END FOR WL#3309 “Stored procedures: FOR statement”:
  27. 27. Курсоры (3): best practices <ul><li>Курсоры в MySQL: </li></ul><ul><ul><li>всегда материализуются (temporary table)
  28. 28. asensitive
  29. 29. WITH HOLD (по умолчанию) </li></ul></ul>Поэтому: <ul><li>не используйте курсоры без необходимости </li></ul><ul><ul><li>можно обойтись SELECT ... INTO ?
  30. 30. можно обойтись INSERT ... SELECT ? </li></ul></ul><ul><li>не разменивайте мощь декларативного языка SQL на итеративную простоту SQL/PSM </li></ul>
  31. 31. Курсоры (4): anti-pattern BEGIN DECLARE done INT DEFAULT 0; DECLARE t1_input int ; DECLARE b,c,d INT ; ... DECLARE cur1 CURSOR FOR SELECT sum(input), sum(output), sum(ng), Createdate, supplier, Model FROM winding WHERE createdate=curdate() GROUP BY Createdate, supplier, Model ; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; REPEAT FETCH cur1 INTO t1_input,b,c,d,e,Model; IF NOT done THEN INSERT INTO Tevent (input,output,ng,dateh,supplier,Model ) VALUES (t1_input,b,c,d,e,Model); END IF ; UNTIL done END REPEAT ; CLOSE cur1; END
  32. 32. This page intentionally left blank.
  33. 33. SQL/PSM : инструкции sp_stmt ::= return | if | case | loop | while | repeat | leave | iterate | open | fetch | close | signal | resignal | [ label : ] BEGIN ... END Классы инструкций: <ul><li>управления ( return , if , case )
  34. 34. циклы ( loop , while , repeat , leave , iterate )
  35. 35. работа с курсорами ( open , fetch , close )
  36. 36. обработка исключений ( signal , resignal )
  37. 37. стандартный SQL и compound statements </li></ul>
  38. 38. Инструкции (2): if и case sp_if ::= IF expr THEN sp_stmt ; [...] [[ ELSEIF expr THEN sp_stmt ; [...]][...]] [ ELSE sp_stmt ; [...]] END IF sp_case ::= CASE [expr] [ WHEN expr THEN sp_stmt ; [...]][...] [ ELSE sp_stmt ; [...]] END CASE
  39. 39. Инструкции (2): if и case IF i > j THEN SET i= j; SET j=+1; ELSE BEGIN DECLARE c INT ; ... END ; END IF ; IF (i > j) THEN DECLARE c INTEGER ; ... END IF ; CASE i WHEN 1 THEN CALL p_monday(); WHEN 2 THEN CALL p_tuesday(); ELSE SIGNAL &quot; 02000 &quot; SET message_text=&quot; Error &quot;; END CASE ; CASE i WHEN i=2 THEN ... END CASE ;
  40. 40. Инструкции (2): while и repeat sp_while ::= [ label : ] WHILE expr DO sp_stmt ; [...] END WHILE sp_repeat ::= [ label : ] REPEAT sp_stmt ; [...] UNTIL expr; END REPEAT sp_iterate ::= ITERATE label sp_leave ::= LEAVE label
  41. 41. SQL/PSM: иcключения Контекст выполнения процедуры это: <ul><li>хранимые свойства
  42. 42. окружение времени выполнения
  43. 43. diagnostics area: </li></ul>SELECT f_function()-> … CALL p_proc() -> … … INSERT …
  44. 44. SQL/PSM: хранимые свойства процедуры
  45. 45. SQL/PSM: исключения (2) sp_decl ::= ... DECLARE name CONDITION FOR cond_desc | DECLARE { CONTINUE | EXIT } HANDLER FOR hand_desc sp_stmt handler_desc ::= NOT FOUND | SQLWARNING | SQLEXCEPTION | errcode | SQLSTATE [ VALUE ] &quot; sqlstate &quot; <ul><li>понимайте разницу между CONTINUE HANDLER и IGNORE
  46. 46. используйте REPLACE или INSERT … ON DUPLICATE KEY UPDATE </li></ul>
  47. 47. SQL/PSM: привилегии <ul><li>права на создание процедуры дают возможность её выполнять
  48. 48. при удалении процедуры права владельца автоматически удаляются
  49. 49. концепция INVOKER/DEFINER
  50. 50. доступ к “внешним” объектом определяется как во всём SQL
  51. 51. statement-based репликация влияет на безопасность SQL/PSM </li></ul>
  52. 52. SQL/PSM: Свойства (characteristic) characteristic ::= [ NOT * ] DETERMINISTIC | { CONTAINS | NO SQL } SQL | { MODIFIES | READS } SQL DATA | SQL SECURITY { DEFINER | INVOKER } * NOT – значение по умолчанию
  53. 53. Dynamic SQL Использование SQL PS: PREPARE name FROM &quot; sql &quot;; EXECUTE name USING @uservar[,...]; DEALLOCATE PREPARE name ; <ul><li>позволяет параметризовать имена объектов БД
  54. 54. не имеет доступа к переменным процедуры
  55. 55. временные таблицы, uservars - доступны
  56. 56. выполняется в текущей схеме
  57. 57. под credentials текущего пользователя </li></ul>
  58. 58. SQL/PSM: репликация “ Unrolling” хранимых процедур в действии: mysql> call load_daily_log(curdate()); mysql> show binlog events; <ul><li>Функции реплицируются через DO(f1())
  59. 59. Тело функции – black box для репликации
  60. 60. 5.1: используйте mixed mode
  61. 61. 5.0: используйте </li></ul>--log-bin-trust-function-creators
  62. 62. SQL/PSM (3): триггеры trg_sql ::= create | drop create ::= CREATE [ DEFINER= user ] TRIGGER name { BEFORE | AFTER } { INSERT | UPDATE | DELETE } FOR EACH ROW sp_body drop ::= DROP TRIGGER [ IF EXISTS ] name
  63. 63. SQL/PSM (3): задачи ev_sql ::= create | drop | alter create ::= CREATE [ DEFINER= user ] EVENT name ON SCHEDULE schedule DO sp_body drop ::= DROP EVENT name schedule::= AT timespec | EVERY interval [ STARTS timespec ] [ ENDS timespec ]
  64. 64. Ограничения <ul><li>везде: </li><ul><li>нет LOCK TABLES </li></ul><li>Триггеры и функции: </li><ul><li>transactional control (Implicit and Explicit)
  65. 65. нет SELECT/SHOW без курсоров
  66. 66. FLUSH statements
  67. 67. не рекурсивны
  68. 68. no cascading modifications on the same resource </li></ul></ul>
  69. 69. Ограничения и RFE <ul><li>Поддержка всех SQL комманд (CHECK TABLE!)
  70. 70. Переменные в LIMIT (есть в 5.5)
  71. 71. FOR цикл
  72. 72. более удобный синтаксис Dynamic SQL
  73. 73. Поддержка курсоров в Dynamic SQL
  74. 74. нативный отладчик
  75. 75. ... </li></ul>
  76. 76. Производительность SQL/PSM 1) Вычисления
  77. 77. Процент диаграмм похожих на Pac-man
  78. 78. Производительность SQL/PSM 2) Оптимизация коррелированного подзапроса
  79. 79. Производительность SQL/PSM 3) Простая обработка больших массивов данных
  80. 80. Производительность SQL/PSM 4) Коррелированный UPDATE
  81. 81. Спасибо! Константин Осипов [email_address]
  82. 82. Ссылки <ul><li>Guy Harrison “MySQL Stored procedures” - неплохая, но уже немного устаревшая книга о хранимых процедурах в MySQL - http://oreilly.com/catalog/mysqlspp
  83. 83. MySQL Stored Procedures FAQ - http://dev.mysql.com/doc/refman/5.5/en/faqs-stored-procs.htm
  84. 84. “ Используем хранимые процедуры” - толковый туториал для начинающих - http://www.brainbell.com/tutorials/MySQL/Using_Stored_Procedures.htm
  85. 85. Библиотека хранимых процедур и функций Giuseppe Maxia - http://www.nongnu.org/mysql-sr-lib/
  86. 86. Форумы на MySQL.com: хранимые процедуры – есть постоянная активность - http://forums.mysql.com/read.php?98,222900,222900#msg-222900
  87. 87. Кликабельная диаграмма MySQL INFORMATION_SCHEMA -- http://www.xcdsql.org/MySQL/information_schema/5.1/MySQL_5_1_INFORMATION_SCHEMA.html
  88. 88. Коммерческие дебаггеры для MySQL SQL/PSM: http://www.mydebugger.com и http://www.devart.com/dbforge/mysql/studio/code-debugger.html </li></ul>
  89. 89. Ссылки (1) Guy Harrison “MySQL Stored procedures” - неплохая, но уже немного устаревшая книга о хранимых процедурах в MySQL - http://oreilly.com/catalog/mysqlspp
  90. 90. Ссылки (2) Библиотека хранимых процедур и функций Giuseppe Maxia - http://www.nongnu.org/mysql-sr-lib/
  91. 91. Ссылки (3) Кликабельная диаграмма MySQL INFORMATION_SCHEMA -- http://www.xcdsql.org/MySQL/information_schema/5.1/MySQL_5_1_INFORMATION_SCHEMA.html
  92. 92. Ссылки (4) Коммерческий дебаггер для MySQL SQL/PSM: http://www.mydebugger.com

×