Введение в mysql (используя perl dbi)


Содержание

Ускорение доступа к базе данных MySQL с использованием Perl и DBI

Я новичок в Perl, и я хочу кэшировать результаты программы Perl, чтобы избавиться от загрузки сервера базы данных.

Я думаю, чтобы реализовать кеш файл для этого (но не на основе кеширования на базе сервера, например memcached), или, может быть, если вы порекомендуете что-то лучше.

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

Я думал создать файл CSV, но, похоже, это сложнее.

Эта программа проверяет IP-адрес пользователя, если IP существует в базе данных, пользователю предоставляется доступ.

Ваш вопрос очень неясен, так как вы не говорите, что именно вы хотите ускорить или почему.

Пример кода, который вы показываете, является ошибочным, следующим образом

Вы должны всегда use strict и use warnings в верхней части каждой программы Perl, которую вы пишете. Вам также нужно будет объявить каждую используемую вами переменную, которую вы, кажется, делаете хорошо

Использование require для включения некоторого внешнего кода немного неудобно, и лучше написать правильный модуль — возможно, используя Exporter чтобы сделать определенные подпрограммы доступными для вызывающего кода

Гораздо более выразительно заменить $|=1 на STDOUT->autoflush , который отлично работает, если вы use IO::Handle . Каждая версия Perl с 14 имеет IO::File по умолчанию, поэтому вам даже не нужно писать use

Никогда не пишите подпрограммы Perl прототипом. Это та часть, которая выражает параметры, которые ожидает подпрограмма. В вашем случае у вас есть sub valid() <. >, который настаивает на том, что valid будет принимать никаких параметров; но вы вызываете его позже с if (&valid($result))

Никогда не используйте & для вызова подпрограммы. Что-то вроде &shellwords следует использовать только тогда, когда вы обрабатываете подпрограмму как данные, например, чтобы получить ссылку подпрограммы, подобную этой

Среди прочего, & приставка имеет эффект игнорирования любых подпрограмм прототипов. Поэтому, даже если вы определили valid , не имеют никаких параметров, вы, возможно, видели его работу, потому что вы назвали его &valid($result) .

Хотя в этом случае, кажется, работают две ошибки, они определенно не делают права!

После этого возникает ряд семантических проблем.

Вы надеетесь ускорить свое программное обеспечение путем кэширования результатов, но ваша valid подпрограмма connect , prepare , execute каждый раз, когда она вызывается. Он также интерполирует значение $ip в исполняемый оператор SQL: что-то, что ядовито в общедоступных сетях, и поэтому легко избежать того, что вы должны инвестировать в использование стиля заполнителя во всем мире. Это даст вам лучшую безопасность и сделает ваш код более читабельным и поддерживаемым.

Я не уверен, почему вы используете eval вокруг вызова fetchrow_arrayref . Он убьет программу только в том случае, если вы захотите индексировать ее как массив без проверки ее значения.

Вот рефакторинг кода, который вы показываете. Может быть, вообще не нужна политика кэширования?

Я надеюсь, что это ясно, что я предположил, что shellwords.pl будет правильно переписан как модуль в ShellWords.pm . Все, что находится внутри shellwords.pl использует значения многих переменных, которые доступны только в правильном контексте и не передаются параметром.

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

14.10. Выполнение команд SQL с помощью DBI и DBD

14.10. Выполнение команд SQL с помощью DBI и DBD

Проблема

Решение

Комментарий

DBI является посредником между программой и всеми драйверами, предназначенными для работы с конкретными СУБД. Для большинства операций нужен манипулятор базы данных (в приведенном выше примере — $dbh).0n ассоциируется с конкретной базой данных и драйвером при вызове DBI->connect.
Первый аргумент DBI->connect представляет собой строку, состоящую из трех полей, разделенных двоеточиями. Он определяет источник данных — СУБД, к которой вы подключаетесь. Первое поле всегда содержит символы DBI, а второе — имя драйвера, который вы собираетесь использовать (Oracle, mysql и т. д.). Оставшаяся часть строки передается модулем DBI запрошенному модулю драйвера (например, DBD::mysql) и идентифицирует базу данных. Второй и третий аргументы выполняют аутентификацию пользователя. Четвертым, необязательным аргументом является ссылка на хэш с определением <>трибутов подключения. Если атрибут PrintError равен true, при каждом неудачном вызове метода DBI будет выдавать предупреждение. Присваивание RaiseError имеет аналогичный смысл, за исключением того, что вместо warn будет использоваться die.
Простые команды SQL (но возвращающие записи данных) могут выполняться методом do манипулятора базы данных. При этом возвращается логическая истина или ложь. Для команд SQL, возвращающих записи данных (например, SELECT), необходимо сначала вызвать метод prepare манипулятора базы данных, чтобы создать манипулятор команды. Далее запрос выполняется методом execute, вызванным для манипулятора команды, а записи извлекаются методами выборки fetchrow_array или fetchrow_hashref (возвращает ссылку на хэш. в котором имя поля ассоциируется со значением).
После завершения работы с базой не забудьте отключиться от нее методом disconnect. Если манипулягор базы данных выходит из области действия без предварительного вызова disconnect, модуль DBI выдает предупреждение. Эта мера предосторожности предназначена для тех СУБД, которые должны возвращать память системе и требуют корректного отключения от сервера. Перед отключением манипулятора базы данных манипуляторы команд должны получить неопределенное значение, выйти из области действия или для них должен быть luii.n^in метод finisri. Если этого не сделать, вы получите предупреждение следующего вида: disconnect(OBI::db-HA8H(Ox9df84)) invalidates 1 active cursor(s) at -e line 1, Модуль DBI содержит ‘FAQ(perldocDBI::FAQ) и стандартную документацию (j/ei’ldoc DBF). Также существует документация для драйверов конкретных СУБД (например, perldoc. DBD-.-.inysq!’). Прикладной интерфейс DBI не ограничивается простейшим подмножеством, рассмотренным памп: он предоставляет разнообразные возможности выборки результата и взаимодействия со специфическими средствами конкретных СУБД (например, сохраняемыми процедурами). За информацией обращайтесь к документации по модулю драйж;рн. Программа ил примера 14.7 создае! и заполняет таблицу пользователей в MySQL, после чего выполняет в ней поиск. Она использует атрибут RaiseError к потому обходится без проверки возвращаемого значения для каждого метода-Пример 14.7. dbusers

