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 ! рПДТПВОПУФЙ Ч ТБЪДЕМЕ " ".

Внимание! Данная работа построена на основе перевода раздела «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)

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.

В этой части статьи допишем начатую в предыдущей статье хранимую процедуру и научимся создавать хранимые mysql функции .

И так нам осталось указать значение для последней переменной PostID. В качестве значения ей будет присвоен результат, который вернёт функция GetPostID, которую сейчас и создадим.

Создание функции

Для начала закрываем текущую форму создания процедуры, нажав на кнопку c надписью Go. Затем в этом же окне снова нажимаем на надпись Add routine, появится знакомая форма, заполним её.

Имя - GetPostID Тип - функция Parameters - ComID BIGINT(20) UNSIGNED Return type (возвращаемый тип) - BIGINT Return length/values - 20 Return options - UNSIGNED Definition: BEGIN RETURN (SELECT comment_post_ID FROM wp_comments WHERE comment_ID = ComID); END;

Так же можно указать дополнительные параметры:

Is deterministic — детерминированная функция всегда возвращает один и тот же результат при одинаковых входных параметрах иначе она является не детерминированной. В нашем случае ставим галочку.

Definer и Security type параметры безопасности, в данном примере оставим их без изменений.

SQL data access имеет несколько значений:

NO SQL - не содержит sql.

Contains SQL - содержит встроенные sql функции или операторы, которые не читают, не пишут и не изменяют данные в базе данных. Например, установка значения переменной: SET name = значение;

READS SQL DATA - только чтение данных, без любой модификации данных, указывается для запроса SELECT.

MODIFIES SQL DATA - изменение или внесение данных, в базу данных, указывается для запросов: INSERT, UPDATE, но при этом не должен присутствовать запрос SELECT.

В нашей функции используется запрос SELECT, укажем READS SQL DATA.

Comment комментарий.

После того как все поля заполнены, нажимаем на кнопку с надписью Go.

Возвращаемся на вкладку Routines и отредактируем нашу процедуру, нажав на кнопку edit.

Присвоим переменой PostID в качестве значения результат, который вернёт функция GetPostID.

SET postID = GetPostID(ComID);

В результате окончательное тело процедуры будет таким

BEGIN DECLARE Author tinytext DEFAULT "admin"; DECLARE UserID bigint(20) DEFAULT 1; DECLARE Email varchar(100); DECLARE Date DATETIME DEFAULT NOW(); DECLARE ParentCom varchar(20); DECLARE Approved varchar(20); DECLARE PostID BIGINT(20); IF Author = "admin" THEN SET Approved = 1; ELSE SET Approved = 0; END IF; SET ParentCom = ComID ; SET Email = "[email protected]"; SET PostID = GetPostID(ComID); INSERT INTO wp_comments (comment_author, comment_author_email, comment_content, comment_date, comment_date_gmt, comment_post_id, comment_parent, comment_approved, user_id) VALUES (Author, Email, Content, Date, Date, PostID, ParentCom, Approved, UserID); END;

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

Так же можно установить значения для одной или нескольких переменных в результате выполнения запроса. Например, поля: Автор, почта и id пользователя хранятся в таблице wp_users.

Зная это можно установить значения для этих переменных следующим образом:

BEGIN -- Объявляем переменные DECLARE Author tinytext DEFAULT "admin"; DECLARE UserID bigint(20) DEFAULT 1; DECLARE Email varchar(100); -- выполнение запроса и установка значений для переменных SELECT user_login, user_email, ID INTO Author, Email, UserID FROM wp_users WHERE user_login LIKE "adm%"; END;

Вызов хранимой процедуры

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

Затем узнаем id добавленного комментария

Возвращаемся на вкладку Routines и нажимаем на надпись Execute

Появится форма

Указываем значения передаваемых параметров: текст ответа и id комментария, после чего нажимаем на кнопку с надписью Go.

Современная база данных MySQL не критична к количеству записей. В контроле выхода за допустимые границы количества строк редко возникает необходимость.

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

Синтаксис функции и пример использования

Функция count MySQL используется непосредственно в запросе к базе данных. У функции есть всего две основных формы применения: все записи или только конкретные. Есть только один существенный фактор - выбираемая строка по полю, которое входит в выражение count(), не должна иметь значение NULL.

