DiM_TauRus Опубликовано 15 января, 2007 (изменено) · Жалоба Приветствую! Дано: Mysql 4x, база данных base_name, таблица "users" Надо: Скрипт на bash, который из базы base_name делает выборку из таблицы "users" по заданному значению столбца "GID" (0-9), затем у попавших в выборку отнимает из столбца "deposit" определенное значение и соответственно записывает новые значения обратно. Кто-то может изобразить здесь такой скрипт ? Изменено 15 января, 2007 пользователем DiM_TauRus Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 16 января, 2007 · Жалоба Месье знает толк в извращениях. А чем Вас перл не устраивает? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
DiM_TauRus Опубликовано 16 января, 2007 · Жалоба можно и перл. лишь бы работало. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 16 января, 2007 · Жалоба #!/usr/bin/perl use DBI; my $sql_db = "db"; my $sql_user = "user"; my $sql_pass = "pass"; my $dbh = DBI->connect("DBI:mysql:$db", $sql_user, $sql_pass); my $gid_value = 1; my $query = qq { SELECT gid, deposit FROM users WHERE gid=$gid_value }; my $sth = $dbh->prepare ($query); $sth->execute (); while (my $row = $sth->fetchrow_hashref()) { $dbh->do ("UPDATE user SET deposit=deposit-$deposit_minus_var where gid=$row->{gid}"); } Впрочем, можно и проще, если вычитаемая сумма одинакова или может быть вычислена на основании др. таблиц: #!/usr/bin/perl use DBI; my $sql_db = "db"; my $sql_user = "user"; my $sql_pass = "pass"; my $dbh = DBI->connect("DBI:mysql:$db", $sql_user, $sql_pass); $dbh->do ("UPDATE users SET deposit=deposit-$sum WHERE gid=$gid_value") Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Kuzmich Опубликовано 16 января, 2007 · Жалоба Поскольку весь скрипт создается ради одного запроса, который к тому же не возвращает никаких данных, то самое оно его запускать как раз из шелл-скрипта, используя консольного клиента mysql. К сожалению, мускулем не пользуюсь уже несколько лет, всё больше постгрес да оракл, поэтому конкретно для мускула командную строку не приведу... Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 16 января, 2007 · Жалоба Поскольку весь скрипт создается ради одного запроса, который к тому же не возвращает никаких данных, то самое оно его запускать как раз из шелл-скрипта, используя консольного клиента mysql. К сожалению, мускулем не пользуюсь уже несколько лет, всё больше постгрес да оракл, поэтому конкретно для мускула командную строку не приведу... Самое оно, если речь идет об одном апдейте. А вот если надо проводить сложные операции, то баш не поможет. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
GateKeeper Опубликовано 16 января, 2007 · Жалоба Самое оно, если речь идет об одном апдейте. А вот если надо проводить сложные операции, то баш не поможет. Сложные, это в такие, для которых даже sed/awk/cut/etc... не помогут а перл самое то? Кстати, условием ограничение на порождаемые процессы не было, так что шелл тоже катит. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 16 января, 2007 · Жалоба Самое оно, если речь идет об одном апдейте. А вот если надо проводить сложные операции, то баш не поможет.Сложные, это в такие, для которых даже sed/awk/cut/etc... не помогут а перл самое то? Кстати, условием ограничение на порождаемые процессы не было, так что шелл тоже катит. Я понимаю, что можно шурупы и молотком забивать. Дайте пример, пожалуйста. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
GateKeeper Опубликовано 16 января, 2007 · Жалоба Я понимаю, что можно шурупы и молотком забивать. Дайте пример, пожалуйста. Ну для примера неплохо бы увидеть ТЗ к этому примеру. Сформулируйте ТЗ - озвучу решение. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 16 января, 2007 · Жалоба Ну для примера неплохо бы увидеть ТЗ к этому примеру. Сформулируйте ТЗ - озвучу решение. Скрипт на bash, который из базы base_name делает выборку из таблицы "users" по заданному значению столбца "GID" (0-9), затем у попавших в выборку отнимает из столбца "deposit" определенное значение и соответственно записывает новые значения обратно.Простейший случай - когда вычитаемая сумма постоянна, то mysql -uuser -ppassword database -e 'UPDATE users SET deposit=deposit-_sum_ WHERE gid=_gid_' Но мы его не рассматриваем :) Предположим, что в SQL-запросе выполнить все действия нельзя. Есть awk/cut/sed и т.д. Нужно сделать буквально то, что указано в задаче, а именно - сделать выборку (обязательно) и для каждого gid из выборки изменить deposit на некоторое значение. Для красоты предположим даже, что значения лежат где-то в других таблицах, никакими джойнами их прицепить нельзя, поэтому для них тоже надо делать выборку. Вот ТЗ :) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
DiM_TauRus Опубликовано 17 января, 2007 · Жалоба Спасибо люди! Разобрался, интуитивно на основе приведенных примеров написал скрипт, получилось, после добавления пары модулей для перла. Собственно скрипт нужен был для запихивания в крон с целью снятия абонплаты ). Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
GateKeeper Опубликовано 17 января, 2007 (изменено) · Жалоба table1 - таблица с gid вида: gid int(4), deposit double(16,4). table2 - таблица с некоторыми исходными данными по каждому gid (тарифы?) вида: gid int(4), decr_mult double(4,4), decr_const double(4,2). Надо: по каждому table1.gid провести уменьшение table1.deposit по формуле: table1.deposit = table1.deposit - table2.decr_const*table2.decr_mult, при этом данные из таблицы table2 брать в соответствии с gid. Ну и дополнительно: никоим образом при всём желании делать это одним запросом нельзя. Итак: #!/bin/sh M_HOST='localhost' M_USER='root' M_DB='ddd' M_PASS='derpassword' M_PARAMSTR="-h ${M_HOST} -u${M_USER} -p${M_PASS} -B $M_DB" echo "SELECT * FROM table2" | mysql ${M_PARAMSTR} > /tmp/defines.tbl echo "SELECT * FROM table1" | mysql ${M_PARAMSTR} | tail -n +2 | while read DEPROW; do DEP_GID=$(echo ${DEPROW} | cut -d " " -f 1) DEP_LASTVAL="$(echo ${DEPROW} | cut -d " " -f 2)" D_CONST="$(grep -E "^${DEP_GID}" /tmp/defines.tbl | cut -f 3)" || D_CONST="0" [ "$D_CONST" != "0" ] && D_MULT="$(grep -E "^${DEP_GID}" /tmp/defines.tbl | cut -f 2)" || D_MULT="0" if [ "$D_CONST" != "0" ] && [ "$D_MULT" != "0" ]; then DEP_NEWVAL="$(echo "${DEP_LASTVAL}-${D_CONST}*${D_MULT}" | bc)" echo "UPDATE table1 SET deposit = '${DEP_NEWVAL}' WHERE gid = '${DEP_GID}'" | mysql $M_PARAMSTR; fi; done; rm /tmp/defines.tbl Не спорю, что немного изврат для периодических снятий абонентки, однако если по условию "только на шелле" - оно самое. Главное, что в системе как правило всё для этого есть - и разные строковые обработчики (cut, grep) и математический процессор, работающий с дробными числами (bc) и т.д. По скрипту получилось: исходные данные: mysql> select * from table1; +------+----------+ | gid | deposit | +------+----------+ | 1 | 360.0000 | | 2 | 400.0000 | +------+----------+ mysql> select * from table2; +------+-----------+------------+ | gid | decr_mult | decr_const | +------+-----------+------------+ | 1 | 0.2500 | 50.00 | | 2 | 0.5000 | 50.00 | +------+-----------+------------+ после выполнения: mysql> select * from table1; +------+----------+ | gid | deposit | +------+----------+ | 1 | 347.5000 | | 2 | 375.0000 | +------+----------+ Изменено 17 января, 2007 пользователем GateKeeper Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
DiM_TauRus Опубликовано 17 января, 2007 · Жалоба GateKeeper`у отдельное спасибо за полностью шеловый вариант, это и правда полезно. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
EvilShadow Опубликовано 17 января, 2007 · Жалоба 2 GateKeeper Красиво, хоть и сложновато. Если у меня под рукой не окажется перла, возьму на заметку Ваш вариант ;) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
GateKeeper Опубликовано 18 января, 2007 (изменено) · Жалоба Кстати, особо прошу обратить внимание на регекспы: мой катит только для случая, когда `0 <= gid <= 9`. Если строку: [ "$D_CONST" != "0" ] && D_MULT="$(grep -E "^${DEP_GID}" /tmp/defines.tbl | cut -f 2)" || D_MULT="0" заменить на: [ "$D_CONST" != "0" ] && D_MULT="$(grep -E "^${DEP_GID}[^[:digit:]]" /tmp/defines.tbl | cut -f 2)" || D_MULT="0" тогда прокатит для `gid >= 0` Изменено 18 января, 2007 пользователем GateKeeper Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...