> Смотри также ——————————-
Документация по DBI и модулям DBD с CPAN, http://www.hef7netica.com/ technologia/perl/DBI/index.html и http://www.perl/com/CPAN/modules/by-category/ О 7 _Database interfaces/.

14.11. Программа: ggh — поиск в глобальном журнале Netscape

s/ at \w+ line \d+\.//;
die «$0: bad pattern $@>»;
>
require DB_File; DB_File->import();
# Отложить загрузку до выполнения
$1=1; # Для перенаправления данных
$dotdir = $env || $env;
$HISTORY = $opt_database || «$dotdir/.netscape/history.db»;
die «no netscape history dbase in $HISTORY: $!» unless -e $HISTORY;
die «can’t dbmopen $HISTORY: $!» unless dbmopen %hist_db, $HISTORY, 0666;
# Следующая строка — хак, поскольку программисты С,
# которые работали над этим, путали strlen и strlen+1.
# Так мне сказал jwz :-)
$add_nulls = (ord(substr(each %hist_db, -1)) == 0);
# XXX: Сейчас следовало бы сбросить скалярные ключи, но
# не хочется тратить время на полный перебор, И необходимый для связанных хэшей,
# Лучше закрыть и открыть заново?
$nulled_href = «»;
$byte_order = «v»; # На pc не понимают «n» (сетевой порядок)
if (@>ARGV) <
foreach $href (@ARGV) <
$nulled_href = $href . ($add_nulls && «\0»);
unless ($binary_time = $hist_db<$nulled_href>) < warn "$0: no history entry for href
$href\n»;
next;
> $epoch_secs = unpack($byte_order, $binary_time);
$stardate = $opt_epochtime ? $epoch_secs
: $opt_gmtime ? gmtime $epoch_secs : localtime $epoch_secs;
print «$stardate $href\n»;
>
> else <
while ( ($href, $binary_time) = each %hist_db ) <
chop $href if $add_nulls;
# gnat reports some binary times are missing
$binary_time = pack($byte_order, 0) unless $binary_time;
$epoch_secs = unpack($byte_order, $binary_time):
$stardate = $opt_epochtime ? $epoch_secs
: $opt_gmtime ? gmtime $epoch_secs : localtime $epoch_secs;
print «$stardate $href\n» unless $pattern && $href !

/$pattern/o;
>
>
sub usage <
print STDERR «@_\n» if (o)_
die $USAGE:
>

Perl и MySQL

Язык программирования Perl превратился из инструмента, используемого преимущественно администраторами Unix-систем, в наиболее распространенную платформу разработки для World W >Web . Perl не предназначался изначально для Web , но простота его использования и мощные функции для работы с текстом сделали естественным его применение для CGI -программирования. Сходным образом, когда mSQL впервые появилась на сцене, исключительные компактность и скорость выполнения сделали ее очень привлекательной для разработчиков Web , которым требовалось обслуживать ежедневно тысячи операций. MySQL со своей высокой скоростью и расширенными возможностями стала еще более привлекательным средством для веб-разработчиков. Естественно поэтому, что был разработан интерфейс Perl к обеим базам — MySQL и mSQL, — объединив таким образом их достоинства.

В то время, когда писался этот материал, существовали два интерфейса между Perl и MySQL с mSQL. Более ранний состоит из специализированных интерфейсов Myaql.pm и Msql.pm, которые работают только с MySQL и mSQL соответственно. Другой, более новый интерфейс является подключаемым модулем в комплекте DBI ( DataBase Independent) — независимых от базы данных модулей. DBI является попыткой обеспечить общий Perl API для доступа к любым базам данных и предоставления более высокой переносимости. Интерфейс DBI стал наиболее надежным и стандартным, и разработчики MySQL рекомендуют пользоваться только DBI , поскольку дальнейшая разработка модулей Mysql .pm и Msql.pm прекращена. Именно о DBI мы и расскажем здесь.

Рекомендуемым методом доступа к базам данных MySQL и mSQL из Perl является интерфейс DBD/ DBI . DBD/ DBI означает DataBase Dependent / DataBase Independent (Зависимый от базы данных /Независимый от базы данных ). Название связано с двухъярусной реализацией интерфейса. В нижнем ярусе находится зависимый от базы данных уровень. На нем существуют свои модули для каждого типа базы данных , доступного из Perl. Поверх этого уровня находится независимый от базы данных уровень. Это тот интерфейс , которым вы пользуетесь при доступе к базе данных. Выгода такой схемы в том, что программисту нужно знать только один API уровня независимости от базы данных . Когда появляется новая база данных , кому-нибудь нужно лишь написать для нее модуль DBD (зависимый), и она станет доступна всем программистам, использующим DBD/ DBI .

Как и в любом модуле Perl, для получения доступа нужно указать DBI в директиве use :

При запуске программ Perl для MySQL /mSQL следует всегда задавать аргумент командной строки -w . Благодаря этому DBI будет перенаправлять все специфические для MySQL и mSQL сообщения об ошибках на STDERR , и вы сможете увидеть ошибки, вызванные работой с базой данных, не прибегая к явной проверке их в программе.

Илон Маск рекомендует:  Атрибут scrolldelay в HTML

Всякое взаимодействие между Perl, с одной стороны, и MySQL и mSQL — с другой, производится с помощью объекта, известного как описатель базы данных ( handle ). Описатель базы данных ( database handle ) — это объект , представленный в Perl как скалярная ссылка и реализующий все методы, используемые для связи с базой данных. Одновременно можно открыть любое число описателей базы данных , ограничение накладывают только ресурсы системы. Метод connect() использует для создания описателя формат соединения DBI :servertype:database:hostname:port ( имя узла и порта необязательны), дополнительными аргументами служат имя пользователя и пароль :

