Mysql функции описание и примеры. Хранимые процедуры и триггеры

SQL - Урок 10. Встроенные функции

Функции - это операции, позволяющие манипулировать данными. В MySQL можно выделить несколько групп встроенных функций:
  • Строковые функции. Используются для управления текстовыми строками, например, для обрезания или заполнения значений.

  • Числовые функции. Используются для выполнения математических операций над числовыми данными. К числовым функциям относятся функции возвращающие абсолютные значения, синусы и косинусы углов, квадратный корень числа и т.д. Используются они только для алгебраических, тригонометрических и геометрических вычислений. В общем, используются редко, поэтому рассматривать их мы не будем. Но вы должны знать, что они существуют, и в случае необходимости обратиться к документации MySQL.

  • Итоговые функции. Используются для получения итоговых данных по таблицам, например, когда надо просуммировать какие-либо данные без их выборки.

  • Функции даты и времени. Используются для управления значениями даты и времени, например, для возвращения разницы между датами.

  • Системные функции. Возвращают служебную информацию СУБД.

Для того, чтобы рассмотреть основные встроенные функции нам понадобится создать новую базу данных, чтобы в ней были числовые значения и значения даты. В уроке 5 основ баз данных мы сделали реляционную модель базы данных интернет-магазина. Пришло время реализовать ее в MySQL, заодно закрепим пройденное.

Итак, смотрим на последнюю схему урока 5 по БД и создаем БД - shop.

Create database shop;

Выбираем ее для работы:

И создаем в ней 8 таблиц, как в схеме: Покупатели (customers), Поставщики (vendors), Покупки (sale), Поставки (incoming), Журнал покупок (magazine_sales), Журнал поставок (magazine_incoming), Товары (products), Цены (prices). Один нюанс, наш магазин будет торговать книгами, поэтому в таблицу Товары мы добавим еще один столбец - Автор (author), в принципе это необязательно, но так как-то привычнее.

create table customers (id_customer int NOT NULL AUTO_INCREMENT, name char(50) NOT NULL, email char(50) NOT NULL, PRIMARY KEY (id_customer)); create table vendors (id_vendor int NOT NULL AUTO_INCREMENT, name char(50) NOT NULL, city char(30) NOT NULL, address char(100) NOT NULL, PRIMARY KEY (id_vendor)); create table sale (id_sale int NOT NULL AUTO_INCREMENT, id_customer int NOT NULL, date_sale date NOT NULL, PRIMARY KEY (id_sale), FOREIGN KEY (id_customer) REFERENCES customers (id_customer)); create table incoming (id_incoming int NOT NULL AUTO_INCREMENT, id_vendor int NOT NULL, date_incoming date NOT NULL, PRIMARY KEY (id_incoming), FOREIGN KEY (id_vendor) REFERENCES vendors (id_vendor)); create table products (id_product int NOT NULL AUTO_INCREMENT, name char(100) NOT NULL, author char(50) NOT NULL, PRIMARY KEY (id_product)); create table prices (id_product int NOT NULL, date_price_changes date NOT NULL, price double NOT NULL, PRIMARY KEY (id_product, date_price_changes), FOREIGN KEY (id_product) REFERENCES products (id_product)); create table magazine_sales (id_sale int NOT NULL, id_product int NOT NULL, quantity int NOT NULL, PRIMARY KEY (id_sale, id_product), FOREIGN KEY (id_sale) REFERENCES sale (id_sale), FOREIGN KEY (id_product) REFERENCES products (id_product)); create table magazine_incoming (id_incoming int NOT NULL, id_product int NOT NULL, quantity int NOT NULL, PRIMARY KEY (id_incoming, id_product), FOREIGN KEY (id_incoming) REFERENCES incoming (id_incoming), FOREIGN KEY (id_product) REFERENCES products (id_product));

Обратите внимание, что в таблицах Журнал покупок, Журнал поставок и Цены первичные ключи - составные, т.е. их уникальные значения состоят из пар значений (в таблице не может быть двух строк с одинаковыми парами значений). Названия столбцов этих пар значений и указываются через запятую после ключевого слова PRIMARY KEY. Остальное вы уже знаете.

В настоящем интернет-магазине данные в эти таблицы будут заноситься посредством сценариев на каком-либо языке (типа php), нам же пока придется внести их вручную. Можете внести любые данные, только помните, что значения в одноименных столбцах связанных таблиц должны совпадать. Либо скопируйте нижеприведенные данные:

INSERT INTO vendors (name, city, address) VALUES ("Вильямс", "Москва", "ул.Лесная, д.43"), ("Дом печати", "Минск", "пр.Ф.Скорины, д.18"), ("БХВ-Петербург", "Санкт-Петербург", "ул.Есенина, д.5"); INSERT INTO customers (name, email) VALUES ("Иванов Сергей", "[email protected]"), ("Ленская Катя", "[email protected]"), ("Демидов Олег", "[email protected]"), ("Афанасьев Виктор", "[email protected]"), ("Пажская Вера", "[email protected]"); INSERT INTO products (name, author) VALUES ("Стихи о любви", "Андрей Вознесенский"), ("Собрание сочинений, том 2", "Андрей Вознесенский"), ("Собрание сочинений, том 3", "Андрей Вознесенский"), ("Русская поэзия", "Николай Заболоцкий"), ("Машенька", "Владимир Набоков"), ("Доктор Живаго", "Борис Пастернак"), ("Наши", "Сергей Довлатов"), ("Приглашение на казнь", "Владимир Набоков"), ("Лолита", "Владимир Набоков"), ("Темные аллеи", "Иван Бунин"), ("Дар", "Владимир Набоков"), ("Сын вождя", "Юлия Вознесенская"), ("Эмигранты", "Алексей Толстой"), ("Горе от ума", "Александр Грибоедов"), ("Анна Каренина", "Лев Толстой"), ("Повести и рассказы", "Николай Лесков"), ("Антоновские яблоки", "Иван Бунин"), ("Мертвые души", "Николай Гоголь"), ("Три сестры", "Антон Чехов"), ("Беглянка", "Владимир Даль"), ("Идиот", "Федор Достоевский"), ("Братья Карамазовы", "Федор Достоевский"), ("Ревизор", "Николай Гоголь"), ("Гранатовый браслет", "Александр Куприн"); INSERT INTO incoming (id_vendor, date_incoming) VALUES ("1", "2011-04-10"), ("2", "2011-04-11"), ("3", "2011-04-12"); INSERT INTO magazine_incoming (id_incoming, id_product, quantity) VALUES ("1", "1", "10"), ("1", "2", "5"), ("1", "3", "7"), ("1", "4", "10"), ("1", "5", "10"), ("1", "6", "8"), ("1", "18", "8"), ("1", "19", "8"), ("1", "20", "8"), ("2", "7", "10"), ("2", "8", "10"), ("2", "9", "6"), ("2", "10", "10"), ("2", "11", "10"), ("2", "21", "10"), ("2", "22", "10"), ("2", "23", "10"), ("2", "24", "10"), ("3", "12", "10"), ("3", "13", "10"), ("3", "14", "10"), ("3", "15", "10"), ("3", "16", "10"), ("3", "17", "10"); INSERT INTO prices (id_product, date_price_changes, price) VALUES ("1", "2011-04-10", "100"), ("2", "2011-04-10", "130"), ("3", "2011-04-10", "90"), ("4", "2011-04-10", "100"), ("5", "2011-04-10", "110"), ("6", "2011-04-10", "85"), ("7", "2011-04-11", "95"), ("8", "2011-04-11", "100"), ("9", "2011-04-11", "79"), ("10", "2011-04-11", "49"), ("11", "2011-04-11", "105"), ("12", "2011-04-12", "85"), ("13", "2011-04-12", "135"), ("14", "2011-04-12", "100"), ("15", "2011-04-12", "90"), ("16", "2011-04-12", "75"), ("17", "2011-04-12", "90"), ("18", "2011-04-10", "150"), ("19", "2011-04-10", "140"), ("20", "2011-04-10", "85"), ("21", "2011-04-11", "105"), ("22", "2011-04-11", "70"), ("23", "2011-04-11", "65"), ("24", "2011-04-11", "130"); INSERT INTO sale (id_customer, date_sale) VALUES ("2", "2011-04-11"), ("3", "2011-04-11"), ("5", "2011-04-11"); INSERT INTO magazine_sales (id_sale, id_product, quantity) VALUES ("1", "1", "1"), ("1", "5", "1"), ("1", "7", "1"), ("2", "2", "1"), ("3", "1", "1"), ("3", "7", "1");

Итак, в нашем магазине 24 наименования товара, привезенные в трех поставках от трех поставщиков, и совершенно три продажи. Все готово, можем приступать к изучению встроенных функций MySQL, чем и займемся в следующем уроке.

■ В MySQL предлагает широкий выбор встроенных операторов и функций, которые могут оказаться полезными при создании запросов. Большинство этих функций предназначено для использования в выражениях SELECT и WHERE. Существуют также некоторые специальные функции группировки для использования в выра­жении GROUP BY. Число доступных для использо­вания функций очень велико, поэтому мы рассмотрим только наиболее полезные из них.

Здесь следует сделать одно важное замечание . В MySQL любое выражение, содержащее NULL, оценивается как NULL.

Операторы

В MySQL используются три главных типа операторов: знаки арифметических операций, операторы сравнения и логические операторы . Арифметические операции

В MySQL используются обычные арифметические операции: сложение (+), вычитание (-), умножение (*) и деление (/). Деление на нулевое значение дает безопасный результат NULL.

Операторы сравнения

При работе с операторами сравнения необходимо помнить о том, что, за ис­ключением нескольких особо оговариваемых случаев, сравнение чего-либо со зна­чением NULL дает в результате NULL.

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




Типы таблиц MySQL

Проектирование системы управления базой данных, подобно многим другим задачам проектирования, подразумевает множество компромиссных решений. На­пример, многие задачи базы данных должны обеспечиваться решениями, предпо­лагающими безопасность транзакций, но такие решения требуют больше времени для их выполнения, больше дискового пространства и памяти. Создатели MySQL делегировали выбор некоторых из компромиссных решений вам, разработчику базы данных, предложив на выбор несколько типов таблиц. В зависимости от при­ложения вы можете выбрать один из типов таблиц, обеспечивающих безопасность транзакций, или же с помощью другого типа обеспечить более высокую произво­дительность, не гарантируя безопасность транзакций. Так или иначе, необходимо знать, какие компромиссы вы при этом допускаете.

Вы уже могли обратить внимание, что типы таблиц мы называли механизмами хранения. Это отражает тот факт, что некоторые из типов таблиц используют большие самостоятельные фрагменты программного кода со своими системами кэширования, индексации, блокировки и доступа к диску. Это отражает также суть назначения базы данных: хранение информации.

Представьте на минуту, что вы имеете дело с базой данных, содержащей ин­формацию о банковских счетах. Если необходимо перевести 1000 долларов с од­ного счета на другой, вам потребуется как минимум два запроса SQL: один, чтобы снять 1000 долларов с одного счета, и еще один, чтобы добавить 1000 долларов ко второму счету. Существует опасность (например, в случае отключения элек­тропитания), что один запрос завершит свою работу, а второй - нет. Было бы очень желательно, чтобы в подобных случаях завершиться успешно могли либо оба из пары запросов, либо ни один из них, чтобы данные в базе данных остались согласованными.

Чтобы обеспечить безопасность транзакций, таблицы должны предусматри­вать возможность указания того, что некоторый набор запросов должен тракто­ваться как одна неделимая единица - транзакция . Транзакция должна либо завер­шиться полностью, либо база данных должна выполнить откат, т.е. возвратиться к тому же состоянию, которое имело место до начала выполнения транзакции.

К типам таблиц, доступных в MySQL, относятся следующие:

■ BerkeleyDB (BDB)

Безопасность транзакций обеспечивают таблицы InnoDB и BerkeleyDB. Остальные (ISAM, MylSAM, MERGE и HEAP) безопасность транзакций не обеспечивают.

Таблицы ISAM

Таблицы ISAM включены в MySQL исключительно для поддержки совмести­мости. Их функциональные возможности полностью поддерживаются таблицами MyISAM.

Таблицы ISAM предлагают быстрый, но не защищенный с точки зрения тран­закций, механизм хранения данных. Практически все, что можно сказать о табли­цах ISAM, будет верно и для таблиц MyISAM, но относящиеся к более старому стандарту таблицы ISAM имеют ряд ограничений.

Улучшения, предложенные в таблицах MyISAM, включают следующее.

■ Мобильность таблиц. Таблицы, сохраненные на диске или другом носителе, можно загрузить в другую систему, поддерживающую MySQL, независимо от платформы. Для таблиц ISAM это не так.

■ Поддержка очень больших таблиц. Размеры таблицы ISAM имеют жесткое ограничение - 4 Гбайт. MyISAM позволяет создавать таблицы настолько большие, насколько большими им позволяет быть операционная система, в которой выполняется MySQL. Это может оказаться важным небольшому числу пользователей, но это означает, что к выбору операционной (и фай­ловой) системы следует отнестись весьма внимательно. Многие файловые системы имеют ограничение 2 Гбайт для размера файла. (Обратите вни­мание на то, что это ограничение можно на самом деле обойти, используя таблицы MERGE.)



■ Более эффективное использование дискового пространства. Сокращен объ­ем пустого пространства и уменьшена фрагментация.

■ Меньшие ограничения на ключи. Таблицы ISAM допускают использование 16 ключей на таблицу и максимальную длину ключа по умолчанию 256 байт. Таблицы MyISAM допускают 64 ключа на таблицу и максимальную длину ключа по умолчанию 1024 байт.

Таблицы ISAM должны восприниматься как нежелательные.

Таблицы MyISAM

Таблицы MyISAM обеспечивают очень быстрый, но не защищенный с точки зрения транзакций, механизм хранения данных. Они обеспечивают высокую про­изводительность в большинстве ситуаций даже при наличии ошибок в структуре базы данных

Таблицы MyISAM могут быть одного из трех типов: динамические, стати­ческие или сжатые . Таблица автоматически становится динамической или ста­тической в зависимости от определения ее столбцов. Сжатые таблицы должны создаваться специально с помощью средства myisampack.

Таблицы со строками фиксированной длины будут статическими, а таблицы со строками переменной длины - динамическими.

Статическая таблица имеет целый ряд преимуществ. Она обеспечивает бо­лее быстрый поиск по сравнению с динамической или сжатой таблицей. Для базы данных очень легко извлечь конкретную запись на основе индекса, когда каждая запись находится на определенном расстоянии от начала файла. Данные проще кэшировать. Менее вероятно возникновение серьезных повреждений в слу­чае отказа системы - возможности восстановления данных, как правило, легко обеспечивают восстановление всех строк, кроме одной поврежденной.

Недостатком статических таблиц является то, что размещение реальных дан­ных в столбцах фиксированного размера, очевидно, не способствует экономии дискового пространства. Это может быть не слишком большой ценой для данных варьирующих в небольших пределах (например, для имен пользователей), но мо­жет оказаться неприемлемым для данных, которые сильно варьируют в размерах.

