MySQL / 9. Получение и использование метаданных

Создание приложений, адаптирующихся к версии сервера MySQL

Задача
Вы хотите использовать некоторую возможность, которая доступна только начиная с какой-то версии MySQL.

Решение
Запросите версию сервера. Если она слишком старая, вероятно, удастся вернуться назад и использовать обходной маневр, существовавший ранее (если такой был).

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

Чтобы узнать версию сервера, создайте предложение SELECT VERSION(). Результатом будет символьная строка, похожая на 3.23.27-gamma. Другими словами, возвращается строка, состоящая из старшего, младшего и самого младшего номеров версии, возможно, с каким-то суффиксом. Строку версии можно использовать для отображения, если вы хотите выводить для пользователя строку состояния. Однако для сравнения удобнее работать с числами, в частности, с пятизначным числом в формате Mmmtt, где M, mm, tt – это старший,
младший и самый младший номера версии. Преобразование можно выполнить, разбив строку по точкам, отделив от третьей части суффикс, который начинается с первого нецифрового символа, и объединив затем фрагменты.

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

sub get_server_version
{
my $dbh = shift;
my ($ver_str, $ver_num);
my ($major, $minor, $teeny);
# извлекаем результат в скалярную строку
$ver_str = $dbh->selectrow_array ("SELECT VERSION()");
return undef unless defined ($ver_str);
($major, $minor, $teeny) = split (/\./, $ver_str);
$teeny =~ s/\D*$//; # отбрасываем нечисловой суффикс, если такой есть
$ver_num = $major*10000 + $minor*100 + $teeny;
return ($ver_str, $ver_num);
}

Чтобы сразу получить информацию о версии в двух формах, вызовем функцию так:

my ($ver_str, $ver_num) = get_server_version ($dbh);

Чтобы вывести только одно из значений, вызов должен быть таким:

my $ver_str = (get_server_version ($dbh))[0]; # строковый формат
my $ver_num = (get_server_version ($dbh)); # числовой формат

Приведем примеры использования числового значения версии для проверки
того, поддерживает ли сервер какие-то функции:

my $ver_num = (get_server_version ($dbh));
printf "GET_LOCK()/RELEASE_LOCK(): %s\n",      ($ver_num >= 32127 ? "yes" : "no");
printf "Functional GRANT statement: %s\n",         ($ver_num >= 32211 ? "yes" : "no");
printf "Temporary tables: %s\n",                            ($ver_num >= 32302 ? "yes" : "no");
printf "Quoted identifiers: %s\n",                           ($ver_num >= 32306 ? "yes" : "no");
printf "UNION statement: %s\n",                           ($ver_num >= 40000 ? "yes" : "no");
printf "Subselects: %s\n",                                      ($ver_num >= 40100 ? "yes" : "no");

Статьи по MySQL на эту тему:

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