Атрибут servertype является именем специфического для базы данных DBD-модуля, в нашем случае » mysql » или «mSQL» (обратите внимание на точное использование регистра). В первом варианте создается соединение с сервером MySQL на локальной машине через сокет Unix. Это наиболее эффективный способ связи с базой данных, который должен использоваться при соединении на локальном сервере. Если указано имя узла , оно используется для соединения с сервером на этом узле через стандартный порт , если только не задан и номер порта . Если при соединении с сервером MySQL вы не указываете имя пользователя и пароль , то пользователь , выполняющий программу, должен обладать достаточными привилегиями в базе данных MySQL . Для баз данных mSQL имя пользователя и пароль не должны указываться.

В Perl 5 используются два соглашения по вызову модулей. В объектно-ориентированном синтаксисе для ссылки на метод определенного класса используется символ стрелки «->» (как в DBI ->connect ). Другой метод — использование непрямого синтаксиса, в котором за именем метода следует имя класса , а затем — аргументы. В последнем примере метод connect следовало бы записать как connect DBI ‘ DBI :mysql:mydata’, ‘me’, ‘ mypass . В ранних версиях Msql.pm использовался исключительно непрямой синтаксис , и требовалось придерживаться метода использования заглавных букв, обусловленного mSQL С API . Поэтому значительная часть старого кода MsqlPerl содержит строки типа SelectDB $dbh ‘test’ там, где можно было бы написать проще: $dbh->selectdb(‘test’). Если вы еще не догадались, то сообщаем, что мы неравнодушны к объектно-ориентированному синтаксису, хотя бы потому, что использование стрелки делает ясной связь между классом и методом.

Как только вы соединились с сервером MySQL или mSQL, описатель базы данных — во всех примерах этого раздела $dbh — становится шлюзом к базе данных. Например, так готовится запрос SQL :

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

Для иллюстрации использования DBI рассмотрим следующие простые программы. В примере 1 datashow.cgi принимает в качестве параметра имя узла ; при отсутствии параметра принимается имя » local-host «. Затем программа выводит список всех баз данных, имеющихся на этом узле.

Пример 1. Программа CGI datashow.cgi показывает все базы данных , имеющиеся на сервере MySQL или mSQL

В примере 2 tableshow.cgi принимает в качестве параметров имя сервера базы данных (по умолчанию » localhost «) и имя базы данных на этом сервере. Затем программа показывает все таблицы, имеющиеся в этой базе данных.

Пример 2. Программа CGI tableshow.cgi выводит список всех таблиц в базе данных

И наконец, пример 3 показывает, как вывести все сведения о некоторой таблице.

Записки *NIX Админа

четверг, 14 июня 2012 г.

Работа с Mysql в Perl (модуль Mysql)

Очень часто приходиться писать различные скрипты на perl.
Большинство скриптов берет или пишет какие либо данные в БД.
Самой популярной БД является MySql, поэтому я опишу основные моменты, как это делать в perl.
Примечание: используемая ОС — Gentoo, но справедливо для любой Linux или *BSD системы.

Необходимые компоненты:

  • Собственно сам Perl. Ставится просто:
  • А также необходимые модули. Проще всего ставить через CPAN.
    Главный модуль, который нам нужен — это Mysql.
    Он же, в свою очередь требует включения DBI и DBD::mysql.
    Модуль YAML (аналог XML) нужен для большинства модулей
    Можно либо ставить каждый модуль отдельно следующим образом: или получить shell и выполнить в интерактивном режиме установку в нем Примечание: Возможно понадобится использовать «force install [module]». Все модули должны ставиться под root либо пользователя с соответствующими правами. Рабочая папка для сборки библиотек —