Динамические таблицы в рамках MySQL требуют более сложных методов управления. В этом случае и кэширование, и поиск, и восстановление записей для механизма хранения оказываются не такими простыми задачами. Причиной отчасти является то, что данные варьируют в размерах, но также и то, что они могут оказаться фрагментированными. Если строка изменяется и становится боль­ше, часть данных останется на исходном месте, а часть может сохраниться в виде нового фрагмента где-нибудь в другом месте файла. Это значит, что сегмент фай­ла, помещенный в кэш операционной системой, не обязательно будет содержать все части соответствующей строки. Могут возникнуть трудности и при восста­новлении повреждений, поскольку в случае потери фрагментов или ссылок будет совсем не очевидно, каким строкам должны принадлежать распознанные части данных.

Таблицы InnoDB

Следующим типом таблиц, который мы будем обсуждать, является тип InnoDB. Данный тип представляет собой механизм хранения, обеспечивающий быструю работу и безопасность транзакций. Таблицы InnoDB предлагают следующие возможности.

■Транзакции.

■Блокировка на уровне строк. Это означает, что при выполнении запроса недоступной для других пользователей будет только строка, используемая в данном запросе. Большинство других механизмов хранения (за исключе­нием BDB) предлагает блокировку на уровне таблиц - пока один процесс обновляет таблицу, таблица не доступна другим процессам.

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

■Согласованное неблокирующее чтение в операторах SELECT. (Эта идея позаимствована из Oracle.)

Механизм InnoDB имеет свои собственные опции настройки, отдельный ката­лог и свои особенности хранения данных. В то время как механизм MyISAM для хранения каждой таблицы использует отдельный файл, механизм InnoDB хранит все таблицы и индексы в специальном пространстве таблиц, и это означает, что содержимое одной таблицы может размещаться в нескольких файлах. Это дает возможность механизму InnoDB создавать очень большие таблицы, которые не обязаны подчиняться каким-либо ограничениям на размеры файлов, налагаемым операционной системой. Однако, следует учитывать то, что для хранения одного и того же объема полезной информации таблицы InnoDB используют значительно больше дискового пространства, чем таблицы MylSAM.

InnoDB является одной из самых быстрых систем, обеспечивающих безопас­ность транзакций, но обеспечение этой безопасности требует жертв. Для большин­ства реальных сценариев таблицы MyISAM будут быстрее, но разница, в общем, не будет слишком впечатляющей.


Тема 5. Язык HTML как средство внешнего представления данных .

Несмотря на то, что в настоящее время существует огромное количество программных продуктов, которые позволяют создавать сайты в режиме "What you see and what you get" (Что видите, то и получаете), после сохранения документа в качестве web-страницы получается html файл. HTML файл - это обычный текстовый документ, который может быть написан в любом текстовом редакторе (например, блокнот) и сохранён с расширением *.htm или *.html. Многие программы, которые позволяют создавать сайты по готовым шаблонам, имеют встроенный html редактор. Знание html необходимо для более полного контроля всех элементов, которые располагаются на вашей странице (текст, рисунки, таблицы, flash эффекты, java аплеты…), а также для внесения каких-либо исправлений в ходе обслуживания сайта.

HTML (HyperText Markup Language)- язык гипертекстовой разметки. Он позволяет:-публиковать электронные документы с заголовками, текстом, таблицами, списками, фотографиями и т.д. в сети интернет;

Загружать электронную информацию с помощью щелчка мыши на гипертекстовой ссылке;

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

Включать электронные таблицы, видеоклипы, звуковые фрагменты и другие приложения непосредственно в документы

Внимание! Данная работа построена на основе перевода раздела «17.1. Stored Routines and the Grant Tables» описания ПО MySQL 5.0.19, «Reference Manual. It documents MySQL 5.0 through 5.0.19. Document generated on: 2006-01-23 (revision:995)»
``Сначала прочти все, а потом пробуй примеры"

Хранимые процедуры представляют собой набор команд SQL, которые могут компилироваться и храниться на сервере. Таким образом, вместо того, чтобы хранить часто используемый запрос, клиенты могут ссылаться на соответствующую хранимую процедуру. Это обеспечивает лучшую производительность, поскольку данный запрос должен анализироваться только однажды и уменьшается трафик между сервером и клиентом. Концептуальный уровень можно также повысить за счет создания на сервере библиотеки функций.

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

Хранимые программы (процедуры и функции) поддерживаются в MySQL 5.0. Хранимые процедуры - набор SQL -выражений, который может быть сохранен на сервере. Как только это сделано, клиенту уже не нужно повторно передавать запрос, а требуется просто вызвать хранимую программу.

Это может быть полезным тогда, когда:

  • многочисленные приложения клиента написаны в разных языках или работают на других платформах, но нужно использовать ту же базу данных операций
  • безопасность на 1 месте

Хранимые процедуры и функции (подпрограммы) могут обеспечить лучшую производительность потому, что меньше информации требуется для пересылки между клиентом и сервером. Выбор увеличивает нагрузку на сервер БД, но снижает затраты на стороне клиента. Используйте это, если много клиентских машин (таких как Веб-серверы) обслуживаются одной или несколькими БД.

Хранимые подпрограммы также позволяют вам использовать библиотеки функций, хранимые в БД сервера. Эта возможность представлена для многих современных языков программирования, которые позволяют вызывать их непосредственно (например, используя классы).

MySQL следует в синтаксисе за SQL:2003 для хранимых процедур, который уже используется в IBM"s DB2.

От слов к делу…

При создании, модификации, удалении хранимых подпрограмм сервер манипулирует с таблицей mysql.proc

Начиная с MySQL 5.0.3 требуются следующие привилегии:

CREATE ROUTINE для создания хранимых процедур

ALTER ROUTINE необходимы для изменения или удаления процедур. Эта привилегия автоматически назначается создателю процедуры (функции)

EXECUTE привилегия потребуется для выполнения подпрограммы. Тем не менее, автоматически назначается создателю процедуры (функции). Также, по умолчанию, SQL SECURITY параметр для подпрограммы DEFINER , который разрешает пользователям, имеющим доступ к БД вызывать подпрограммы, ассоциированные с этой БД.

Синтаксис хранимых процедур и функций

Хранимая подпрограмма представляет собой процедуру или функцию. Хранимые подпрограммы создаются с помощью выражений CREATE PROCEDURE или CREATE FUNCTION . Хранимая подпрограмма вызывается, используя выражение CALL , причем только возвращающие значение переменные используются в качестве выходных. Функция может быть вызвана подобно любой другой функции и может возвращать скалярную величину. Хранимые подпрограммы могут вызывать другие хранимые подпрограммы.

Начиная с MySQL 5.0.1, загруженная процедура или функция связана с конкретной базой данных. Это имеет несколько смыслов:

  • Когда подпрограмма вызывается, то подразумевается, что надо произвести вызов USE db_name (и отменить использование базы, когда подпрограмма завершилась, и база больше не потребуется)
  • Вы можете квалифицировать обычные имена с именем базы данных. Это может быть использовано, чтобы ссылаться на подпрограмму, которая - не в текущей базе данных. Например, для выполнения хранимой процедуры p или функции f которые связаны с БД test , вы можете сказать интерпретатору команд так: CALL test.p() или test.f() .
  • Когда база данных удалена, все загруженные подпрограммы связанные с ней тоже удаляются. В MySQL 5.0.0, загруженные подпрограммы - глобальные и не связанны с базой данных. Они наследуют по умолчанию базу данных из вызывающего оператора. Если USE db_name выполнено в пределах подпрограммы, оригинальная текущая БД будет восстановлена после выхода из подпрограммы (Например текущая БД db_11 , делаем вызов подпрограммы, использующей db_22 , после выхода из подпрограммы остается текущей db_11)

MySQL поддерживает полностью расширения, которые разрешают юзать обычные SELECT выражения (без использования курсоров или локальных переменных) внутри хранимых процедур. Результирующий набор, возвращенный от запроса, а просто отправляется напрямую клиенту. Множественный SELECT запрос генерирует множество результирующих наборов, поэтому клиент должен использовать библиотеку, поддерживающую множественные результирующие наборы.

CREATE PROCEDURE - создать хранимую процедуру.

CREATE FUNCTION - создать хранимую функцию.

Синтаксис:

CREATE PROCEDURE имя_процедуры ([параметр_процедуры[,...]])
[характеристёика...] тело_подпрограммы

CREATE FUNCTION имя_функции ([параметр_функции[,...]])
RETURNS тип
[характеристика...] тело_подпрограммы

параметр_процедуры:
[ IN | OUT | INOUT ] имя_параметра тип
параметр_функции:
имя_параметра тип

тип:
Любой тип данных MySQL

характеристика:
LANGUAGE SQL
| DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT "string"

тело_подпрограммы:
Правильное SQL выражение.

Рассмотрим все на практике.

Сначала создадим хранимую процедуру следующим запросом:

CREATE PROCEDURE `my_proc`(OUT t INTEGER(11))
NOT DETERMINISTIC
SQL SECURITY INVOKER
COMMENT ""
BEGIN
select val1+val2 into "t" from `my` LIMIT 0,1;
END;

Применение выражения LIMIT в этом запросе сделано из соображений того, что не любой клиент способен принять многострочный результирующий набор.

После этого вызовем ее:

CALL my_proc(@a);
SELECT @a;

Для отделения внутреннего запроса от внешнего всегда используют разделитель отличный от обычно (для задания используют команду DELIMITER <строка/символ>)

Вот еще один пример с учетом всех требований.

Mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END;
-> //

mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)

Весь процесс можно пронаблюдать на рисунке ниже:

Триггеры

Поддержка триггеров появилась в MySQL начиная с версии 5.0.2.

Триггер - поименованный объект БД, который ассоциирован с таблицей и активируемый при наступлении определенного события, события связанного с этой таблицей.

Например, нижеприведенный код создает таблицу и INSERT триггер. Триггер суммирует значения, вставляемые в один из столбцов таблицы.

Mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
-> FOR EACH ROW SET @sum = @sum + NEW.amount;
Query OK, 0 rows affected (0.06 sec)

Объявим переменную sum и присвоим ей значение 1. После этого при каждой вставке в таблицу account значение этой переменной будет увеличивать согласно вставляемой части.

Замечание . Если значение переменной не инициализировано, то триггер работать не будет!

Синтаксис создания триггера

CREATE

TRIGGER имя_триггера время_триггера событие_срабатывания_триггера
ON имя_таблицы FOR EACH ROW выражение_выполняемое_при_срабатывании_триггера

Если с именем триггера и именем пользователя все понятно сразу, то о «времени триггера» и «событии» поговорим отдельно.

время_триггера

Определяет время свершения действия триггера. BEFORE означает, что триггер выполнится до завершения события срабатывания триггера, а AFTER означает, что после. Например, при вставке записей (см. пример выше) наш триггер срабатывал до фактической вставки записи и вычислял сумму. Такой вариант уместен при предварительном вычислении каких-то дополнительных полей в таблице или параллельной вставке в другую таблицу.

событие_срабатывания_триггера

Здесь все проще. Тут четко обозначается, при каком событии выполняется триггер.

  • INSERT: т.е. при операциях вставки или аналогичных ей выражениях (INSERT, LOAD DATA, и REPLACE)
  • UPDATE: когда сущность (строка) модифицирована
  • DELETE: когда запись удаляется (запросы, содержащие выражения DELETE и/или REPLACE)

3.1 дПВБЧМЕОЙЕ ОПЧЩИ ЖХОЛГЙК Ч MySQL

еУФШ ДЧБ УРПУПВБ ДПВБЧЙФШ ОПЧХА ЖХОЛГЙА Ч MySQL:

  • чЩ НПЦЕФЕ ДПВБЧЙФШ ЖХОЛГЙА ЮЕТЕЪ НЕИБОЙЪН ПРТЕДЕМСЕНЩИ РПМШЪПЧБФЕМЕН ЖХОЛГЙК (user-definable function, UDF). пОЙ ДПВБЧМСАФУС ДЙОБНЙЮЕУЛЙ, ЙУРПМШЪХС ЛПНБОДЩ CREATE FUNCTION Й DROP FUNCTION . рПДТПВОПУФЙ Ч ТБЪДЕМЕ " ".
  • чЩ НПЦЕФЕ ДПВБЧЙФШ ЖХОЛГЙА ЛБЛ ЧОХФТЕООАА Ч MySQL. фБЛЙЕ ЖХОЛГЙЙ ЛПНРЙМЙТХАФУС РТСНП ЧОХФТШ УЕТЧЕТБ mysqld Й УФБОПЧСФУС ДПУФХРОЩНЙ ОБ РПУФПСООПК ПУОПЧЕ.

лБЦДЩК НЕФПД ЙНЕЕФ УЧПЙ РТПВМЕНЩ:

  • еУМЙ чЩ РЙЫЕФЕ ПРТЕДЕМСЕНХА РПМШЪПЧБФЕМЕН ЖХОЛГЙА, чЩ ДПМЦОЩ ХУФБОПЧЙФШ ПВЯЕЛФОЩК ЖБКМ Ч ДПРПМОЕОЙЕ Л УЕТЧЕТХ. еУМЙ чЩ ЛПНРЙМЙТХЕФЕ чБЫХ ЖХОЛГЙА РТСНП Ч УЕТЧЕТ, чЩ ОЕ ДПМЦОЩ ДЕМБФШ ЬФПЗП.
  • чЩ НПЦЕФЕ ДПВБЧМСФШ UDF Л ДЧПЙЮОПНХ ДЙУФТЙВХФЙЧХ MySQL. чУФТПЕООЩЕ ЖХОЛГЙЙ ФТЕВХАФ, ЮФПВЩ чЩ ЙЪНЕОЙМЙ ЙУИПДОЙЛЙ.
  • еУМЙ чЩ ПВОПЧМСЕФЕ MySQL, чЩ НПЦЕФЕ РТПДПМЦБФШ ЙУРПМШЪПЧБФШ чБЫ РТЕДЧБТЙФЕМШОП ХУФБОПЧМЕООЩК UDF. дМС ЧУФТПЕООЩИ ЖХОЛГЙК чЩ ДПМЦОЩ РПЧФПТЙФШ НПДЙЖЙЛБГЙЙ ЛБЦДЩК ТБЪ, ЛПЗДБ чЩ ДЕМБЕФЕ БРЗТЕКД.

оЕЪБЧЙУЙНП ПФ НЕФПДБ, ЛПФПТЩК чЩ ЙУРПМШЪХЕФЕ, ЮФПВЩ ДПВБЧЙФШ ОПЧЩЕ ЖХОЛГЙЙ, ПОЙ НПЗХФ ЙУРПМШЪПЧБФШУС ФПЮОП ФБЛ ЦЕ ЛБЛ НЕУФОЩЕ ЖХОЛГЙЙ ФЙРБ ABS() ЙМЙ SOUNDEX() .

3.1.1 уЙОФБЛУЙУ CREATE FUNCTION/DROP FUNCTION

CREATE FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name

пРТЕДЕМСЕНЩЕ РПМШЪПЧБФЕМЕН ЖХОЛГЙЙ (user-definable function, UDF) РТЕДУФБЧМСАФ УПВПК УРПУПВ ТБУЫЙТЙФШ MySQL ОПЧПК ЖХОЛГЙЕК, ЛПФПТБС ТБВПФБЕФ РПДПВОП НЕУФОЩН (ЧУФТПЕООЩН) ЖХОЛГЙСН MySQL ФЙРБ ABS() ЙМЙ CONCAT() .

AGGREGATE ОПЧБС ПРГЙС ДМС MySQL Version 3.23. жХОЛГЙС У AGGREGATE ТБВПФБЕФ ФПЮОП ФБЛ ЦЕ, ЛБЛ Й ЧУФТПЕООБС ЖХОЛГЙС GROUP , РПДПВОП SUM ЙМЙ COUNT() .

CREATE FUNCTION УПИТБОСЕФ ЙНС ЖХОЛГЙЙ, ФЙР Й ПВЭЕДПУФХРОПЕ ВЙВМЙПФЕЮОПЕ ЙНС Ч ФБВМЙГЕ mysql.func УЙУФЕНЩ. чЩ ДПМЦОЩ ЙНЕФШ РТЙЧЙМЕЗЙЙ insert Й delete ДМС ВБЪЩ ДБООЩИ mysql , ЮФПВЩ УПЪДБЧБФШ Й ХДБМСФШ ЖХОЛГЙЙ.

чУЕ БЛФЙЧОЩЕ ЖХОЛГЙЙ РЕТЕЪБЗТХЦБАФУС РТЙ ЛБЦДПН ЪБРХУЛЕ УЕТЧЕТБ, ЕУМЙ чЩ ОЕ ЪБРХУЛБЕФЕ mysqld У ПРГЙЕК --skip-grant-tables . ч ЬФПН УМХЮБЕ ЙОЙГЙБМЙЪБГЙС РТПРХЭЕОБ, Й UDF УФБОХФ ОЕДПУФХРОЩ. бЛФЙЧОБС ЖХОЛГЙС РТЕДУФБЧМСЕФ УПВПК ФБЛХА ЖХОЛГЙА, ЛПФПТБС ВЩМБ ЪБЗТХЦЕОБ У РПНПЭША CREATE FUNCTION , ОП ОЕ ВЩМБ ХДБМЕОБ ЮЕТЕЪ ЧЩЪПЧ DROP FUNCTION .

рП РПЧПДХ РТБЧЙМ ОБРЙУБОЙС ПРТЕДЕМСЕНЩИ РПМШЪПЧБФЕМЕН ЖХОЛГЙК ПФУЩМБА чБУ Л ТБЪДЕМХ "3.1 дПВБЧМЕОЙЕ ОПЧПК ЖХОЛГЙЙ, ПРТЕДЕМСЕНПК РПМШЪПЧБФЕМЕН Ч MySQL ". дМС ТБВПФЩ НЕИБОЙЪНБ UDF ЖХОЛГЙЙ ДПМЦОЩ ВЩФШ ОБРЙУБОЩ ОБ C ЙМЙ C++, чБЫБ ПРЕТБГЙПООБС УЙУФЕНБ ДПМЦОБ РПДДЕТЦЙЧБФШ ДЙОБНЙЮЕУЛХА ЪБЗТХЪЛХ, Й mysqld ДПМЦЕО ВЩФШ ПФЛПНРЙМЙТПЧБО ДЙОБНЙЮЕУЛЙ (ОЕ УФБФЙЮЕУЛЙ).

3.1.2 дПВБЧМЕОЙЕ ОПЧПК ЖХОЛГЙЙ, ПРТЕДЕМСЕНПК РПМШЪПЧБФЕМЕН

дМС ТБВПФЩ НЕИБОЙЪНБ UDF ЖХОЛГЙЙ ДПМЦОЩ ВЩФШ ОБРЙУБОЩ ОБ C ЙМЙ C++, Б чБЫБ ПРЕТБГЙПООБС УЙУФЕНБ ДПМЦОБ РПДДЕТЦЙЧБФШ ДЙОБНЙЮЕУЛХА ЪБЗТХЪЛХ. дЙУФТЙВХФЙЧ ЙУИПДОЙЛПЧ MySQL ЧЛМАЮБЕФ ЖБКМ sql/udf_example.cc , ЛПФПТЩК ПРТЕДЕМСЕФ 5 ОПЧЩИ ЖХОЛГЙК. лПОУХМШФЙТХКФЕУШ У ЬФЙН ЖБКМПН, ЮФПВЩ ЧЙДЕФШ, ЛБЛ ТБВПФБАФ УПЗМБЫЕОЙС П ЧЩЪПЧБИ UDF.

юФПВЩ mysqld НПЗ ЙУРПМШЪПЧБФШ UDF, чЩ ДПМЦОЩ ЛПОЖЙЗХТЙТПЧБФШ MySQL У ПРГЙЕК --with-mysqld-ldflags=-rdynamic . рТЙЮЙОБ ЬФПЗП Ч ФПН, ЮФП ОБ НОПЗЙИ РМБФЖПТНБИ (ЧЛМАЮБС Linux) чЩ НПЦЕФЕ ЪБЗТХЦБФШ ДЙОБНЙЮЕУЛХА ВЙВМЙПФЕЛХ (ЧЩЪПЧПН dlopen()) ЙЪ УФБФЙЮЕУЛЙ УЛПНРПОПЧБООПК РТПЗТБННЩ, ЛПФПТБС УПВТБОБ У ПРГЙЕК --with-mysqld-ldflags=-all-static , ОП ЕУМЙ чЩ ИПФЙФЕ ЙУРПМШЪПЧБФШ UDF, ЛПФПТЩК ДПМЦЕО ПВТБФЙФШУС Л УЙНЧПМБН ЙЪ mysqld (РПДПВОП РТЙНЕТХ methaphone Ч sql/udf_example.cc , ЛПФПТЩК ЙУРПМШЪХЕФ default_charset_info), чЩ ДПМЦОЩ ЛПНРПОПЧБФШ РТПЗТБННХ У -rdynamic . рПДТПВОПУФЙ ОБ man dlopen .

дМС ЛБЦДПК ЖХОЛГЙЙ, ЛПФПТХА чЩ ИПФЙФЕ ЙУРПМШЪПЧБФШ Ч ЙОУФТХЛГЙСИ SQL, чЩ ДПМЦОЩ ПРТЕДЕМЙФШ УППФЧЕФУФЧХАЭХА ЖХОЛГЙА ОБ C ЙМЙ ОБ C++. ч ПВУХЦДЕОЙЙ ОЙЦЕ ЙНС ``xxx"" ЙУРПМШЪХЕФУС ДМС ЙНЕОЙ ЖХОЛГЙЙ РТЙНЕТБ. ъДЕУШ XXX() (ЧЕТИОЙК ТЕЗЙУФТ) ХЛБЪЩЧБЕФ SQL-ПВТБЭЕОЙЕ Л ЖХОЛГЙЙ, Й xxx() (ОЙЦОЙК ТЕЗЙУФТ) ХЛБЪЩЧБЕФ C/C++-ПВТБЭЕОЙЕ Л ЖХОЛГЙЙ.

жХОЛГЙЙ, ЛПФПТЩЕ чЩ РЙЫЕФЕ ОБ C/C++ ДМС ТЕБМЙЪБГЙЙ ЙОФЕТЖЕКУБ У XXX() :

Xxx() (ПВСЪБФЕМШОБ) пУОПЧОБС ЖХОЛГЙС. ьФП ФП НЕУФП, ЗДЕ ЖХОЛГЙПОБМШОЩК ТЕЪХМШФБФ ЧЩЮЙУМЕО. уППФЧЕФУФЧЙЕ НЕЦДХ ФЙРПН SQL Й ФЙРПН ЧПЪЧТБФБ чБЫЕК ЖХОЛГЙЙ ОБ C/C++ РПЛБЪЩЧБЕФУС ОЙЦЕ:

SQL-ФЙР C/C++-ФЙР
STRING char *
INTEGER long long
REAL double
xxx_init() (ПРГЙПОБМШОБ) жХОЛГЙС ЙОЙГЙБМЙЪБГЙЙ ДМС xxx() . ьФП НПЦЕФ ЙУРПМШЪПЧБФШУС ДМС:
  • рТПЧЕТЛЙ ЮЙУМБ РБТБНЕФТПЧ XXX() .
  • рТПЧЕТЛЙ, ЮФП РБТБНЕФТЩ ЙНЕАФ ФТЕВХЕНЩК ФЙР ЙМЙ ЧЩДБЮЙ РТЕДРЙУБОЙС, ЮФПВЩ MySQL РТЙОХДЙФЕМШОП РТЙЧЕМ РБТБНЕФТЩ Л ФЙРБН, ЛПФПТЩЕ чЩ ИПФЙФЕ ЙНЕФШ, ЛПЗДБ ПУОПЧОБС ЖХОЛГЙС ЧЩЪЧБОБ.
  • тБУРТЕДЕМЕОЙС МАВПК РБНСФШ, ФТЕВХЕНПК ДМС ПУОПЧОПК ЖХОЛГЙЙ.
  • пРТЕДЕМЕОЙС НБЛУЙНБМШОПК ДМЙОЩ ТЕЪХМШФБФБ.
  • хЛБЪБОЙС (ДМС ЖХОЛГЙК ФЙРБ REAL) НБЛУЙНБМШОПЗП ЛПМЙЮЕУФЧБ ДЕУСФЙЮОЩИ ЮЙУЕМ.
  • хЛБЪБОЙС ФПЗП, НПЦЕФ ЙМЙ ОЕФ ТЕЪХМШФБФ ВЩФШ NULL .
xxx_deinit() (ПРГЙПОБМШОП) жХОЛГЙС ДЕЙОЙГЙБМЙЪБГЙЙ ДМС xxx() . ьФП ДПМЦОП ПУЧПВПДЙФШ МАВХА РБНСФШ, ТБУРТЕДЕМЕООХА ЖХОЛГЙЕК ЙОЙГЙБМЙЪБГЙЙ.

лПЗДБ ЙОУФТХЛГЙС SQL ЧЩЪЩЧБЕФ XXX() , MySQL ЧЩЪЩЧБЕФ ЖХОЛГЙА ЙОЙГЙБМЙЪБГЙЙ xxx_init() , ЮФПВЩ РПЪЧПМЙФШ ЕК ЧЩРПМОЙФШ МАВХА ФТЕВХЕНХА ОБУФТПКЛХ, ФЙРБ РТПЧЕТЛЙ РБТБНЕФТБ ЙМЙ ТБУРТЕДЕМЕОЙС РБНСФЙ. еУМЙ xxx_init() ЧПЪЧТБЭБЕФ ПЫЙВЛХ, ЙОУФТХЛГЙС SQL ВХДЕФ РТЕТЧБОБ У УППВЭЕОЙЕН ПВ ПЫЙВЛЕ, РТЙЮЕН ЗМБЧОБС Й ДЕЙОЙГЙБМЙЪБГЙПООБС ЖХОЛГЙЙ ОЕ ВХДХФ ЧЩЪЧБОЩ, ЮФП УФПЙФ ЙНЕФШ Ч ЧЙДХ РТЙ ТБУРТЕДЕМЕОЙЙ РБНСФЙ. йОБЮЕ ПУОПЧОБС ЖХОЛГЙС xxx() ВХДЕФ ЧЩЪЧБОБ ПДЙО ТБЪ ДМС ЛБЦДПК УФТПЛЙ. рПУМЕ ФПЗП, ЛБЛ ЧУЕ УФТПЛЙ ВЩМЙ ПВТБВПФБОЩ, ЧЩЪЩЧБЕФУС ЖХОЛГЙС xxx_deinit() , ФБЛ ЮФП ПОБ НПЦЕФ ЧЩРПМОЙФШ ФТЕВХЕНХА ПЮЙУФЛХ.

чУЕ ЖХОЛГЙЙ ДПМЦОЩ ВЩФШ ВЕЪПРБУОЩ ДМС РПФПЛПЧ (ОЕ ФПМШЛП ПУОПЧОБС ЖХОЛГЙС, ОП Й ПУФБМШОЩЕ: ЙОЙГЙБМЙЪБГЙС Й ДЕЙОЙГЙБМЙЪБГЙС ЙДХФ Ч РПФПЮОПН ТЕЦЙНЕ!). ьФП ПЪОБЮБЕФ, ЮФП чБН ОЕ РПЪЧПМСФ ТБУРТЕДЕМЙФШ МАВЩЕ ЗМПВБМШОЩЕ ЙМЙ НЕОСФШ УФБФЙЮЕУЛЙЕ РЕТЕНЕООЩЕ! еУМЙ чЩ ОХЦДБЕФЕУШ Ч РБНСФЙ, чЩ ДПМЦОЩ ТБУРТЕДЕМЙФШ ЕЕ Ч xxx_init() Й ОЕРТЕНЕООП ПУЧПВПДЙФШ Ч xxx_deinit() .

3.1.2.1 уПЗМБЫЕОЙС РП ЧЩЪПЧХ UDF

пУОПЧОБС ЖХОЛГЙС ДПМЦОБ ВЩФШ ПВЯСЧМЕОБ ЛБЛ РПЛБЪБОП ОЙЦЕ. пВТБФЙФЕ ЧОЙНБОЙЕ, ЮФП ФЙР ЧПЪЧТБФБ Й РБТБНЕФТЩ ПФМЙЮБАФУС Ч ЪБЧЙУЙНПУФЙ ПФ ФПЗП, ПВЯСЧЙФЕ МЙ чЩ ФЙР ЧПЪЧТБФБ ЖХОЛГЙЙ SQL XXX() ЛБЛ STRING , INTEGER ЙМЙ REAL Ч ЧЩЪПЧЕ CREATE FUNCTION:

дМС ЖХОЛГЙК ФЙРБ STRING:

Char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);

дМС ЖХОЛГЙК ФЙРБ INTEGER:

Long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

дМС ЖХОЛГЙК ФЙРБ REAL:

Double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

жХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ Й ДЕЙОЙГЙБМЙЪБГЙЙ ПВЯСЧМЕОЩ РПДПВОП ЬФПНХ:

My_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);

рБТБНЕФТ initid РЕТЕДБО ЧУЕН ФТЕН ЖХОЛГЙСН. пО ХЛБЪЩЧБЕФ ОБ УФТХЛФХТХ UDF_INIT , ЛПФПТБС ЙУРПМШЪХЕФУС, ЮФПВЩ РЕТЕДБФШ ЙОЖПТНБГЙА НЕЦДХ ЖХОЛГЙСНЙ. юМЕОЩ УФТХЛФХТЩ UDF_INIT РЕТЕЮЙУМЕОЩ ОЙЦЕ. жХОЛГЙС ЙОЙГЙБМЙЪБГЙЙ ДПМЦОБ ЪБРПМОЙФШ МАВЩЕ ЮМЕОЩ, ЛПФПТЩЕ ПОБ ЦЕМБЕФ ЙЪНЕОЙФШ. юФПВЩ ЙУРПМШЪПЧБФШ ЪОБЮЕОЙЕ РП ХНПМЮБОЙА ДМС ЮМЕОБ, ПУФБЧШФЕ ЕЗП ОЕЙЪНЕООЩН. рЕТЕКДЕН Л ПРЙУБОЙА:

My_bool maybe_null xxx_init() ДПМЦОБ ХУФБОПЧЙФШ maybe_null Ч 1 , ЕУМЙ xxx() НПЦЕФ ЧПЪЧТБЭБФШ NULL . ъОБЮЕОЙЕ РП ХНПМЮБОЙА 1 , ЕУМЙ МАВПК ЙЪ РБТБНЕФТПЧ ПВЯСЧМЕО ЛБЛ maybe_null . unsigned int decimals юЙУМП ДЕУСФЙЮОЩИ ГЙЖТ. ъОБЮЕОЙЕ РП ХНПМЮБОЙА: НБЛУЙНБМШОПЕ ЛПМЙЮЕУФЧП ДЕУСФЙЮОЩИ ГЙЖТ Ч РБТБНЕФТБИ, РЕТЕДБООЩИ ПУОПЧОПК ЖХОЛГЙЙ. оБРТЙНЕТ, ЕУМЙ ЖХОЛГЙЙ РЕТЕДБОЩ 1.34 , 1.345 Й 1.3 , ЪОБЮЕОЙЕН РП ХНПМЮБОЙА ВХДЕФ 3, РПУЛПМШЛХ 1.345 ЙНЕЕФ 3 ДЕУСФЙЮОЩИ ГЙЖТЩ. unsigned int max_length нБЛУЙНБМШОБС ДМЙОБ ТЕЪХМШФБФБ-УФТПЛЙ. ъОБЮЕОЙЕ РП ХНПМЮБОЙА ПФМЙЮБЕФУС Ч ЪБЧЙУЙНПУФЙ ПФ ФЙРБ ТЕЪХМШФБФБ ЖХОЛГЙЙ. дМС УФТПЮОЩИ ЖХОЛГЙК ЪОБЮЕОЙЕ РП ХНПМЮБОЙА ТБЧОП ДМЙОЕ УБНПЗП ДМЙООПЗП РБТБНЕФТБ. дМС ГЕМПЮЙУМЕООЩИ ЖХОЛГЙК ЪОБЮЕОЙЕ РП ХНПМЮБОЙА УППФЧЕФУФЧХЕФ 21 ГЙЖТЕ. дМС ТЕБМШОЩИ ЖХОЛГЙК ЪОБЮЕОЙЕ РП ХНПМЮБОЙА 13+ЛПМЙЮЕУФЧП ДЕУСФЙЮОЩИ ЮЙУЕМ, ПВПЪОБЮЕООЩИ ЛБЛ initid->decimals . дМС ЮЙУМПЧЩИ ЖХОЛГЙК ДМЙОБ ЧЛМАЮБЕФ МАВПК ЪОБЛ ЙМЙ ДЕУСФЙЮОЩЕ УЙНЧПМЩ ПФНЕФЛЙ. char *ptr хЛБЪБФЕМШ, ЛПФПТЩК ЖХОЛГЙС НПЦЕФ ЙУРПМШЪПЧБФШ ДМС УПВУФЧЕООЩИ ГЕМЕК. оБРТЙНЕТ, ЖХОЛГЙЙ НПЗХФ ЙУРПМШЪПЧБФШ initid->ptr , ЮФПВЩ РЕТЕДБФШ ТБУРТЕДЕМЕООХА РБНСФШ НЕЦДХ ЖХОЛГЙСНЙ. ч xxx_init() ЛБЛ ПВЩЮОП ТБУРТЕДЕМЙФЕ РБНСФШ Й ОБЪОБЮШФЕ ЕЕ ЬФПНХ ХЛБЪБФЕМА: initid->ptr=allocated_memory; ч xxx() Й xxx_deinit() ПВТБФЙФЕУШ Л initid->ptr , ЮФПВЩ ЙУРПМШЪПЧБФШ ЙМЙ ПУЧПВПДЙФШ РБНСФШ.

3.1.2.2 пВТБВПФЛБ РБТБНЕФТПЧ

рБТБНЕФТ args ХЛБЪЩЧБЕФ ОБ УФТХЛФХТХ UDF_ARGS , ЮМЕОЩ ЛПФПТПК РТЙЧЕДЕОЩ ОЙЦЕ:

Unsigned int arg_count юЙУМП РБТБНЕФТПЧ. рТПЧЕТШФЕ ЬФП ЪОБЮЕОЙЕ Ч ЖХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ, ЕУМЙ чЩ ИПФЙФЕ, ЮФПВЩ чБЫБ ЖХОЛГЙС ВЩМБ ЧЩЪЧБОБ УП УРЕГЙЖЙЮЕУЛЙН ЮЙУМПН РБТБНЕФТПЧ. оБРТЙНЕТ, ФБЛЙН ЛПДПН: if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; } enum Item_result *arg_type фЙРЩ ДМС ЛБЦДПЗП РБТБНЕФТБ. чПЪНПЦОЩЕ ЪОБЮЕОЙС ФЙРПЧ: STRING_RESULT , INT_RESULT Й REAL_RESULT . юФПВЩ ХДПУФПЧЕТЙФШУС, ЮФП РБТБНЕФТЩ ЙНЕАФ ДБООЩК ФЙР Й ЧПЪЧТБЭБАФ ПЫЙВЛХ, ЕУМЙ ПОЙ Л ОЕНХ ОЕ РТЙОБДМЕЦБФ, РТПЧЕТШФЕ НБУУЙЧ arg_type Ч ЖХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ. оБРТЙНЕТ: if (args->arg_type != STRING_RESULT || args->arg_type != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; } чЩ НПЦЕФЕ ЙУРПМШЪПЧБФШ ЖХОЛГЙА ЙОЙГЙБМЙЪБГЙЙ, ЮФПВЩ ХУФБОПЧЙФШ ЬМЕНЕОФЩ arg_type Л ФЙРБН, ЛПФПТЩЕ чЩ ИПФЙФЕ РПМХЮЙФШ. ьФП ЪБУФБЧМСЕФ MySQL РТЙЧЕУФЙ РБТБНЕФТЩ Л ФЕН ФЙРБН ДМС ЛБЦДПЗП ПВТБЭЕОЙС Л xxx() . оБРТЙНЕТ, ЮФПВЩ ПРТЕДЕМЙФШ РЕТЧЩЕ ДЧБ ЬМЕНЕОФБ ЛБЛ УФТПЛХ Й ЮЙУМП, УДЕМБКФЕ УМЕДХАЭЕЕ Ч xxx_init() : args->arg_type = STRING_RESULT; args->arg_type = INT_RESULT; char **args args->args УППВЭБЕФ ЙОЖПТНБГЙА ЖХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ ПФОПУЙФЕМШОП ПВЭЕЗП ИБТБЛФЕТБ РБТБНЕФТПЧ, У ЛПФПТЩНЙ чБЫБ ЖХОЛГЙС ВЩМБ ЧЩЪЧБОБ. дМС РПУФПСООПЗП РБТБНЕФТБ (ЛПОУФБОФЩ) i args->args[i] ХЛБЪЩЧБЕФ ОБ ЪОБЮЕОЙЕ РБТБНЕФТБ. дМС ОЕРПУФПСООПЗП РБТБНЕФТБ args->args[i] ТБЧОП 0 . рПУФПСООЩК РБТБНЕФТ РТЕДУФБЧМСЕФ УПВПК ЧЩТБЦЕОЙЕ, ЛПФПТПЕ ЙУРПМШЪХЕФ ФПМШЛП ЛПОУФБОФЩ, ФЙРБ 3 , 4*7-2 ЙМЙ SIN(3.14) . оЕРПУФПСООЩК РБТБНЕФТ РТЕДУФБЧМСЕФ УПВПК ЧЩТБЦЕОЙЕ, ЛПФПТПЕ ПВТБЭБЕФУС Л ЪОБЮЕОЙСН, ЛПФПТЩЕ НПЗХФ ЙЪНЕОСФШУС, ФЙРБ ЙНЕОЙ УФПМВГБ ЙМЙ ЖХОЛГЙК, ЛПФПТЩЕ ЧЩЪЧБОЩ У ОЕРПУФПСООЩНЙ РБТБНЕФТБНЙ. дМС ЛБЦДПЗП ПВТБЭЕОЙС ПУОПЧОПК ЖХОЛГЙЙ args->args ИТБОЙФ ЖБЛФЙЮЕУЛЙЕ РБТБНЕФТЩ, ЛПФПТЩЕ РЕТЕДБОЩ ДМС Ч ОБУФПСЭЕЕ ЧТЕНС ПВТБВБФЩЧБЕНПК УФТПЛЙ. жХОЛГЙЙ НПЗХФ ПВТБФЙФШУС Л РБТБНЕФТХ i УМЕДХАЭЙН ПВТБЪПН:

  • рБТБНЕФТ ФЙРБ STRING_RESULT , ДБООЩК ЛБЛ ХЛБЪБФЕМШ УФТПЛЙ РМАУ ДМЙОБ, РПЪЧПМСЕФ ПВТБВПФЛХ ДЧПЙЮОЩИ ДБООЩИ ЙМЙ ДБООЩИ РТПЙЪЧПМШОПК ДМЙОЩ. уПДЕТЦБОЙЕ УФТПЛЙ ДПУФХРОП ЛБЛ args->args[i] , Б ДМЙОБ УФТПЛЙ ЛБЛ args->lengths[i] . чЩ ОЕ ДПМЦОЩ УЮЙФБФШ, ЮФП УФТПЛБ ЪБЧЕТЫБЕФУС ОХМЕЧЩН УЙНЧПМПН.
  • дМС РБТБНЕФТБ ФЙРБ INT_RESULT чЩ ДПМЦОЩ РТЙЧЕУФЙ args->args[i] Л ФЙРХ long long: long long int_val; int_val = *((long long*) args->args[i]);
  • дМС РБТБНЕФТБ ФЙРБ REAL_RESULT чЩ ДПМЦОЩ РТЙЧЕУФЙ args->args[i] Л ФЙРХ double: double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths дМС ЖХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ, НБУУЙЧ lengths ХЛБЪЩЧБЕФ НБЛУЙНБМШОХА ДМЙОХ УФТПЛЙ ДМС ЛБЦДПЗП РБТБНЕФТБ. дМС ЛБЦДПЗП ПВТБЭЕОЙС Л ПУОПЧОПК ЖХОЛГЙЙ lengths ИТБОЙФ ЖБЛФЙЮЕУЛЙЕ ДМЙОЩ МАВЩИ УФТПЛПЧЩИ РБТБНЕФТПЧ, ЛПФПТЩЕ РЕТЕДБОЩ ДМС УФТПЛЙ, ПВТБВБФЩЧБЕНПК Ч ОБУФПСЭЕЕ ЧТЕНС. дМС РБТБНЕФТПЧ ФЙРПЧ INT_RESULT ЙМЙ REAL_RESULT lengths ИТБОЙФ НБЛУЙНБМШОХА ДМЙОХ РБТБНЕФТБ (ЛБЛ ДМС ЖХОЛГЙЙ ЙОЙГЙБМЙЪБГЙЙ).

3.1.2.3 чПЪЧТБЭБЕНЩЕ ЪОБЮЕОЙС Й ПВТБВПФЛБ ПЫЙВПЛ

жХОЛГЙС ЙОЙГЙБМЙЪБГЙЙ ЧПЪЧТБФЙФ 0 , ЕУМЙ ОЙЛБЛБС ПЫЙВЛБ ОЕ РТПЙЪПЫМБ, Й 1 Ч РТПФЙЧОПН УМХЮБЕ. еУМЙ ПЫЙВЛБ РТПЙУИПДЙФ, xxx_init() ДПМЦОБ УПИТБОЙФШ УППВЭЕОЙЕ ПВ ПЫЙВЛЕ У ОХМЕЧЩН УЙНЧПМПН Ч ЛПОГЕ Ч РБТБНЕФТЕ message . уППВЭЕОЙЕ ВХДЕФ ЧПЪЧТБЭЕОП РПМШЪПЧБФЕМА. вХЖЕТ УППВЭЕОЙК ЙНЕЕФ ДМЙОХ Ч MYSQL_ERRMSG_SIZE УЙНЧПМПЧ, ОП чЩ ДПМЦОЩ РПРТПВПЧБФШ УПИТБОЙФШ УППВЭЕОЙЕ Ч 80 УЙНЧПМБИ ФБЛ, ЮФПВЩ ЬФП ХДПЧМЕФЧПТЙМП ЫЙТЙОЕ УФБОДБТФОПЗП ЬЛТБОБ ФЕТНЙОБМБ.

ъОБЮЕОЙЕ ЧПЪЧТБФБ ПУОПЧОПК ЖХОЛГЙЙ xxx() ЪБЧЙУЙФ ПФ ФЙРБ. дМС ЖХОЛГЙК ФЙРПЧ long long Й double ПОП РТЕДУФБЧМСЕФ УПВПК УПВУФЧЕООП ЖХОЛГЙПОБМШОПЕ ЪОБЮЕОЙЕ. уФТПЛПЧЩЕ ЖХОЛГЙЙ ДПМЦОЩ ЧПЪЧТБФЙФШ ХЛБЪБФЕМШ ОБ ТЕЪХМШФБФ Й УПИТБОЙФШ ДМЙОХ УФТПЛЙ Ч РБТБНЕФТБИ length . ъДЕУШ result РТЕДУФБЧМСЕФ УПВПК ВХЖЕТ ДМЙОПК Ч 255 ВБКФ. хУФБОПЧЙФЕ ЙИ Л УПДЕТЦБОЙА Й ДМЙОЕ ЪОБЮЕОЙС. оБРТЙНЕТ:

Memcpy(result, "result string", 13); *length=13;

еУМЙ чБЫЙ ЖХОЛГЙЙ УФТПЛЙ ДПМЦОЩ ЧПЪЧТБФЙФШ УФТПЛХ ДМЙООЕЕ, ЮЕН 255 ВБКФ, ТБУРТЕДЕМЙФЕ РБНСФШ ДМС ТЕЪХМШФБФБ ЮЕТЕЪ malloc() Ч ЖХОЛГЙЙ xxx_init() ЙМЙ Ч xxx() , Б ЪБФЕН ПУЧПВПДЙФЕ РБНСФШ Ч xxx_deinit() . чЩ НПЦЕФЕ УПИТБОСФШ ТБУРТЕДЕМЕООХА РБНСФШ Ч УМПФЕ ptr УФТХЛФХТЩ UDF_INIT ДМС РПЧФПТОПЗП ЙУРПМШЪПЧБОЙС Ч ВХДХЭЕН ПВТБЭЕОЙЙ xxx() . рПДТПВОПУФЙ Ч ТБЪДЕМЕ "3.1.2.1 уПЗМБЫЕОЙС П ЧЩЪПЧЕ UDF ".

юФПВЩ ХЛБЪЩЧБФШ ЪОБЮЕОЙЕ ЧПЪЧТБФБ NULL Ч ПУОПЧОПК ЖХОЛГЙЙ, ХУФБОПЧЙФЕ is_null Ч 1:

*is_null=1;

юФПВЩ ХЛБЪБФШ ЧПЪЧТБФ ПЫЙВЛЙ Ч ПУОПЧОПК ЖХОЛГЙЙ, ХУФБОПЧЙФЕ РБТБНЕФТ ПЫЙВЛЙ (error) Ч ЪОБЮЕОЙЕ 1:

*error=1;

еУМЙ xxx() ХУФБОБЧМЙЧБЕФ *error Ч 1 ДМС МАВПК УФТПЛЙ, ЖХОЛГЙПОБМШОПЕ ЪОБЮЕОЙЕ NULL ДМС ФЕЛХЭЕК УФТПЛЙ Й ДМС МАВЩИ РПУМЕДХАЭЙИ УФТПЛ, ПВТБВПФБООЩИ ЙОУФТХЛГЙЕК, Ч ЛПФПТПК ЧЩЪЩЧБМБУШ XXX() . рТЙЮЕН, xxx() ОЕ ВХДЕФ ДБЦЕ ЪБРТБЫЙЧБФШУС ДМС РПУМЕДХАЭЙИ УФТПЛ. ртйнеюбойе: ч MySQL ДП ЧЕТУЙЙ 3.22.10 чЩ ДПМЦОЩ ХУФБОПЧЙФШ *error Й *is_null:

*error=1; *is_null=1;

3.1.2.4 лПНРЙМСГЙС Й ХУФБОПЧЛБ ПРТЕДЕМСЕНЩИ РПМШЪПЧБФЕМЕН ЖХОЛГЙК

жБКМЩ, ЧЩРПМОСАЭЙЕ UDF, ДПМЦОЩ ЛПНРЙМЙТПЧБФШУС Й ХУФБОБЧМЙЧБФШУС ОБ УЕТЧЕТЕ. ьФПФ РТПГЕУУ ПРЙУБО ОЙЦЕ ДМС РТЙНЕТОПЗП UDF-ЖБКМБ udf_example.cc , ЛПФПТЩК ЧЛМАЮЕО Ч ДЙУФТЙВХФЙЧ ЙУИПДОЙЛПЧ MySQL. ьФПФ ЖБКМ УПДЕТЦЙФ УМЕДХАЭЙЕ ЖХОЛГЙЙ:

  • metaphon() ЧПЪЧТБЭБЕФ НЕФБ-УФТПЛХ ДМС УФТПЛПЧПЗП РБТБНЕФТБ. ьФП РПИПЦЕ ОБ soundex, ОП ВПМШЫЕ ЪБФПЮЕОП РПД БОЗМЙКУЛЙК.
  • myfunc_double() ЧПЪЧТБЭБЕФ УХННХ ASCII-ЪОБЮЕОЙК УЙНЧПМПЧ Ч РБТБНЕФТБИ, РПДЕМЕООХА ОБ УХННХ ДМЙО ЬФЙИ РБТБНЕФТПЧ.
  • myfunc_int() ЧПЪЧТБЭБЕФ УХННХ ДМЙО РБТБНЕФТПЧ.
  • sequence() ЧПЪЧТБФЙФ РПУМЕДПЧБФЕМШОПУФШ, ОБЮЙОБАЭХАУС У ЪБДБООПЗП ЮЙУМБ ЙМЙ У 1, ЕУМЙ ОЙЛБЛПЗП ЮЙУМБ ЪБДБОП ОЕ ВЩМП.
  • lookup() ЧПЪЧТБЭБЕФ IP-БДТЕУ.
  • reverse_lookup() ЧПЪЧТБЭБЕФ hostname ДМС IP-БДТЕУБ. жХОЛГЙС НПЦЕФ ВЩФШ ЧЩЪЧБОБ УП УФТПЛПК "xxx.xxx.xxx.xxx" ЙМЙ У 4 ЮЙУМБНЙ.

дЙОБНЙЮЕУЛЙ ЪБЗТХЦБЕНЩК ЖБКМ ДПМЦЕО ЛПНРЙМЙТПЧБФШУС ЛБЛ ТБЪДЕМСЕНЩК ПВЯЕЛФОЩК ЖБКМ, ЙУРПМШЪХС ЛПНБОДХ:

Shell> gcc -shared -o udf_example.so myfunc.cc

чЩ НПЦЕФЕ МЕЗЛП ЧЩСУОСФШ РТБЧЙМШОЩЕ РБТБНЕФТЩ ЛПНРЙМСФПТБ ДМС чБЫЕК УЙУФЕНЩ, ЪБРХУЛБС ФБЛХА ЛПНБОДХ Ч ЛБФБМПЗЕ sql чБЫЕЗП ДЕТЕЧБ ЙУИПДОЩИ ФЕЛУФПЧ MySQL:

Shell> make udf_example.o

чЩ ДПМЦОЩ ЧЩРПМОЙФШ ЛПНБОДХ ЛПНРЙМСГЙЙ, РПДПВОХА ПДОПК ЙЪ ФЕИ, ЮФП ПФПВТБЦБЕФ make , ЪБ ЙУЛМАЮЕОЙЕН ФПЗП, ЮФП чЩ ДПМЦОЩ ХДБМЙФШ ПРГЙА -c ВМЙЪЛП Л ЛПОГХ УФТПЛЙ Й ДПВБЧЙФШ -o udf_example.so Ч УБНЩК ЛПОЕГ УФТПЛЙ. оБ ОЕЛПФПТЩИ УЙУФЕНБИ ХДБМСФШ -c ОЕ ОБДП, РТПВХКФЕ.

лБЛ ФПМШЛП чЩ УЛПНРЙМЙТХЕФЕ ПВЭЕДПУФХРОЩК ПВЯЕЛФ, УПДЕТЦБЭЙК UDF, чЩ ДПМЦОЩ ХУФБОПЧЙФШ ЕЗП Й УППВЭЙФШ MySQL П ТБУЫЙТЕОЙЙ ЖХОЛГЙПОБМШОПУФЙ. лПНРЙМСГЙС ПВЭЕДПУФХРОПЗП ПВЯЕЛФБ ЙЪ udf_example.cc РТПЙЪЧПДЙФ ЖБКМ У ЙНЕОЕН udf_example.so (ФПЮОПЕ ЙНС НПЦЕФ ЙЪНЕОСФШУС ПФ РМБФЖПТНЩ Л РМБФЖПТНЕ). уЛПРЙТХКФЕ ЬФПФ ЖБКМ Ч ОЕЛПФПТЩК ЛБФБМПЗ, ЗДЕ ЙЭЕФ ЖБКМЩ ld , ОБРТЙНЕТ, Ч /usr/lib . оБ НОПЗЙИ УЙУФЕНБИ чЩ НПЦЕФЕ ХУФБОБЧМЙЧБФШ УЙУФЕНОХА РЕТЕНЕООХА LD_LIBRARY ЙМЙ LD_LIBRARY_PATH , ЮФПВЩ ХЛБЪБФШ ЛБФБМПЗ, ЗДЕ чЩ ЙНЕЕФЕ чБЫЙ ЖБКМЩ ЖХОЛГЙЙ UDF. тХЛПЧПДУФЧП ОБ dlopen УППВЭБЕФ чБН, ЛПФПТХА РЕТЕНЕООХА чЩ ДПМЦОЩ ЙУРПМШЪПЧБФШ ОБ чБЫЕК УЙУФЕНЕ. чЩ ДПМЦОЩ ХУФБОПЧЙФШ ЬФП Ч mysql.server ЙМЙ Ч safe_mysqld Й РЕТЕЪБРХУФЙФШ mysqld .

рПУМЕ ФПЗП, ЛБЛ ВЙВМЙПФЕЛБ ХУФБОПЧМЕОБ, УППВЭЙФЕ mysqld ПФОПУЙФЕМШОП ОПЧЩИ ЖХОЛГЙК ЬФЙНЙ ЛПНБОДБНЙ:

Mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";

жХОЛГЙЙ НПЗХФ ВЩФШ ХДБМЕОЩ, ЙУРПМШЪХС DROP FUNCTION:

Mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;

йОУФТХЛГЙЙ CREATE FUNCTION Й DROP FUNCTION НПДЙЖЙГЙТХАФ УЙУФЕНОХА ФБВМЙГХ func Ч ВБЪЕ ДБООЩИ mysql . йНС ЖХОЛГЙЙ, ФЙР Й ПВЭЕДПУФХРОПЕ ВЙВМЙПФЕЮОПЕ ЙНС ВХДХФ УПИТБОЕОП Ч ФБВМЙГЕ. чЩ ДПМЦОЩ ЙНЕФШ РТЙЧЙМЕЗЙЙ insert Й delete ДМС ВБЪЩ ДБООЩИ mysql , ЮФПВЩ УПЪДБЧБФШ Й ХДБМСФШ УЧПЙ ЖХОЛГЙЙ.

чЩ ОЕ ДПМЦОЩ ЙУРПМШЪПЧБФШ CREATE FUNCTION , ЮФПВЩ ДПВБЧЙФШ ЖХОЛГЙА, ЛПФПТБС ХЦЕ ВЩМБ УПЪДБОБ. еУМЙ чЩ ДПМЦОЩ РПЧФПТОП ХУФБОПЧЙФШ ЖХОЛГЙА, УОБЮБМБ ХДБМЙФЕ ЕЕ ЮЕТЕЪ ЧЩЪПЧ DROP FUNCTION Й ЪБФЕН РПЧФПТОП ХУФБОПЧЙФЕ ЕЕ У РПНПЭША CREATE FUNCTION . чЩ ДПМЦОЩ УДЕМБФШ ЬФП, ОБРТЙНЕТ, ЕУМЙ чЩ ПФЛПНРЙМЙТПЧБМЙ ОПЧХА ЧЕТУЙА чБЫЕК ЖХОЛГЙЙ, ЮФПВЩ mysqld ПВОПЧЙМ ЙУРПМШЪХЕНХА ЙН ЧЕТУЙА. йОБЮЕ УЕТЧЕТ РТПДПМЦЙФ РТЙНЕОСФШ УФБТХА ЧЕТУЙА.

бЛФЙЧОЩЕ ЖХОЛГЙЙ ВХДХФ РЕТЕЪБЗТХЦЕОЩ РТЙ ЛБЦДПН РЕТЕЪБРХУЛЕ УЕТЧЕТБ, ЕУМЙ чЩ ОЕ ЪБРХУЛБЕФЕ mysqld У ПРГЕК --skip-grant-tables . ч ЬФПН УМХЮБЕ ЙОЙГЙБМЙЪБГЙС UDF ВХДЕФ РТПРХЭЕОБ, Б UDF-ЖХОЛГЙЙ УФБОХФ ОЕДПУФХРОЩНЙ. бЛФЙЧОБС ЖХОЛГЙС РТЕДУФБЧМСЕФ УПВПК ЖХОЛГЙА, ЪБЗТХЦЕООХА ЮЕТЕЪ CREATE FUNCTION , ОП ОЕ ХДБМЕООХА DROP FUNCTION .

3.1.3 дПВБЧМЕОЙЕ ОПЧЩИ ЧУФТПЕООЩИ ЖХОЛГЙК

рТПГЕДХТБ ДМС ДПВБЧМЕОЙС ОПЧПК ЧУФТПЕООПК ЖХОЛГЙЙ ПРЙУБОБ ОЙЦЕ. пВТБФЙФЕ ЧОЙНБОЙЕ, ЮФП чЩ ОЕ НПЦЕФЕ ДПВБЧМСФШ ЧУФТПЕООЩЕ ЖХОЛГЙЙ Л ДЧПЙЮОПНХ ДЙУФТЙВХФЙЧХ РПФПНХ, ЮФП РТПГЕДХТБ ЧЛМАЮБЕФ ЙЪНЕОЕОЙЕ ЙУИПДОПЗП ФЕЛУФБ MySQL. чЩ ДПМЦОЩ УЛПНРЙМЙТПЧБФШ MySQL УБНПУФПСФЕМШОП ЙЪ ЙУИПДОЙЛПЧ. фБЛЦЕ ПВТБФЙФЕ ЧОЙНБОЙЕ, ЮФП, ЕУМЙ чЩ НЙЗТЙТХЕФЕ ОБ ДТХЗХА ЧЕТУЙА MySQL (ОБРТЙНЕТ, ЛПЗДБ ОПЧБС ЧЕТУЙС ЧЩРХЭЕОБ), чЩ ВХДЕФЕ ДПМЦОЩ РПЧФПТЙФШ РТПГЕДХТХ У ОПЧПК ЧЕТУЙЕК.

юФПВЩ ДПВБЧЙФШ ОПЧХА ЧУФТПЕООХА ЖХОЛГЙА MySQL, ОХЦОП:

  1. дПВБЧШФЕ ПДОХ УФТПЛХ Ч ЖБКМ lex.h , ЛПФПТБС ПРТЕДЕМСЕФ ЙНС ЖХОЛГЙЙ Ч НБУУЙЧЕ sql_functions .
  2. еУМЙ ЖХОЛГЙПОБМШОЩК РТПФПФЙР РТПУФ (ВЕТЕФ ОЕ ВПМЕЕ ФТЕИ РБТБНЕФТПЧ), чЩ ДПМЦОЩ Ч lex.h ПРТЕДЕМЙФШ SYM(FUNC_ARG#) (ЪДЕУШ # СЧМСЕФУС ЮЙУМПН РБТБНЕФТПЧ) ЛБЛ ЧФПТПК РБТБНЕФТ Ч НБУУЙЧЕ sql_functions Й ДПВБЧЙФШ ЖХОЛГЙА, ЛПФПТБС УПЪДБЕФ ЖХОЛГЙПОБМШОЩК ПВЯЕЛФ, Ч item_create.cc . уНПФТЙФЕ "ABS" Й create_funcs_abs() ЛБЛ РТЙНЕТ. еУМЙ ЖХОЛГЙПОБМШОЩК РТПФПФЙР ХУМПЦОЕО (ОБРТЙНЕТ, ВЕТЕФ РЕТЕНЕООПЕ ЮЙУМП РБТБНЕФТПЧ), чЩ ДПМЦОЩ ДПВБЧЙФШ ДЧЕ УФТПЛЙ Л sql_yacc.yy . лБЦДБС ХЛБЪЩЧБЕФ УЙНЧПМ РТЕРТПГЕУУПТБ, ЛПФПТЩК yacc ДПМЦЕО ПРТЕДЕМЙФШ (ЬФП ДПМЦОП ВЩФШ ДПВБЧМЕОП Ч ОБЮБМЕ ЖБКМБ). ъБФЕН ПРТЕДЕМЙФЕ ЖХОЛГЙПОБМШОЩЕ РБТБНЕФТЩ Й ДПВБЧШФЕ ЬМЕНЕОФ У ЬФЙНЙ РБТБНЕФТБНЙ ДМС РТБЧЙМБ УЙОФБЛУЙЮЕУЛПЗП БОБМЙЪБ simple_expr . дМС РТЙНЕТБ, РТПЧЕТШФЕ ЧУЕ НЕУФПОБИПЦДЕОЙС ATAN Ч sql_yacc.yy , ЮФПВЩ ХЧЙДЕФШ, ЛБЛ ЬФП ЧЩРПМОЕОП.
  3. ч item_func.h ПВЯСЧЙФЕ ОБУМЕДПЧБОЙЕ ЛМБУУБ ЙЪ Item_num_func ЙМЙ Item_str_func , Ч ЪБЧЙУЙНПУФЙ ПФ ФПЗП, ЧПЪЧТБЭБЕФ МЙ чБЫБ ЖХОЛГЙС ЮЙУМП ЙМЙ УФТПЛХ.
  4. ч item_func.cc ДПВБЧШФЕ ПДОП ЙЪ УМЕДХАЭЙИ ПВЯСЧМЕОЙК Ч ЪБЧЙУЙНПУФЙ ПФ ФПЗП, ПРТЕДЕМСЕФЕ МЙ чЩ ЮЙУМПЧХА ЙМЙ УФТПЛПЧХА ЖХОЛГЙА: double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str) еУМЙ чЩ ОБУМЕДХЕФЕ чБЫ ПВЯЕЛФ ПФ МАВПЗП ЙЪ УФБОДБТФОЩИ ЬМЕНЕОФПЧ (РПДПВОП Item_num_func , чЩ, ЧЕТПСФОП, ДПМЦОЩ ФПМШЛП ПРТЕДЕМЙФШ ПДОХ ЙЪ ЧЩЫЕХРПНСОХФЩИ ЖХОЛГЙК Й РПЪЧПМЙФШ ТПДЙФЕМШУЛПНХ ПВЯЕЛФХ ЪБВПФЙФШУС П ДТХЗЙИ ЖХОЛГЙСИ. оБРТЙНЕТ, ЛМБУУ Item_str_func ПРТЕДЕМСЕФ ЖХОЛГЙА val() , ЛПФПТБС ЧЩРПМОСЕФ atof() ОБ ЪОБЮЕОЙЙ, ЧПЪЧТБЭЕООПН::str() .
  5. чЩ ДПМЦОЩ, ЧЕТПСФОП, ФБЛЦЕ ПРТЕДЕМЙФШ УМЕДХАЭХА ПВЯЕЛФОХА ЖХОЛГЙА: void Item_func_newname::fix_length_and_dec() ьФБ ЖХОЛГЙС ДПМЦОБ РП ЛТБКОЕК НЕТЕ ЧЩЮЙУМЙФШ max_length , ЙУИПДС ЙЪ ДБООЩИ РБТБНЕФТПЧ. max_length ЪБДБЕФ НБЛУЙНБМШОПЕ ЮЙУМП УЙНЧПМПЧ, ЛПФПТПЕ ЖХОЛГЙС НПЦЕФ ЧПЪЧТБЭБФШ. ьФБ ЖХОЛГЙС ДПМЦОБ ФБЛЦЕ ХУФБОПЧЙФШ maybe_null=0 , ЕУМЙ ПУОПЧОБС ЖХОЛГЙС ОЕ НПЦЕФ ЧПЪЧТБЭБФШ ЪОБЮЕОЙЕ NULL . жХОЛГЙС НПЦЕФ РТПЧЕТЙФШ, УРПУПВЕО МЙ МАВПК ЙЪ РБТБНЕФТПЧ ЧПЪЧТБЭБФШ NULL , РТПЧЕТСС РЕТЕНЕООХА РБТБНЕФТПЧ maybe_null . чЩ НПЦЕФЕ ЙЪХЮЙФШ Item_func_mod::fix_length_and_dec Ч ЛБЮЕУФЧЕ ФЙРЙЮОПЗП РТЙНЕТБ ФПЗП, ЛБЛ ЧУЕ ЬФП УДЕМБФШ.

чУЕ ЖХОЛГЙЙ ДПМЦОЩ ВЩФШ РПФПЮОП-ВЕЪПРБУОЩНЙ (ДТХЗЙНЙ УМПЧБНЙ, ОЕ ЙУРПМШЪХКФЕ МАВЩЕ ЗМПВБМШОЩЕ ЙМЙ УФБФЙЮЕУЛЙЕ РЕТЕНЕООЩЕ Ч ЖХОЛГЙСИ ВЕЪ ФПЗП, ЮФПВЩ ЪБЭЙФЙФШ ЙИ ЮЕТЕЪ mutex).

еУМЙ чЩ ИПФЙФЕ ЧПЪЧТБЭБФШ NULL ЙЪ::val() , ::val_int() ЙМЙ::str() чЩ ДПМЦОЩ ХУФБОПЧЙФШ null_value Ч 1 Й ЧЕТОХФШ ЙЪ ЖХОЛГЙЙ 0.

дМС ПВЯЕЛФОПК ЖХОЛГЙЙ::str() ЙНЕАФУС ОЕЛПФПТЩЕ ДПРПМОЙФЕМШОЩЕ ИЙФТПУФЙ, ЛПФПТЩЕ ОБДП ЪОБФШ:

  • рБТБНЕФТ String *str ПВЕУРЕЮЙЧБЕФ ВХЖЕТ УФТПЛЙ, ЛПФПТЩК НПЦЕФ ЙУРПМШЪПЧБФШУС, ЮФПВЩ ИТБОЙФШ ТЕЪХМШФБФ. дМС РПМХЮЕОЙС ВПМШЫЕЗП ЛПМЙЮЕУФЧБ ЙОЖПТНБГЙЙ ПФОПУЙФЕМШОП ФЙРБ String ПВТБФЙФЕУШ Л ЖБКМХ sql_string.h .
  • жХОЛГЙС::str() ДПМЦОБ ЧПЪЧТБФЙФШ УФТПЛХ, ЛПФПТБС ИТБОЙФ ТЕЪХМШФБФ, ЙМЙ (char*) 0 , ЕУМЙ ТЕЪХМШФБФПН СЧМСЕФУС NULL .
  • чУЕ ФЕЛХЭЙЕ ЖХОЛГЙЙ УФТПЛЙ ОЕ ДПМЦОЩ ТБУРТЕДЕМСФШ ОЙЛБЛХА РБНСФШ, ЕУМЙ ЬФП ОЕ БВУПМАФОП ОЕПВИПДЙНП!

3.2 дПВБЧМЕОЙЕ ОПЧЩИ РТПГЕДХТ Ч MySQL

ч MySQL чЩ НПЦЕФЕ ПРТЕДЕМСФШ РТПГЕДХТХ ОБ C++, ЛПФПТБС НПЦЕФ ПВТБЭБФШУС Й ЙЪНЕОСФШ ДБООЩЕ Ч ЪБРТПУЕ РТЕЦДЕ, ЮЕН ПОЙ ПФРТБЧСФУС Л РПМШЪПЧБФЕМА. нПДЙЖЙЛБГЙС НПЦЕФ ВЩФШ ЧЩРПМОЕОБ ОБ ХТПЧОЕ УФТПЛЙ ЙМЙ GROUP BY .

бЧФПТЩ РБЛЕФБ УПЪДБМЙ РТПГЕДХТХ РТЙНЕТБ Ч MySQL Version 3.23, ЮФПВЩ РПЛБЪБФШ чБН, ЮФП ФБН НПЦЕФ ВЩФШ ЧЩРПМОЕОП.

дПРПМОЙФЕМШОП БЧФПТЩ ТЕЛПНЕОДХАФ чБН РПУНПФТЕФШ ЖБКМ mylua, ЛПФПТЩК чЩ НПЦЕФЕ ОБКФЙ Ч ЛБФБМПЗЕ Contrib. чЩ НПЦЕФЕ ЙУРПМШЪПЧБФШ СЪЩЛ LUA, ЮФПВЩ ЪБЗТХЪЙФШ РТПГЕДХТХ Ч mysqld РТСНП ЧП ЧТЕНС ЧЩРПМОЕОЙС.

3.2.1 бОБМЙЪ РТПГЕДХТ

analyse(])

ьФБ РТПГЕДХТБ ПРТЕДЕМЕОБ Ч sql/sql_analyse.cc . пОБ ЙУУМЕДХЕФ ТЕЪХМШФБФ, РПМХЮЕООЩК ЙЪ чБЫЕЗП ЪБРТПУБ, Й ЧПЪЧТБЭБЕФ БОБМЙЪ ТЕЪХМШФБФПЧ:

  • max elements (РП ХНПМЮБОЙА 256) ЪБДБЕФ НБЛУЙНБМШОПЕ ЮЙУМП ТБЪОЩИ ЪОБЮЕОЙК, ЛПФПТЩЕ analyse ЪБНЕФЙФ Ч УФПМВГЕ. ьФП ЙУРПМШЪХЕФУС, ЮФПВЩ РТПЧЕТЙФШ ПРФЙНБМШОПУФШ РТЙНЕОЕОЙС ФЙРБ ENUM .
  • max memory (РП ХНПМЮБОЙА 8192) ЪБДБЕФ НБЛУЙНХН РБНСФЙ, ЛПФПТХА analyse ДПМЦЕО ТБУРТЕДЕМЙФШ ОБ УФПМВЕГ РТЙ РПРЩФЛЕ ОБКФЙ ЧУЕ ПФМЙЮОЩЕ ЪОБЮЕОЙС.
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE(])

3.2.2 оБРЙУБОЙЕ РТПГЕДХТ

оБ УЕЗПДОСЫОЙК ДЕОШ ЕДЙОУФЧЕООПК ДПЛХНЕОФБГЙЕК ДМС ЬФПЗП СЧМСЕФУС ЙУИПДОЩК ЛПД РБЛЕФБ.

чЩ НПЦЕФЕ ОБКФЙ ЧУА ЙОЖПТНБГЙА ПФОПУЙФЕМШОП РТПГЕДХТ, ЙУУМЕДХС ЖБКМЩ:

  • sql/sql_analyse.cc
  • sql/procedure.h
  • sql/procedure.cc
  • sql/sql_select.cc

3.3 оБЮЙОЛБ MySQL

ьФБ ЗМБЧБ ПРЙУЩЧБЕФ НОПЗП ЧЕЭЕК, ЛПФПТЩЕ чЩ ДПМЦОЩ ЪОБФШ РТЙ ТБВПФЕ ОБ ЛПДЕ MySQL. еУМЙ чЩ РМБОЙТХЕФЕ УРПУПВУФЧПЧБФШ MySQL ТБЪТБВПФЛЕ, ЙНЕФШ ДПУФХР Л ЛПДХ ПФМБЦЙЧБЕНЩИ ЧЕТУЙК ЙМЙ ИПФЙФЕ ФПМШЛП УМЕДЙФШ ЪБ ТБЪТБВПФЛПК, УМЕДХКФЕ ЛПНБОДБН Ч ТБЪДЕМЕ " ". еУМЙ чЩ ЪБЙОФЕТЕУПЧБОЩ ЧОХФТЕООЕК ПТЗБОЙЪБГЙЕК MySQL, чЩ ДПМЦОЩ ФБЛЦЕ РПДРЙУБФШУС ОБ УРЕГЙБМШОЩК УРЙУПЛ ТБУУЩМЛЙ [email protected] .

3.3.1 рПФПЛЙ Ч MySQL

уЕТЧЕТ MySQL УПЪДБЕФ УМЕДХАЭЙЕ РПФПЛЙ:

  • рПФПЛ TCP/IP-РПДЛМАЮЕОЙК ПВТБВБФЩЧБЕФ ЧУЕ РПДЛМАЮЕОЙС, ЪБРТБЫЙЧБЕФ Й УПЪДБЕФ ОПЧЩК УРЕГЙБМЙЪЙТПЧБООЩК РПФПЛ, ЮФПВЩ ПВТБВПФБФШ БЧФПТЙЪБГЙА Й ЪБРТПУЩ SQL ДМС ЛБЦДПЗП РПДЛМАЮЕОЙС.
  • ч Windows NT ЙНЕЕФУС ДТБКЧЕТ ЙНЕОПЧБООПЗП ЛБОБМБ, ЛПФПТЩК ДЕМБЕФ ФХ ЦЕ УБНХА ТБВПФХ, ЮФП Й РПФПЛ TCP/IP, ОП У ЪБРТПУБНЙ ОБ ЙНЕОПЧБООПН ЛБОБМЕ.
  • рПФПЛ УЙЗОБМБ ПВТБВБФЩЧБЕФ ЧУЕ УЙЗОБМЩ. пО ФБЛЦЕ ПВЩЮОП ПВТБВБФЩЧБЕФ ФТЕЧПЗЙ Й ЧЩЪЩЧБЕФ process_alarm() , ЮФПВЩ ЪБЧЕТЫЙФШ РПДЛМАЮЕОЙС, ЛПФПТЩЕ ВЩМЙ ОЕБЛФЙЧОЩ УМЙЫЛПН ДПМЗП.
  • еУМЙ mysqld ЛПНРЙМЙТХЕФУС У -DUSE_ALARM_THREAD , УРЕГЙБМЙЪЙТПЧБООЩК РПФПЛ, ЛПФПТЩК ПВТБВБФЩЧБЕФ ФТЕЧПЗЙ, ВХДЕФ УПЪДБО. ьФП ЙУРПМШЪХЕФУС ФПМШЛП ОБ ОЕЛПФПТЩИ УЙУФЕНБИ, ЗДЕ ЙНЕАФУС РТПВМЕНЩ У sigwait() , ЙМЙ ЕУМЙ ЕУФШ ОЕДПУФБФЛЙ Ч РТЙНЕОЕОЙЙ ЛПДБ thr_alarm() Ч РТЙЛМБДОПК РТПЗТБННЕ ВЕЪ УРЕГЙБМЙЪЙТПЧБООПЗП РПФПЛБ ПВТБВПФЛЙ УЙЗОБМБ.
  • еУМЙ ЙУРПМШЪПЧБОБ ПРГЙС --flush_time=# , ВХДЕФ УПЪДБО ЕЭЕ ПДЙО УРЕГЙБМЙЪЙТПЧБООЩК РПФПЛ, ЛПФПТЩК УВТБУЩЧБЕФ ФБВМЙГЩ ОБ ДЙУЛ.
  • лБЦДПЕ УПЕДЙОЕОЙЕ ПВТБВБФЩЧБЕФУС УЧПЙН РПФПЛПН.
  • лБЦДБС ФБВМЙГБ, ОБ ЛПФПТПК ЙУРПМШЪПЧБОБ ЙОУФТХЛГЙС INSERT DELAYED , РПМХЮБЕФ УПВУФЧЕООЩК РПФПЛ.
  • еУМЙ чЩ ЙУРПМШЪХЕФЕ --master-host , ВХДЕФ ЪБРХЭЕО РПФПЛ ТЕРМЙЛБГЙЙ, ЮФПВЩ ЮЙФБФШ Й РТЙНЕОСФШ НПДЙЖЙЛБГЙЙ У ЗМБЧОПЗП УЕТЧЕТБ.

mysqladmin processlist РПЛБЪЩЧБЕФ ФПМШЛП РПДЛМАЮЕОЙС, РПФПЛЙ ТЕРМЙЛБГЙЙ Й INSERT DELAYED .

3.3.2 оБВПТ ФЕУФПЧ MySQL

дП ОЕДБЧОЕЗП ЧТЕНЕОЙ ПУОПЧОПК ОБВПТ ФЕУФБ ВЩМ ПУОПЧБО ОБ УПУФБЧМСАЭЙИ УПВУФЧЕООПУФШ ДБООЩИ ЪБЛБЪЮЙЛБ Й РП ЬФПК РТЙЮЙОЕ ОЕ ВЩМ РХВМЙЮОП ДПУФХРЕО. еДЙОУФЧЕООЩК РХВМЙЮОП ДПУФХРОБС ЮБУФШ РТПГЕУУБ ФЕУФЙТПЧБОЙС УПУФПСМБ ЙЪ ФЕУФБ crash-me , ЬФБМПООПЗП ФЕУФБ Perl DBI/DBD, ОБИПДСЭЕЗПУС Ч ЛБФБМПЗЕ sql-bench , Й ТБЪОППВТБЪОЩИ ФЕУФПЧ, ТБЪНЕЭЕООЩИ Ч ЛБФБМПЗЕ tests . пФУХФУФЧЙЕ УФБОДБТФЙЪЙТПЧБООПЗП РХВМЙЮОП ДПУФХРОПЗП ОБВПТБ ФЕУФПЧ УДЕМБМП ФТХДОЩН ДМС РПМШЪПЧБФЕМЕК Й ТБЪТБВПФЮЙЛПЧ ФЕУФЙТПЧБОЙЕ ЛПДБ MySQL. юФПВЩ ЙУРТБЧЙФШ ЬФХ УЙФХБГЙА, БЧФПТЩ РБЛЕФБ УПЪДБМЙ УПЧЕТЫЕООП ОПЧХА УЙУФЕНХ ФЕУФПЧ, ЛПФПТБС ФЕРЕТШ ЧЛМАЮЕОБ Ч ЙУИПДОЩЕ Й ДЧПЙЮОЩЕ ДЙУФТЙВХФЙЧЩ, ОБЮЙОБС У Version 3.23.23.

фЕЛХЭЙК ОБВПТ ФЕУФПЧ ОЕ РТПЧЕТСЕФ ЧУЕ Ч MySQL, ОП ДПМЦЕО ПИЧБФЙФШ ОБЙВПМЕЕ ПЮЕЧЙДОЩЕ ПЫЙВЛЙ Ч ПВТБВПФЛБ ЛПДБ SQL, OS/library РТПВМЕНЩ Й ФЕУФЙТПЧБОЙЕ ТЕРМЙЛБГЙЙ. лПОЕЮОБС ГЕМШ УПУФПЙФ Ч ФПН, ЮФПВЩ ЙНЕФШ ФЕУФЩ, РПЛТЩЧБАЭЙЕ 100% ЛПДБ. чЩ НПЦЕФЕ РТЕДПУФБЧЙФШ ФЕУФЩ, ЛПФПТЩЕ ЙУУМЕДХАФ ЖХОЛГЙПОБМШОЩЕ ЧПЪНПЦОПУФЙ, ЛТЙФЙЮОЩЕ ДМС чБЫЕК УЙУФЕНЩ, РПУЛПМШЛХ ЬФП ЗБТБОФЙТХЕФ, ЮФП ЧУЕ ВХДХЭЙЕ ЧЩРХУЛЙ MySQL ВХДХФ ИПТПЫП ТБВПФБФШ У чБЫЙНЙ РТЙЛМБДОЩНЙ РТПЗТБННБНЙ.

3.3.2.1 ъБРХУЛ ОБВПТБ ФЕУФПЧ MySQL

уЙУФЕНБ ФЕУФБ УПУФПЙФ ЙЪ ЙОФЕТРТЕФБФПТБ СЪЩЛПЧ ФЕУФПЧ (mysqltest), УЛТЙРФБ ПВПМПЮЛЙ, ЮФПВЩ ЧЩРПМОЙФШ ЧУЕ ФЕУФЩ (mysql-test-run), ЖБЛФЙЮЕУЛЙИ УМХЮБЕЧ ФЕУФПЧ, ОБРЙУБООЩИ ОБ УРЕГЙБМШОПН СЪЩЛЕ ФЕУФПЧ Й ЙИ ПЦЙДБЕНЩИ ТЕЪХМШФБФПЧ. юФПВЩ ЧЩРПМОЙФШ ОБВПТ ФЕУФБ ОБ чБЫЕК УЙУФЕНЕ РПУМЕ РПУФТПЕОЙС, ЧЧЕДЙФЕ make test ЙМЙ mysql-test/mysql-test-run ЙЪ ЛПТОЕЧПЗП ЛБФБМПЗБ ЙУИПДОЩИ ФЕЛУФПЧ. еУМЙ чЩ ХУФБОПЧЙМЙ ДЧПЙЮОЩК ДЙУФТЙВХФЙЧ, РЕТЕКДЙФЕ Ч ЛПТЕОШ ХУФБОПЧЛЙ (ОБРТЙНЕТ, /usr/local/mysql) Й УЛПНБОДХКФЕ scripts/mysql-test-run . чУЕ ФЕУФЩ ДПМЦОЩ ЧЩРПМОЙФШУС. еУМЙ ЬФПЗП ОЕ РТПЙЪПЫМП, РТПРПВХКФЕ ЧЩСУОЙФШ РПЮЕНХ Й УППВЭЙФЕ П РТПВМЕНЕ, ЕУМЙ ЬФП ПЫЙВЛБ Ч РБЛЕФЕ MySQL. рПДТПВОПУФЙ Ч ТБЪДЕМЕ "3.3.2.3 лБЛ УППВЭБФШ П РТПВМЕНБИ Й ПЫЙВЛБИ Ч ОБВПТЕ ФЕУФПЧ MySQL ".

еУМЙ чЩ ЙНЕЕФЕ ЛПРЙА mysqld ОБ НБЫЙОЕ, ЗДЕ чЩ ИПФЙФЕ ЧЩРПМОЙФШ ОБВПТ ФЕУФПЧ, чЩ ОЕ ДПМЦОЩ ПУФБОБЧМЙЧБФШ ЕЕ, ЕУМЙ ПОБ ОЕ ЙУРПМШЪХЕФ РПТФЩ 9306 Й 9307 . еУМЙ ПДЙО ЙЪ ЬФЙИ РПТФПЧ РТЙНЕОСЕФУС, чЩ ДПМЦОЩ ПФТЕДБЛФЙТПЧБФШ mysql-test-run Й ЙЪНЕОЙФШ ЪОБЮЕОЙС ЗМБЧОПЗП ЙМЙ РПДЮЙОЕООПЗП РПТФБ Л ФПНХ, ЛПФПТПЕ СЧМСЕФУС ДПУФХРОЩН.

чЩ НПЦЕФЕ ЪБРХУФЙФШ ЙОДЙЧЙДХБМШОП ЛБЦДЩК ФЕУФ ЛПНБОДПК mysql-test/mysql-test-run test_name .

еУМЙ ПДЙО ФЕУФ УЧБМЙМУС, РТПЧЕТШФЕ ТБВПФХ mysql-test-run У ПРГЙЕК --force , ЮФПВЩ РТПЧЕТЙФШ, УВПСФ МЙ МАВЩЕ ДТХЗЙЕ ФЕУФЩ.

3.3.2.2 тБУЫЙТЕОЙЕ ОБВПТБ ФЕУФПЧ MySQL

чЩ НПЦЕФЕ ЙУРПМШЪПЧБФШ СЪЩЛ mysqltest , ЮФПВЩ РЙУБФШ чБЫЙ УПВУФЧЕООЩЕ УМХЮБЙ ФЕУФБ. л УПЦБМЕОЙА, БЧФПТЩ РБЛЕФБ ЕЭЕ ОЕ ОБРЙУБМЙ РПМОХА ДПЛХНЕОФБГЙА ДМС ОЕЗП. чЩ НПЦЕФЕ, ПДОБЛП, ТБУУНБФТЙЧБФШ ФЕЛХЭЙЕ УМХЮБЙ ФЕУФБ Й ЙУРПМШЪПЧБФШ ЙИ ЛБЛ РТЙНЕТ. уМЕДХАЭЙЕ РХОЛФЩ ДПМЦОЩ РПНПЮШ чБН:

  • фЕУФЩ ОБИПДСФУС Ч ЛБФБМПЗЕ mysql-test/t/*.test
  • уМХЮБК ФЕУФБ УПУФПЙФ ЙЪ ЪБЧЕТЫЕООПК ФПЮЛПК У ЪБРСФПК (;) ЙОУФТХЛГЙЙ Й РПДПВЕО ЧЧПДХ ЛМЙЕОФБ ЛПНБОДОПК УФТПЛЙ mysql . йОУФТХЛГЙС РП ХНПМЮБОЙА: ЪБРТПУ, ЛПФПТЩК ВХДЕФ РПУМБО УЕТЧЕТХ MySQL, ЕУМЙ ПО ОЕ ТБУРПЪОБО ЛБЛ ЧОХФТЕООСС ЛПНБОДБ (ОБРТЙНЕТ, sleep).
  • чУЕ ЪБРТПУЩ, ЛПФПТЩЕ РТПЙЪЧПДСФ ТЕЪХМШФБФЩ, ОБРТЙНЕТ, SELECT , SHOW , EXPLAIN Й РТПЮЙЕ, ОХЦОП РТЕДЧБТЙФШ ХЛБЪБОЙЕН @/path/to/result/file . жБКМ ДПМЦЕО УПДЕТЦБФШ ПЦЙДБЕНЩЕ ТЕЪХМШФБФЩ. рТПУФПК УРПУПВ ЗЕОЕТЙТПЧБФШ ЖБКМ ТЕЪХМШФБФБ УПУФПЙФ Ч ФПН, ЮФПВЩ ЧЩРПМОЙФШ mysqltest -r юФПВЩ ЧУЕ УППФЧЕФУФЧПЧБМП ХУФБОПЧЛЕ, чЩ ДПМЦОЩ РПНЕУФЙФШ чБЫЙ ЖБКМЩ ТЕЪХМШФБФБ Ч ЛБФБМПЗ mysql-test/r Й ОБЪЧБФШ ЙИ ЛБЛ test_name.result . еУМЙ ФЕУФ РТПЙЪЧПДЙФ ВПМШЫЕ, ЮЕН ПДЙО ТЕЪХМШФБФ, чЩ ДПМЦОЩ ЙУРПМШЪПЧБФШ test_name.a.result , test_name.b.result Й ФБЛ ДБМЕЕ.
  • еУМЙ ЙОУФТХЛГЙС ЧПЪЧТБЭБЕФ ПЫЙВЛХ, чЩ ДПМЦОЩ ОБ УФТПЛЕ РЕТЕД ОЕК ХЛБЪБФШ --error error-number . ъДЕУШ error-number НПЦЕФ ВЩФШ УРЙУЛПН ЧПЪНПЦОЩИ ЛПДПЧ ПЫЙВПЛ, ПФДЕМСЕНЩИ ЪБРСФЩНЙ (,).
  • еУМЙ чЩ ЪБРЙУЩЧБЕФЕ УМХЮБК ФЕУФБ ТЕРМЙЛБГЙЙ, чЩ ДПМЦОЩ Ч РЕТЧПК УФТПЛЕ ЖБКМБ ФЕУФБ РПНЕЭБФШ source include/master-slave.inc; . юФПВЩ РЕТЕЛМАЮБФШУС НЕЦДХ ЗМБЧОПК Й РПДЮЙОЕООПК УЙУФЕНБНЙ, ЙУРПМШЪХКФЕ connection master; Й connection slave; . еУМЙ чЩ ДПМЦОЩ ДЕМБФШ ЮФП-ФП ОБ БМШФЕТОБФЙЧОПН РПДЛМАЮЕОЙЙ, чЩ НПЦЕФЕ УДЕМБФШ РПДЛМАЮЕОЙЕ connection master1; ДМС ЗМБЧОПК Й connection slave1; ДМС РПДЮЙОЕООПК УЙУФЕНЩ.
  • еУМЙ чЩ ДПМЦОЩ ДЕМБФШ ЮФП-ФП Ч ГЙЛМЕ, чЩ НПЦЕФЕ ЙУРПМШЪПЧБФШ: let $1=1000; while ($1) { # чЩРПМОСЕН ЪДЕУШ ЪБРТПУ. dec $1; }
  • юФПВЩ ВЕЪДЕКУФЧПЧБФШ НЕЦДХ ЪБРТПУБНЙ, ЙУРПМШЪХКФЕ ЛПНБОДХ sleep . пОБ РПДДЕТЦЙЧБЕФ ДПМЙ УЕЛХОДЩ, ФБЛ ЮФП чЩ НПЦЕФЕ ХЛБЪБФШ sleep 1.5; , ОБРТЙНЕТ, ЮФПВЩ ВЕЪДЕКУФЧПЧБФШ 1.5 УЕЛХОДЩ.
  • юФПВЩ ЧЩРПМОСФШ РПДЮЙОЕООПЗП У ДПРПМОЙФЕМШОЩНЙ РБТБНЕФТБНЙ ДМС чБЫЕЗП УМХЮБС ФЕУФБ, РПНЕУФЙФЕ ЙИ Ч ЖПТНБФЕ ЛПНБОДОПК УФТПЛЙ Ч mysql-test/t/test_name-slave.opt . дМС ЗМБЧОПК УЙУФЕНЩ РПНЕУФЙФЕ ЙИ Ч ЖБКМ mysql-test/t/test_name-master.opt .
  • еУМЙ чЩ ЙНЕЕФЕ ЧПРТПУ ПФОПУЙФЕМШОП ОБВПТБ ФЕУФБ ЙМЙ УМХЮБК ФЕУФБ, ЛПФПТЩК НПЦЕФ РТЙЗПДЙФШУС ЧУЕН, ОБРЙЫЙФЕ ПВ ЬФПН ОБ [email protected] . рПУЛПМШЛХ УРЙУПЛ ОЕ РТЙОЙНБЕФ ЧМПЦЕОЙС, чЩ ДПМЦОЩ ЪБЛБЮБФШ РП ftp ЧУЕ ТЕМЕЧБОФОЩЕ ЖБКМЩ ОБ ftp://support.mysql.com/pub/mysql/Incoming .

3.3.2.3 лБЛ УППВЭБФШ ПВ ПЫЙВЛБИ Ч ОБВПТЕ ФЕУФПЧ MySQL

еУМЙ чБЫБ ЧЕТУЙС MySQL ОЕ ЧЩРПМОСЕФ ОБВПТ ФЕУФПЧ, чЩ ДПМЦОЩ УДЕМБФШ ФБЛ:

  • оЕ ФПТПРЙФЕУШ РПУЩМБФШ ПФЮЕФ ПВ ПЫЙВЛЕ! уОБЮБМБ ТБЪВЕТЙФЕУШ ФПМЛПН, ЮФП ФБН Х чБУ РТПЙУИПДЙФ Й РПЮЕНХ. еУМЙ ПФЮЕФ ЧУЕ-ФБЛЙ РТЙДЕФУС РПУМБФШ, РПЦБМХКУФБ, ЙУРПМШЪХКФЕ ДМС ЕЗП ЗЕОЕТБГЙЙ УЛТЙРФ mysqlbug , ЮФПВЩ ТБЪТБВПФЮЙЛЙ НПЗМЙ РПМХЮЙФШ ЙОЖПТНБГЙА ПФОПУЙФЕМШОП чБЫЕК УЙУФЕНЩ Й ЧЕТУЙЙ MySQL.
  • хДПУФПЧЕТШФЕУШ, ЮФП ЧЛМАЮЙМЙ ЧЩЧПД mysql-test-run Й УПДЕТЦБОЙЕ ЧУЕИ.reject ЖБКМПЧ Ч ЛБФБМПЗЕ mysql-test/r .
  • еУМЙ ФЕУФ ЧБМЙФУС Ч ОБВПТЕ, РТПЧЕТШФЕ, ЮФП У ОЙН ВХДЕФ РТПЙУИПДЙФШ РТЙ ОЕРПУТЕДУФЧЕООПН ЪБРХУЛЕ ЛПНБОДПК: cd mysql-test mysql-test-run --local test-name еУМЙ ЬФП ФЕТРЙФ ОЕХДБЮХ, ФП УЛПОЖЙЗХТЙТХКФЕ MySQL У ПРГЙЕК --with-debug Й ЧЩРПМОЙФЕ mysql-test-run У ПРГЙЕК --debug . еУМЙ ЬФП ФБЛЦЕ ФЕТРЙФ ОЕХДБЮХ, ЪБЛБЮБКФЕ ЖБКМ ФТБУУЙТПЧЛЙ var/tmp/master.trace ОБ ftp://support.mysql.com/pub/mysql/secret, ЮФПВЩ БЧФПТЩ НПЗМЙ ЙУУМЕДПЧБФШ ЬФП. рПЦБМХКУФБ, ОЕ ЪБВХДШФЕ ФБЛЦЕ ЧЛМАЮЙФШ РПМОПЕ ПРЙУБОЙЕ чБЫЕК УЙУФЕНЩ, ЧЕТУЙА mysqld Й РБТБНЕФТЩ ЛПНРЙМСГЙЙ.
  • рПРТПВХКФЕ ФБЛЦЕ ЧЩРПМОЙФШ mysql-test-run У ПРГЙЕК --force , ЮФПВЩ ХЧЙДЕФШ, ЙНЕЕФУС МЙ МАВПК ДТХЗПК ФЕУФ, ЛПФПТЩК ФПЦЕ ФЕТРЙФ ОЕХДБЮХ.
  • еУМЙ чЩ ЛПНРЙМЙТПЧБМЙ MySQL УБНПУФПСФЕМШОП, ЙЪХЮЙФЕ ТХЛПЧПДУФЧП ОБ РТЕДНЕФ ФПЗП, ЛБЛ ЛПНРЙМЙТПЧБФШ MySQL ОБ чБЫЕК РМБФЖПТНЕ ЙМЙ, ЮФП РТЕДРПЮФЙФЕМШОП, ЙУРПМШЪХКФЕ ПДЙО ЙЪ ЗПФПЧЩИ ДЧПЙЮОЩИ ДЙУФТЙВХФЙЧПЧ, ЛПФПТЩК ХЦЕ ПФЛПНРЙМЙТПЧБО Й НПЦЕФ ВЩФШ УЛБЮБО У http://www.mysql.com/downloads. чУЕ УФБОДБТФОЩЕ ДЧПЙЮОЩЕ ЖБКМЩ ДПМЦОЩ РТПИПДЙФШ ФЕУФЙТПЧБОЙЕ.
  • еУМЙ чЩ РПМХЮБЕФЕ ПЫЙВЛХ, РПДПВОП Result length mismatch ЙМЙ Result content mismatch , ЬФП ПЪОБЮБЕФ, ЮФП ЧЩЧПД ФЕУФБ ОЕ УППФЧЕФУФЧПЧБМ ФПЮОП ПЦЙДБЕНПНХ ЧЩЧПДХ. ьФП НПЦЕФ ВЩФШ ПЫЙВЛПК Ч MySQL, ЙМЙ ДЕМП Ч ФПН, ЮФП чБЫБ ЧЕТУЙС mysqld РТПЙЪЧПДЙФ НБМПУФШ ЙОЩЕ ТЕЪХМШФБФЩ РТЙ ОЕЛПФПТЩИ ПВУФПСФЕМШУФЧБИ. оЕХДБЮОЩЕ ТЕЪХМШФБФЩ ФЕУФБ ВХДХФ РПНЕЭЕОЩ Ч ЖБКМ У ФЕН ЦЕ УБНЩН ПУОПЧОЩН ЙНЕОЕН, ЮФП Й ЖБКМ ТЕЪХМШФБФБ, ОП У ТБУЫЙТЕОЙЕН.reject . еУМЙ чБЫ УМХЮБК ФЕУФБ ФЕТРЙФ ОЕХДБЮХ, чЩ ДПМЦОЩ УТБЧОЙФШ ДЧБ ЖБКМБ. еУМЙ чЩ ОЕ НПЦЕФЕ ХЧЙДЕФШ, ЮЕН ПОЙ ПФМЙЮБАФУС, ЙУУМЕДХКФЕ ЙИ У РПНПЭША od -c Й РТПЧЕТШФЕ ЙИ ДМЙОЩ.
  • еУМЙ ФЕУФ ФЕТРЙФ ОЕХДБЮХ РПМОПУФША, чЩ ДПМЦОЩ РТПЧЕТЙФШ ЦХТОБМЩ Ч ЛБФБМПЗЕ mysql-test/var/log ДМС ЧЩСУОЕОЙС ФПЗП, ЮФП ОЕ ФБЛ.
  • еУМЙ чЩ ЛПНРЙМЙТПЧБМЙ MySQL У ПФМБДЛПК, НПЦОП РПРТПВПЧБФШ ПФМБЦЙЧБФШ ФЕУФ ЪБРХУЛПН mysql-test-run У ПРГЙСНЙ --gdb Й/ЙМЙ --debug . рПДТПВОПУФЙ Ч ТБЪДЕМЕ "6.1.2 уПЪДБОЙЕ ЖБКМПЧ ФТБУУЙТПЧЛЙ ". еУМЙ чЩ ОЕ ЛПНРЙМЙТПЧБМЙ MySQL ДМС ПФМБДЛЙ, ЧЕТПСФОП, УФПЙФ УДЕМБФШ ЬФП. фПМШЛП ПРТЕДЕМЙФЕ РБТБНЕФТ --with-debug ДМС ЧЩЪПЧБ configure ! рПДТПВОПУФЙ Ч ТБЪДЕМЕ " ".

What are functions?

MySQL can do much more than just store and retrieve data . We can also perform manipulations on the data before retrieving or saving it. That"s where MySQL Functions come in. Functions are simply pieces of code that perform some operations and then return a result. Some functions accept parameters while other functions do not accept parameters.

Let" briefly look at an example of MySQL function. By default, MySQL saves date data types in the format "YYYY-MM-DD". Suppose we have built an application and our users want the date to be returned in the format "DD-MM-YYYY", we can use MySQL built in function DATE_FORMAT to achieve this. DATE_FORMAT is one of the most used functions in MySQL. We will look at it in more details as we unfold the lesson.

Why use functions?

Based on the example given in the introduction, people with experience in computer programming may be thinking "Why bother MySQL Functions? The same effect can be achieved with scripting/programming language?" It"s true we can achieve that by writing some procedures/function in the application program.

Getting back to our DATE example in the introduction, for our users to get the data in the desired format, business layer will have to do necessary processing.

This becomes a problem when the application has to integrate with other systems. When we use MySQL functions such as the DATE_FORMAT, then we can have that functionality embedded into the database and any application that needs the data gets it in the required format. This reduces re-work in the business logic and reduce data inconsistencies.

Another reason why we should consider using MySQL functions is the fact that it can help reducing network traffic in client/server applications . Business Layer will only need to make call to the stored functions without the need manipulate data .On average, the use of functions can help greatly improve overall system performance.

Types of functions

Built-in functions

MySQL comes bundled with a number of built in functions. Built in functions are simply functions come already implemented in the MySQL server. These functions allow us to perform different types of manipulations on the data. The built in functions can be basically categorized into the following most used categories.

  • Strings functions - operate on string data types
  • Numeric functions - operate on numeric data types
  • Date functions - operate on date data types
  • Aggregate functions - operate on all of the above data types and produce summarized result sets.
  • Other functions - MySQL also supports other types of built in functions but we will limit our lesson to the above named functions only.

Let"s now look at each of the functions mentioned above in detail. We will be explaining the most used functions using our "Myflixdb".

String functions

We already looked at what string functions do. We will look at a practical example that uses them. In our movies table, the movie titles are stored using combinations of lower and upper case letters. Suppose we want to get a query list that returns the movie titles in upper case letters. We can use the "UCASE" function to do that. It takes a string as a parameter and converts all the letters to upper case. The script shown below demonstrates the use of the "UCASE" function.

SELECT `movie_id`,`title`, UCASE(`title`) FROM `movies`;

  • UCASE(`title`) is the built in function that takes the title as a parameter and returns it in upper case letters with the alias name `upper_case_title`.

Executing the above script in MySQL workbench against the Myflixdb gives us the following results shown below.

movie_id title UCASE("title")
16 67% Guilty 67% GUILTY
6 Angels and Demons ANGELS AND DEMONS
4 Code Name Black CODE NAME BLACK
5 Daddy"s Little Girls DADDY"S LITTLE GIRLS
7 Davinci Code DAVINCI CODE
2 Forgetting Sarah Marshal FORGETTING SARAH MARSHAL
9 Honey mooners HONEY MOONERS
19 movie 3 MOVIE 3
1 Pirates of the Caribean 4 PIRATES OF THE CARIBEAN 4
18 sample movie SAMPLE MOVIE
17 The Great Dictator THE GREAT DICTATOR
3 X-Men X-MEN

MySQL supports a number of string functions. For a complete list of all the built in string functions, refere to this link http://dev.mysql.com/doc/refman/5.0/en/string-functions.html on MySQL website.

Numeric functions

As earlier mentioned, these functions operate on numeric data types. We can perform mathematic computations on numeric data in the SQL statements.

Arithematic operators

MySQL supports the following arithmatic operators that can be used to perform computations in the SQL statements.

Description

Integer division

Let"s now look at examples of each of the above operator

Integer Division (DIV)

SELECT 23 DIV 6 ;

Division operator (/)

Let"s now look at the division operator example. We will modify the DIV example.

Executing the above script gives us the following results.

Subtraction operator (-)

Let"s now look at the subtraction operator example. We will use the same values as in the previous two examples

Executing the above script gives us 17

Addition operator (+)

Let"s now look at the addition operator example. We will modify the previous example.

Executing the above script gives us 29

Multiplication operator (*)

Let"s now look at the multiplication operator example. We will use the same values as in the previous examples.

SELECT 23 * 6 AS `multiplication_result`;

Executing the above script gives us the following results.

multiplication_result

Modulo operator (-)

The modulo operator divides N by M and gives us the reminder. Let"s now look at the modulo operator example. We will use the same values as in the previous examples.

SELECT 23 MOD 6 ;

Executing the above script gives us 5

Let"s now look at some of the common numeric functions in MySQL.

Floor - this function removes decimals places from a number and rounds it to the nearest lowest number. The script shown below demonstrates its usage.

SELECT FLOOR(23 / 6) AS `floor_result`;

Executing the above script gives us the following results.

Floor_result

Round - this function rounds a number with decimal places to the nearest whole number. The script shown below demonstrates its usage.

SELECT ROUND(23 / 6) AS `round_result`;

Executing the above script gives us the following results.

Round_result

Rand - this function is used to generate a random number, its value changes every time that the function is called. The script shown below demonstrates its usage.

SELECT RAND() AS `random_result`;

Stored functions

Stored functions are just like built in functions except that you have to define the stored function yourself. Once a stored function has been created, it can be used in SQL statements just like any other function. The basic syntax for creating a stored function is as shown below

CREATE FUNCTION sf_name () RETURNS data type DETERMINISTIC STATEMENTS

  • "CREATE FUNCTION sf_name () " is mandatory and tells MySQL server to create a function named `sf_name" with optional parameters defined in the parenthesis.
  • "RETURNS data type" is mandatory and specifies the data type that the function should return.
  • "DETERMINISTIC" means the function will return the same values if the same arguments are supplied to it.
  • "STATEMENTS" is the procedural code that the function executes.

Let"s now look at a practical example that implements a built in function. Suppose we want to know which rented movies are past the return date. We can create a stored function that accepts the return date as the parameter and then compares it with the current date in MySQL server. If the current date is less than the return movie date, then we return "No" else we return "Yes". The script shown below helps us to achieve that.

DELIMITER | CREATE FUNCTION sf_past_movie_return_date (return_date DATE) RETURNS VARCHAR(3) DETERMINISTIC BEGIN DECLARE sf_value VARCHAR(3); IF curdate() > return_date THEN SET sf_value = "Yes"; ELSEIF curdate() <= return_date THEN SET sf_value = "No"; END IF; RETURN sf_value; END|

Executing the above script created the stored function `sf_past_movie_return_date`.

Let"s now test our stored function.

SELECT `movie_id`,`membership_number`,`return_date`,CURDATE() ,sf_past_movie_return_date(`return_date`) FROM `movierentals`;

Executing the above script in MySQL workbench against the myflixdb gives us the following results.

movie_id membership_number return_date CURDATE() sf_past_movie_return_date("return_date")
1 1 NULL 04-08-2012 NULL
2 1 25-06-2012 04-08-2012 yes
2 3 25-06-2012 04-08-2012 yes
2 2 25-06-2012 04-08-2012 yes
3 3 NULL 04-08-2012 NULL

User-defined functions

MySQL also supports user defined functions that extend MySQL. User defined functions are functions that you can create using a programming language such as C, C++ etc. and then add them to MySQL server. Once added, they can be used just like any other function.

Summary

  • Functions allow us to enhance the capabilities of MySQL.
  • Functions always return a value and can optionally accept parameters.
  • Built in functions are functions that are shipped with MySQL. They can be categorized according to the data types that they operate on i.e. strings, date and numeric built in functions.
  • Stored functions are created by the user within MySQL server and can be used in SQL statements.
  • User defined functions are created outside MySQL and can be incorporated into MySQL server.
 

Пожалуйста, поделитесь этим материалом в социальных сетях, если он оказался полезен!