В приведённом примере функция count MySQL используется без условий. Следует обратить внимание, что использование count (*) - это обращение ко всем записям таблицы и совершенно не имеет значения, что в некоторых записях может быть значение NULL. Запрос, содержащий count(*) выдаст всегда всё количество записей, которое содержится в таблице.

Разработчик может предусмотреть смысл выражения:

  • count(...) as result.

Но оно будет иметь больше наглядное значение, нежели практическое.

Безопасность PHP & MySQL: count() - на практике

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

Есть только два самых надёжных и безопасных барьера на пути любого злоумышленника:

  • незнание;
  • отклонение.

Первый барьер - самый железобетонный. Можно строить догадки о чём угодно, но, если не знаешь куда, зачем и каким образом, - эффекта не будет никогда. Всегда нужна дверь, которую следует открыть, ключ к ней и уважительная причина, чтобы заниматься этим.

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

Простроив таблицу безопасности таким образом, чтобы каждый вход/выход сотрудника компании отмечался состоянием NULL или не NULL, можно контролировать все отклонения, которые происходят в течение рабочего времени дня. Естественно выходные, праздничные и нерабочее время рабочего дня должны сбрасывать все записи таблицы безопасности в значение NULL.

Даже при такой примитивной логике можно заметить и предотвратить любое непредвиденное вторжение самым простым способом, без особых затрат. Чем проще и незаметнее защита, тем сложнее построить вторжение.

Условия и особые случаи

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

Результат исполнения всех запросов соответствует условию. При этом использование запроса:

  • select param1 + param2 + param3 from `ex_count` where count(*)

эквивалентно запросу

  • select count(*) from `ex_count` where (param1 + param2 + param3) > 0.

Функция count MySQL допускает различные варианты применения, в том числе во вложенных запросах. Однако всегда следует принимать во внимание: простота - залог успеха. Функция подсчета количества записей по тем или иным условиям слишком проста, но не следует её применение делать слишком сложным.

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

Эта статья также доступна на следующих языках: Тайский

  • Next

    Огромное Вам СПАСИБО за очень полезную информацию в статье. Очень понятно все изложено. Чувствуется, что проделана большая работа по анализу работы магазина eBay

    • Спасибо вам и другим постоянным читателям моего блога. Без вас у меня не было бы достаточной мотивации, чтобы посвящать много времени ведению этого сайта. У меня мозги так устроены: люблю копнуть вглубь, систематизировать разрозненные данные, пробовать то, что раньше до меня никто не делал, либо не смотрел под таким углом зрения. Жаль, что только нашим соотечественникам из-за кризиса в России отнюдь не до шоппинга на eBay. Покупают на Алиэкспрессе из Китая, так как там в разы дешевле товары (часто в ущерб качеству). Но онлайн-аукционы eBay, Amazon, ETSY легко дадут китайцам фору по ассортименту брендовых вещей, винтажных вещей, ручной работы и разных этнических товаров.

      • Next

        В ваших статьях ценно именно ваше личное отношение и анализ темы. Вы этот блог не бросайте, я сюда часто заглядываю. Нас таких много должно быть. Мне на эл. почту пришло недавно предложение о том, что научат торговать на Амазоне и eBay. И я вспомнила про ваши подробные статьи об этих торг. площ. Перечитала все заново и сделала вывод, что курсы- это лохотрон. Сама на eBay еще ничего не покупала. Я не из России , а из Казахстана (г. Алматы). Но нам тоже лишних трат пока не надо. Желаю вам удачи и берегите себя в азиатских краях.

  • Еще приятно, что попытки eBay по руссификации интерфейса для пользователей из России и стран СНГ, начали приносить плоды. Ведь подавляющая часть граждан стран бывшего СССР не сильна познаниями иностранных языков. Английский язык знают не более 5% населения. Среди молодежи — побольше. Поэтому хотя бы интерфейс на русском языке — это большая помощь для онлайн-шоппинга на этой торговой площадке. Ебей не пошел по пути китайского собрата Алиэкспресс, где совершается машинный (очень корявый и непонятный, местами вызывающий смех) перевод описания товаров. Надеюсь, что на более продвинутом этапе развития искусственного интеллекта станет реальностью качественный машинный перевод с любого языка на любой за считанные доли секунды. Пока имеем вот что (профиль одного из продавцов на ебей с русским интерфейсом, но англоязычным описанием):
    https://uploads.disquscdn.com/images/7a52c9a89108b922159a4fad35de0ab0bee0c8804b9731f56d8a1dc659655d60.png