/.cpan.

  • Если у Вас выбиват при запуске программы ошибку то нужно сделать
  • Подключение модуля:

    Connect

    Эта команда устанавливает соединение с сервером и базой данных.
    Без аргумента или с пустой строкой в качестве первого аргумента он связывается с устройством UNIX /dev/mysql, который сильно повышает эффективность.
    Имя базы данных во втором аргументе указывает с какой именно базой данных надо связаться.
    Возвращается дескриптор базы данных, если команда Connect выполнена успешно.
    В противном случае возвращаемое значение не определено.
    Если Вы используете mysqld, скомпилированный с библиотекой потоков MIT, Вы не сможете использовать устройства. В этом случае укажите имя сервера в переменной host.
    А вообще библиотека потоков MIT такое глюкало.

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

    Возвращаемый дескриптор нужен для обращения к базе данных.
    Можно отдать несколько команд Connect переменных ($dbh1,$dbh2, $dbh3, . )

    Из полученного дескриптора можно извлечь сведения о имени сервера, порте и имени базы данных:
    Имя базы данных не определено, если при вызове команды Connect было указано только имя сервера.

    Смена порта

    Сменить порт, к которому присоединился MysqlPerl можно так:

    SelectDB

    Выбор базы данных для использования.

    Если база данных не выбрана в команде Connect, или если нужно связаться с другой базой данных, то используется дескриптор базы данных из предыдущего вызова команды Connect. Он используется командой SelectDB.

    ListDBs

    Список доступных баз данных.
    СИНТАКСИС:

    ОПИСАНИЕ:
    ListDBs возвращает массив, который содержит один элемент для имени каждой базы данных, управляемой MySQL.
    ПРИМЕР:

    ListTables

    Список таблиц, доступных в базе данных.

    ОПИСАНИЕ:
    Возвращает массив с одним элементом для каждого имени таблицы в базе данных. Вы должны были, определить базу данных при вызове Connect или SelectDB.
    ПРИМЕР:

    ListFields

    Список полей в таблице.
    СИНТАКСИС:

    ОПИСАНИЕ:
    ListFields возвращает операторный дескриптор, который может использоваться, чтобы выяснить, что именно сервер должен Вам передать. В случае ошибки возвращаемое значение не определено.

    MySQL ListFields не работает так же как mSQL ListFields. В MySQL Вы используете следующие команды, чтобы получить информацию после вызова ListFields.

    Перед использованием следующих функций, Вы должны выполнить успешное обращение к ListFields.

    @arr = @<$sth->name>; Возвращает массив имен столбцов
    @arr = @<$sth->length>; Возвращает массив длин столбцов
    $value = $sth->numfields; Возвращает количество столбцов в таблице
    @arr = @<$sth->type>; Массив MySQL типов
    @arr = @<$sth->is_num>; Массив 0 и 1, где 1 указывает что столбец числовой
    @arr = @<$sth->is_blob>; Массив 0 и 1, где 1 указывает что столбец — blob
    @arr = @<$sth->is_not_null>; Массив 0 и 1, где 1 указывает что столбец — не NULL

    Query

    Выполнить запрос.
    СИНТАКСИС:

    ОПИСАНИЕ:
    Эта функция позволяет Вам посылать запрос базе данных. Вы должны использовать FetchRow, чтобы получить результат.

    ПРИМЕР:
    Хорошая идея — всегда проверить ошибки. В этом примере такой проверкой занимается блок «or die. » оператора Query.

    FetchCol

    Возвращает массив, содержащий один столбец, состоящий из значений.
    СИНТАКСИС:
    ОПИСАНИЕ:
    Возвращает массив значений для столбца номер $col. FetchRow возвращает следующую строку результата запроса. FetchCol возвращает весь одиночный столбец результата запроса.

    Обратите внимание, что эта функция сбросит текущий указатель строки на конец таблицы; вы должны использовать DataSeek(0), чтобы переустановить его.

    FetchHash

    Возвращает результат запроса.
    СИНТАКСИС:


    ОПИСАНИЕ:
    Возвращает ассоциативный массив, содержащий следующую строку, полученную с сервера.

    FetchRow

    Возвращает строку результатов.
    СИНТАКСИС:
    ОПИСАНИЕ:
    Возвращает массив значений следующей строки, полученной с сервера.

    Пример
    Выводит описание структуры таблицы TABLE_NAME

    DataSeek

    Обработка двоичных строк

    Некоторых символов нужно избежать прежде, чем двоичные строки могут быть вставлены в базу данных MySQL. MySQL perl API обеспечивает следующую функцию, чтобы делать это автоматически.

    ОПИСАНИЕ:
    Конвертирует строку: пропускает все символы ‘ и \, а также конвертирует \0 и \n.

    Потерянные значения

    Операторный дескриптор

    Два конструктора возвращают операторный дескриптор:
    $sth хранит все метаданные, предоставляемые API:

    Введение в mysql (используя perl dbi)

    Унифицированные методы DBI

    Метод Описание
    connect Создает соединение с сервером
    disconnect Разрывает соединение с сервером
    prepare Готовит SQL-запрос к выполнению
    execute Выполняет приготовленный запрос
    do Готовит и выполняет запрос
    quote Заключает в символы цитирования строки или BLOB -значения, которые вы собираетесь внести
    fetchrow_array Возвращает следующую запись как массив
    fetchrow_arrayref Возвращает следующую запись как ссылку на массив
    fetchrow_hashref Возвращает следующую запись как ссылку на хеш
    fetchall_arrayref Возвращает всю информацию как массив массивов
    finish Завершает выражение и освобождает системные ресурсы
    rows Возвращает количество измененных/удаленных строк
    data_sources Возвращает массив, список баз данных, доступных на сервере
    ChopBlanks Определяет, будут ли методы fetchrow_* убирать начальные и оконечные пробелы
    NUM_OF_PARAMS Количество символов-заполнителей в приготовленном выражении
    NULLABLE Возвращает ссылку на массив значений, которые определяют, могут ли столбцы содержать значения NULL . Возможные значения для каждого элемента массива: 0 или пустая строка, если столбец не может быть NULL , 1 — если может, и 2, если статус NULL для столбца неизвестен
    trace Производит трассировку для отладки

    Методы, определенные только для MySQL

    Метод Описание
    insrtid Значение AUTO_INCREMENT , которое было присвоено последним
    is_blob Какие столбцы имеют тип BLOB
    is_key Какие столбцы являются ключами
    is_num Какие столбцы имеют числовой тип
    is_pri_key Какие столбцы являются первичными ключами
    is_not_null Столбцы, которые НЕ МОГУТ иметь значение NULL . См. NULLABLE
    length Максимально допустимые размеры содержимого столбцов
    max_length Максимальные размеры столбцов, присутствующих в результате
    NAME Имена столбцов
    NUM_OF_FIELDS Количество полей, возвращенных в результате операции
    table Имена таблиц в результате
    type Типы всех столбцов

    Более детально методы Perl DBI описаны в следующих разделах. Возвращаемые переменные:

    Дескриптор базы данных

    Код возврата (часто статус)

    Возвращенное значение (часто количество строк)

    Унифицированные методы DBI

    connect($data_source, $username, $password)

    Метод connect используется для подсоединения к источнику данных (СУБД). Строка $data_source должна начинаться с DBI:имя драйвера: . Примеры вызова connect с драйвером DBD::mysql :

    Если не определены имя пользователя либо пароль, DBI использует значения переменных окружения DBI_USER и DBI_PASS . Если не указано имя хоста, используется значение по умолчанию — localhost . Если не указан номер порта, также используется значение по умолчанию (3306).

    Начиная с Msql-Mysql-modules версии 1.2009, доступны следующие модификаторы $data_source :

    Читать файл file_name как файл настроек. За более подробной информацией о файлах настройки обращайтесь к разделу See Раздел 4.1.2, «Файлы параметров my.cnf ».

    По умолчанию используется группа [client] файла настроек. Опцией mysql_read_default_group , группа по умолчанию устанавливается в [group_name] .

    Использовать сжатие при обмене клиента и сервера (MySQL версий 3.22.3 и выше).

    Указывает путь к Unix-сокету, который будет использоваться для соединения с сервером. (MySQL версии 3.21.15 и более поздние).

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

    Например, если вы не хотите явно указывать имя пользователя и пароль в программе, использующей DBI , можно внести эту информацию в файл

    /.my.cnf , написав вызов connect . Это делается следующим образом:

    Данный пример считает настройки из группы [client] файла

    /.my.cnf . Чтобы выполнить те же действия, но с настройками, взятыми из группы [perl] , нужно использовать следующую форму записи:

    Метод disconnect разрывает соединение с базой данных. Это стоит делать перед выходом из программы. Пример:

    Подготавливает SQL-запрос $statement к исполнению сервером. Возвращает дескриптор выражения ( $sth ), который затем используется для вызова метода execute . Обычно работа с запросами типа SELECT (так же, как и аналогичными, такими как SHOW , DESCRIBE , EXPLAIN ) сводится к вызову методов prepare и execute . Пример:

    Если вы хотите считывать большие результаты вашим клиентом, вы можете указать использование mysql_use_result() в Perl:

    Метод execute выполняет приготовленный запрос. Если запрос не SELECT , метод возвращает количество строк, которые были подверглись воздействию запроса. Если таковых нет, execute возвращает «0E0″ , что Perl интерпретирует как нуль, но воспринимает как значение «истина» (true). Если возникает ошибка, execute возвращает undef . Для запросов SELECT метод только инициирует выполнение запроса SQL-сервером и для получения данных необходимо использовать один из методов fetch_* . Пример:

    Метод do готовит SQL-запрос к выполнению, выполняет его и возвращает количество строк, подвергшихся воздействию. Если нет ни одной такой строки, как результат возвращается значение «0E0″ , что Perl интерпретирует как нуль, но воспринимает как значение «истина» (true).. Этот метод обычно используется для выражений, не являющихся операторами SELECT , которые не могут быть подготовлены заранее (из-за ограничений драйвера) или же выполняются только один раз (операции вставки, удаления и т.д.). Например:

    Обычно использование ‘do’ существенно быстрей (и предпочтительней) для запросов без параметров, чем пара prepare / execute .

    Метод quote используется для экранирования специальных символов в запросе символами экранирования, а также заключения данных в необходимые внешние символы цитирования (например кавычки). Пример:

    Этот метод выбирает очередную строку данных и возвращает ее как массив значений полей. Пример:

    Этот метод выбирает очередную строку данных и возвращает ссылку на массив значений полей. Пример:

    Этот метод выбирает строку данных и возвращает ссылку на хеш, содержащий пары имя/значение. Данный метод намного менее эффективен, чем использование пописанных выше ссылок на массивы. Пример:

    Этот метод выдает все данные (все строки), получаемые как результат SQL-запроса. Он возвращает ссылку на массив ссылок на массивы отдельных строк. Соответственно, для обращения к этим данным нужно использовать вложенный цикл. Пример:

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

    Возвращает число измененных/удаленных последней командой ( UPDATE , DELETE и т.д.) строк. Это обычно требуется после выполнения метода execute над запросами, не являющимися запросами SELECT . Например:

    Возвращает ссылку на массив значений, которые указывают, может столбец принимать значения NULL или нет. Возможные значения для каждого элемента массива — это 0 или пустая строка, если столбец не может содержать значения NULL , 1 — если может и 2 — если статус столбца относительно значения NULL не определен.

    Значение этого атрибута равно числу полей в результате запроса ( SELECT или SHOW FIELDS ). Его можно использовать его для проверки, возвращает ли запрос результат вообще: нулевое значение соответствует запросам типа INSERT , DELETE , UPDATE — т.е. всем, кроме SELECT . Например:

    Этот метод возвращает массив с именами баз данных, доступных на локальном MySQL-сервере (на localhost ). Пример:

    Этот атрибут определяет, будут ли методы fetchrow_* убирать начальные и оконечные пробелы из результатов. Пример:

    trace($trace_level) , trace($trace_level, $trace_filename)

    Метод trace разрешает или запрещает трассировку. Если он вызывается как метод класса DBI , он влияет на разрешение трассировки всех дескрипторов. В случае же обращения к нему как к методу дескриптора запроса либо базы данных он разрешает/запрещает трассировку для этой базы данных или этого запроса (и всех будущих потомков). $trace_level указывает уровень детализации трассировочной информации, так установка $trace_level в 2 включает детализированную трассировку. Установка $trace_level в 0 запрещает трассировку. По умолчанию вывод трассировочной информации осуществляется на стандартное устройство вывода ошибок ( stderr ). Если указан параметр $trace_filename , его значение используется как имя файла, в который выводится трассировочная информация ВСЕХ дескрипторов, для которых разрешена трассировка. Пример:

    Трассировку DBI можно также включить при помощи переменной окружения DBI_TRACE . Присвоение числового значения эквивалентно вызову DBI->trace(значение) . Строковое значение (имя файла) эквивалентно вызову DBI->trace(2,значение) .

    Методы, специфичные для MySQL

    Описанные здесь методы специфичны для MySQL и не являются частью стандарта DBI . Сейчас считается, что часть из них использовать не стоит: is_blob , is_key , is_num , is_pri_key , is_not_null , length , max_length и table . Ниже указаны возможные стандартные альтернативы, если они существуют:

    Если вы используете специфичную для MySQL функцию AUTO_INCREMENT , здесь будут сохраняться автоматически увеличенные значения. Пример:

    В качестве альтернативы можно использовать $dbh -> <'mysql_insertid'>.

    Возвращает ссылку на массив булевых значений; для каждого элемента массива значение «истина» указывает, что соответствующий столбец имеет тип BLOB . Например:

    Возвращает ссылку на массив булевых значений; для каждого элемента массива значение «истина» указывает, что соответствующий столбец является ключом. Пример:

    Возвращает ссылку на массив булевых значений; для каждого элемента массива, значение «истина» указывает, что соответствующий столбец содержит числовые значения. Например:

    Возвращает ссылку на массив булевых значений; для каждого элемента массива, значение «истина» указывает, что соответствующий столбец является первичным ключом. Пример:

    Возвращает ссылку на массив б булевых значений; для каждого элемента массива значение «ложь» указывает на то, что столбец может содержать значения NULL . Например:

    is_not_null не рекомендуется к применению; предпочтительно использование NULLABLE (описан ранее), поскольку это стандартный для DBI метод.

    Каждый из этих методов возвращает ссылку на массив размеров столбцов. Массив, соответствующий length , содержит максимальные допустимые размеры каждого столбца (из описания таблицы). Массив max_length содержит максимальные размеры элементов, присутствующих в результирующей таблице. Например:

    Возвращает ссылку на массив имен столбцов. Например:

    Возвращает ссылку на массив названий таблиц. Например:

    Возвращает ссылку на массив типов столбцов. Пример:

    Ускорьте доступ к базе данных MySQL, используя Perl и DBI

    Я новичок в Perl, и я хочу кешировать результаты программы Perl, чтобы уменьшить нагрузку на сервер базы данных.

    Я подумываю реализовать для этого файловый кеш (но не серверные методы кэширования, такие как memcached) или, может быть, если вы порекомендуете что-нибудь лучше.

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

    Я думал сделать файл CSV, но кажется, что это сложнее.

    Эта программа проверяет IP пользователя, если IP существует в базе данных, пользователю предоставляется доступ.

    1 ответ

    Ваш вопрос очень неясен, так как вы не говорите, что именно вы хотите ускорить или почему.

    Пример кода, который вы показываете, имеет следующие недостатки:

    Вы всегда должны use strict и use warnings в верхней части каждой написанной вами Perl-программы. Вам также нужно будет объявить каждую переменную, которую вы используете, что у вас вроде бы хорошо

    Использование require для включения некоторого внешнего кода немного неудобно, и лучше написать правильный модуль — возможно, используя Exporter чтобы сделать определенные подпрограммы доступными для вызывающего кода.

    Гораздо более выразительно заменить $|=1 на STDOUT->autoflush , что прекрасно работает, если вы уже use IO::Handle . Каждая версия Perl начиная с 14 имеет IO::File требуемый по умолчанию, так что вам даже не нужно писать use

    Никогда не пишите подпрограммы Perl с прототипом. Это та часть, которая выражает, какие параметры ожидает подпрограмма. В вашем случае у вас есть sub valid() < . >, который настаивает на том, что valid будет принимать никаких параметров; но вы вызываете его позже с помощью if (&valid($result))

    Никогда не используйте & чтобы вызвать подпрограмму. Нечто подобное &shellwords следует использовать только тогда, когда вы рассматриваете подпрограмму как данные, например, чтобы получить ссылку на подпрограмму, подобную этой

    Помимо всего прочего, префикс & имеет эффект игнорирования любых прототипов подпрограмм. Вот почему, даже если вы определили valid как не имеющий параметров, вы, возможно, видели, как он работает, потому что вы назвали его с &valid($result) .

    Хотя в этом случае, кажется, работают две ошибки, они определенно не делают ошибку!

    После этого возникает ряд семантических проблем.

    Вы надеетесь ускорить работу вашего программного обеспечения за счет кэширования результатов, но ваша valid подпрограмма connect , prepare и execute каждом вызове. Он также интерполирует значение $ip в выполняемый оператор SQL: что-то ядовитое в общедоступных сетях, и его так легко избежать, что вы должны повсеместно использовать стиль заполнителя. Это обеспечит вам большую безопасность и сделает ваш код более читабельным и обслуживаемым.

    Я не уверен, почему вы используете eval для вызова fetchrow_arrayref . Это убьет программу, только если вы решите проиндексировать ее как массив без проверки его значения.

    Вот рефакторинг кода, который вы показываете. Может, вообще не нужна политика кэширования?

    Я надеюсь, что ясно, что я предположил, что shellwords.pl будет переписан как модуль в ShellWords.pm . Что бы ни было внутри shellwords.pl оно использует значения многих переменных, которые доступны только в правильном контексте и не передаются параметром.

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

    Введение в mysql (используя perl dbi)


    За последние 60 дней ни разу не выходила

    Сайт рассылки: http://perl.dp.ua
    Открыта: 03-12-2000

    Статистика

    Perl — подпишись и учись! — Introduction to MySQL(Using Perl DBI)

    Информационный Канал Subscribe.Ru

    Hi, All!
    Приветствую всех!(А именно 9440 подписчиков)

    Рад Вас приветствовать!
    По просьбе приятеля стояла задача перевода небольшой статейки о использовании MySQL(естественно с PERL). Разобью эту статейку на две рассылки. Надеюсь кому-то она будет полезна. Да, и ещё, некоторое время назад общался с людьми(из подписчиков), которые помогали мне с редактированием рассылки, так вот, обращаюсь к ним: «Люди, если Вы ещё здесь — откликнитесь :)), пожалуйста, нужна будет Ваша помощь, а emailы Ваши — растерял ввиду своей рассеянности.. :((»
    #форматироание — автора статьи, оригинал — http://www.danchan.com/feature/2000/10/16/mysql/mysql.htm

    Введение в MySQL (используя Perl DBI)

    Я считаю, что если название статьи не звучит для Вас чуждо, то, возможно, Вы в нужном месте.

    MySQL — это реляционная база данных. MySQL основана на технологии client/server. Все примеры команд MySQL в этой статье могут быть введены прямо в командную строку MySQL. MySQL поддерживает многострочные команды и использует точку с запятой, как разделитель между командами.

    Почему же MySQL, а ни другая база данных SQL?

    Хотя бы потому, что она бесплатна , быстра и имеет хорошую поддержку .

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

    Лучший способ для C программиста понять что же это такое:

    Каждый ряд — это структурная ссылка.

    Каждая колонка — это член этой структуры.

    Вот обычная структура (класс, объявленный с ключевым словом struct) в C:

    Это выглядит как информация, собранная Web-сайтом о пользователе.

    А вот MySQL версия этой структуры:

    Несколько похоже, не так ли?

    Вот как будет выглядеть ряд в MySQL:

    Что же тогда матрица? Вот данные в таблице(матрице) о трёх гипотетических пользователях:

    Фактически эти таблицы — это то, что вы увидете, если введёте в MySQL следующую команду:

    Звёздочка означает, что мы выбираем все колонки из таблицы.

    Таблица — это структурная основа многомиллиардной годовой индустрии баз данных, которая включает в себя такие компании, как Oracle и Informix.

    Простейшие команды MySQL

    Давайте быстро «пробежим» по простейшим командам MySQL. Вы уже занете команду create.

    А что же делать, если хотим увидеть только прозвища и любимые числа пользователей?

    Данная команда даст нам:

    А если хотим вывести прозвища пользователей, но с условием, что носков у них меньше, чем 10 пар и их любимое число больше, чем 100?

    Как же ввести данные в таблицу? Это просто.

    Да , но мы забыли добавить поле пароля в таблицу!

    Под NOT NULL понимается то, что поле должно нести в себе какие-либо данные. Поэтому в заданном выше примере MySQL выдаст ошибку. Поэтому следует сделать так:

    Результат будет следующим:

    Но подождите! Мы не определили id ! Оно также not null .

    В этом случае колонку id мы определили как auto_increment и MySQL сама создаёт значения для нас , добавляя 1 к наибольшему значению, которое найдёт в таблице ( Rolo имеет id == 3 ).

    Мы забыли ввести любимое число пользователя Cowlick . Которое, между прочим, -1 . Для этого мы будем использовать команду update.

    Также можем выполнить это следующим образом:

    Но вдруг у нас появится больше чем один пользователь с прозвищем Cowlick ? В нашем примере этого быть не может, т.к. в команде create table мы определили:

    Если мы попробуем ввести ещё одного пользователя с прозвищем Cowlick , то мы получим ошибку от MySQL.

    Предположим Вы имеете проблемы с пользователем Javier . Длугие члены вашего общества также считают, что этому пользователю не место среди них, Вы можете сделать следующее

    Если же Вы хотите удалить всю таблицу, то необходимо будет сделать следующее.

    Определение таблицы и все данные после вышеописанной команды будут удалены. Будьте осторожны с этой командой.

    Логические значения в MySQL, Perl DBI и JSON

    Рассмотрим простую таблицу mysql со столбцами id (целое число) и flag (логическое). Пользовательский интерфейс, написанный на JavaScript, связывается с CGI-сервером через JSON, как для приема данных из таблицы, так и для его обновления.

    Теперь, отправляя данные на сервер, я, конечно, использую from_json для получения хэша perl (ref). Тогда

    всегда приводит к введению ложного значения. Я считаю, что это из-за магического поведения JSON:: true и JSON:: false, которые строят соответственно «true» и «false» (но будут нумерации на 1 и 0). По-видимому, оператор execute предоставляет строковый контекст, а не числовой контекст, поэтому сервер mysql получает строку, не содержащую цифр, которая затем вызывает значение 0. На данный момент я исправляю это, помещая ? 1 : 0 после $data-> .

    В другом направлении происходит противоположное: согласно документу DBI, «Большинство данных возвращается в Perl script как строки.», поэтому, когда я нажимаю на результат запроса SELECT с помощью to_json , значения принимаются UI как строки JavaScript «0» и «1», которые являются истинными в JavaScript. Так что теперь я делаю $_-> += 0 foreach (@result) перед применением to_json .

    Вопрос: В какой точке (точках) в цепочке я должен вставить эти «хаки»? В конце JavaScript я мог бы, например, обязательно отправить значения 1 и 0 вместо true и false и перечитать флаги как числа. Есть ли что-то, что я могу сказать DBI, чтобы он возвращал числовые столбцы в виде (скаляры, которые JSON учитывал бы)?

    Был и сделал это. Первоначально я добавил 0 к номерам в JSON, которые мы расшифровали в Perl, но это было утомительно и требовало много времени, потому что мне пришлось перебирать большую структуру, добавляя 0 ко всем номерам. Затем я помог Tim Bunce добавить sql_type_cast в DBI, чтобы несколько незначительных изменений в DBD:: Oracle могли использовать его для возврата чисел вместо строк (они все еще являются скалярами Perl, но с некоторым внутренним мастерингом — см. ниже).

    Проблема была в том, что я использовал JSON:: XS и смотрел на скаляры в encode_json, чтобы убедиться, что pv или iv настроен на выбор, производить ли «0» или 0 в закодированном JSON. DBI sql_type_cast и новый атрибут DBIstcf_DISCARD_STRING означает, что теперь я связываю числовые столбцы как $s- > bind_col (1,\my $col, SQL_INTEGER, DiscardString = > 1>), и sql_type_cast удаляет скалярный pv, если он выглядит число. Проблема в том, что DBD необходимо изменить для использования sql_type_cast. DBD:: Oracle изменен, и я просто изменил DBD:: ODBC в 1.31, чтобы сделать это.

    Возможно, вы могли бы изменить DBD:: mysql таким же образом или убедить кого-то другого (я не использую mysql).

    Смотрите здесь для долгого обсуждения реализации DiscardString и т.д.

    использование заполнителем в Perl DBI

    У меня есть PERL скрипт как следующий

    my $tb = ‘rajeev’;
    $query = ‘select * from table where name = ?’
    $sth = $dbh->prepare($query);
    $sth->execute($tb);

    ли $ Т.Б. заменен Раджив или «Раджив» при выполнении запроса? средство делает executs запроса в
    select * from table where name = rajeev
    или
    select * from table where name = ‘rajeev’

    Создан 28 июн. 12 2012-06-28 14:05:36 r.bhardwaj

    Попробуйте и посмотрите. Один сравнивает столбец ‘name’ с * с именем’ rajeev’ *, а другой — с строковым литералом »rajeev» *. Да, в качестве комментариев @bohica ниже, утверждение удобно не буквально интерполировать — см. [Docs для ‘mysql_server_prepare’] (http://search.cpan.org/dist/DBD-mysql/lib/DBD/mysql.pm) — но вы сможете определить, какие семантики действуют . – pilcrow 28 июн. 12 2012-06-28 16:36:10

    1 ответ

    DBI обрабатывает все ускользающей для вас. В случае строки это будет ‘rajeev’ . Вызов select * from table where name = rajeev даст вам ошибку.

    Если вы предоставляете номер, он не будет добавлять кавычки, потому что они не нужны.

    См. DBI Doc. В нем также говорится:

    Метод quote() не следует использовать с «Placeholders and Bind Values».

    Использование заполнителей иногда берет на себя котирование для вас, в зависимости от того, какой DBD вы используете. В вашем случае DBD::mysql вызовов $dbh->quote() как указано в док:

    в этом случае метод цитата выполняется автоматически.

    Если у вас есть доступ к query log, вы можете проверить, на что похожи запросы. Если у вас есть запросы, которые занимают много времени, вы также можете открыть консоль mysql и сказать SHOW FULL PROCESSLIST; , чтобы просмотреть список запущенных запросов. Это также будет содержать полные инструкции SQL для вас. В Windows вы можете использовать HeidiSQL, чтобы сделать это.

    Создан 28 июн. 12 2012-06-28 14:33:16 simbabque

    Лично я был бы осторожен, чтобы не смешивать слово «цитирование» в любом описании того, как заполняются заполнители. Многие DBD ничего не цитируют, они передают SQL с заполнителями нетронутыми, а параметры передаются отдельно, когда выполняется вызов, поэтому нет цитирования как такового. – bohica 28 июн. 12 2012-06-28 15:03:54

    FWIW, ‘. где name = rajeev’ не будет ошибкой, если’ rajeev’ — это имя столбца. – pilcrow 28 июн. 12 2012-06-28 18:02:20

    @pilcrow: это правильно, но это не то, что здесь предназначено, а не поведение, которое ожидает OP. – simbabque 28 июн. 12 2012-06-28 18:31:57

    @bohica: Спасибо, я редактировал сообщение. – simbabque 28 июн. 12 2012-06-28 18:39:52

    @simbabque: кто знает? Возможно, Раджив является эгоистом. :)pilcrow 28 июн. 12 2012-06-28 19:29:46

    Если кто-то ищет это: Если есть столбец namend ‘rajeev’,’ SELECT * FROM table WHERE name = rajeev’ вернет все строки, в которых поля ‘name’ и’ rajeev’ имеют одинаковые значения в этом ряд. – simbabque 29 июн. 12 2012-06-29 07:27:07

    Ускорение доступа к базе данных MySQL с использованием Perl и DBI

    Я новичок в Perl, и я хочу кэшировать результаты программы Perl, чтобы избавиться от загрузки сервера базы данных.

    Я думаю, чтобы реализовать кеш файл для этого (но не на основе кеширования на базе сервера, например memcached), или, может быть, если вы порекомендуете что-то лучше.

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

    Я думал создать файл CSV, но, похоже, это сложнее.

    Эта программа проверяет IP-адрес пользователя, если IP существует в базе данных, пользователю предоставляется доступ.

    Ваш вопрос очень неясен, так как вы не говорите, что именно вы хотите ускорить или почему.

    Пример кода, который вы показываете, является ошибочным, следующим образом

    Вы должны всегда use strict и use warnings в верхней части каждой программы Perl, которую вы пишете. Вам также нужно будет объявить каждую используемую вами переменную, которую вы, кажется, делаете хорошо

    Использование require для включения некоторого внешнего кода немного неудобно, и лучше написать правильный модуль — возможно, используя Exporter чтобы сделать определенные подпрограммы доступными для вызывающего кода

    Гораздо более выразительно заменить $|=1 на STDOUT->autoflush , который отлично работает, если вы use IO::Handle . Каждая версия Perl с 14 имеет IO::File по умолчанию, поэтому вам даже не нужно писать use

    Никогда не пишите подпрограммы Perl прототипом. Это та часть, которая выражает параметры, которые ожидает подпрограмма. В вашем случае у вас есть sub valid() <. >, который настаивает на том, что valid будет принимать никаких параметров; но вы вызываете его позже с if (&valid($result))

    Никогда не используйте & для вызова подпрограммы. Что-то вроде &shellwords следует использовать только тогда, когда вы обрабатываете подпрограмму как данные, например, чтобы получить ссылку подпрограммы, подобную этой

    Среди прочего, & приставка имеет эффект игнорирования любых подпрограмм прототипов. Поэтому, даже если вы определили valid , не имеют никаких параметров, вы, возможно, видели его работу, потому что вы назвали его &valid($result) .

    Хотя в этом случае, кажется, работают две ошибки, они определенно не делают права!

    После этого возникает ряд семантических проблем.

    Вы надеетесь ускорить свое программное обеспечение путем кэширования результатов, но ваша valid подпрограмма connect , prepare , execute каждый раз, когда она вызывается. Он также интерполирует значение $ip в исполняемый оператор SQL: что-то, что ядовито в общедоступных сетях, и поэтому легко избежать того, что вы должны инвестировать в использование стиля заполнителя во всем мире. Это даст вам лучшую безопасность и сделает ваш код более читабельным и поддерживаемым.

    Я не уверен, почему вы используете eval вокруг вызова fetchrow_arrayref . Он убьет программу только в том случае, если вы захотите индексировать ее как массив без проверки ее значения.

    Вот рефакторинг кода, который вы показываете. Может быть, вообще не нужна политика кэширования?

    Я надеюсь, что это ясно, что я предположил, что shellwords.pl будет правильно переписан как модуль в ShellWords.pm . Все, что находится внутри shellwords.pl использует значения многих переменных, которые доступны только в правильном контексте и не передаются параметром.

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

    Илон Маск рекомендует:  C# произносится, как си шарп
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL