Shell Skript mit Schleife und mysql Abfrage

P

philip123

Grünschnabel
Hallo Leute,
mit der Shell-Programmierung in Linux bin ich leider noch totaler Neuling und müsste nun ein kleines Skript bauen.
Erst müsste eine mysql Abfrage gestellt werden und die Werte in eine Variable gespeichert werden.

SELECT campaign_id, active FROM campaigns WHERE active='Y';

Alle campaign_id's müssten in Variablen gespeichert werden, damit sie in einer anderen SQL Abfrage wieder verwendet werden können.
Die 2. Abfrage müsste dann so aussehen:

UPDATE list SET amount = umsatz WHERE ((datestamp)>=curdate()) AND status='SALE' AND campaign_id= VARIABLE ;

Jetzt könnte man das mit einer Schleife lösen für alle Kampagnen.
Als erstes die Anzahl berechnet mit SELECT COUNT ..., dann weiss man wieviel Zeilen die Abfrage haben wird, und dann eine Schleife erstellen bis die Anzahl der Zeilen erreicht ist.
In VBA wäre das kein Problem, aber Linux :-)
Ein mysql Befehl starten klappt bei mir bestens mit
mysql -uUSER -pPW -hIPSERVER --database=asterisk --execute="SQLBEFEHL"

Wenn ihr mir helfen könntet wäre ich euch super dankbar!!

Viele Grüsse
Philip
 
Ich halte perl oder python mit ihren libs für mysql für geeigneter, aber wenn du ein paar shell-skripte machen möchtest

Siehe zu Variablen hier
http://de.wikibooks.org/wiki/Linux-Kompendium:_Shellprogrammierung#Variablen

Um deine Erwartungshaltung zu dämpfen, es wird kaum jemand dir eine "fertige" lösung geben, falls du das erwartest

Hier ist eine gute Seite für dein Ziel - Stichwort PEP 249, DB API HOWTO
http://wiki.python.org/moin/DatabaseProgramming/

EDIT: Es ist meines Erachtens nicht ratsam, auf diese Art und Weise (via Shellskript) Daten zu aktualisieren, da keine Transaktionssicherheit gewährleistet ist
 
Zuletzt bearbeitet von einem Moderator:
Super danke!
Ich denke die Shellprogrammierung reicht mir, da ich alle 30 Minuten das Skript ausführe und lediglich Daten aktualisiere.
Bei der Abfrage kann eigentlich nichts schief laufen und der Server wird sowieso localhost sein.

Dann teste ich mal und gebe Feedback.

Grüsse
Philip
 
Kann man das nicht in einer Query machen? Ich konnte deine Aufgabenstellung allerdings nicht wirklich 100%ig nachvollziehen..
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

P.S.: Ein SELECT * LIMIT 10 der jeweiligen Beispieltabellen und ein DESCRIBE tabelle helfen beim Nachvollziehen.
 
Zuletzt bearbeitet:
Leider nicht, die Abfrage ist sehr komplex und greift auch auf verschiedene Datenbanken zu die variieren in Abhängigkeit der 1.Abfrage, deswegen komme ich nicht drum rum mit Variablen zu arbeiten. Je nachdem was Abfrage 1 als Ergebnis auswirft, greift man auf eine bestimmte Tabelle in einer anderen Datenbank zu.
Ich lese mich gerade im Skripting ein in dem Link von cinhtau.

Gruss
Philip
 
Mit Sachen wie Perl hast du aber eben sehr viel geilere Möglichkeiten mit Schleifen, Arrays und dessen DB-Libs....

Zwar ist die Syntax aus dem Blickwinkel von bash & co. umgewöhnungsbedürftig, aber gerade Perl agiert ja auch als Script-Interpreter, wie bash in der Situation auch. Nur mit einem etwas mächtigeren Hintergrund.

Bei Perl muß man mal bedenken, daß es eigentlich aus der Not begrenzter Shells entstanden ist. Es kann viel komplexer mit Aufrufen umgehen als ein Shellscript und ist trotzdem dafür konzipiert worden, auf Textbasis zu arbeiten. Deshalb wurde es zu einer Größe im CGI-Bereich, weil Webserver sich über sowas sehr freuen, sie verwursten ja auch hauptsächlich Text (evtl. mit Verweisen auf irgend was binär vorliegendes).

Aber eigentlich war die Idee bei Perl, etwas auf Shell-Basis zu schaffen, wo Shellscripte selber in der Komplexität nicht oder nur mit Mühe mit kommen. Du kannst je nach Kondition mehrere Datenbanken kontaktieren, diese nach ihren Tabellen abfragen, alles in mehrdimensionalen nummerischen oder assoziativen Arrays speichern und aus diesen sonstwas irgend wo hin pumpen.

Da Perl inzwischen betagt ist, hatten inzwischen noch mehr Leute auch solche Ideen :D

Die Vorgehensweise ist aber anders als im Shellscript, z.B. kann Perl von sich aus gut mit regulären Ausdrücken umgehen, wenn es etwas sucht, ohne dafür Streameditoren nutzen zu müssen, weil es das gleich mit Strings machen kann, die in Variablen stehen, diese in Segmente zerlegen und in Arrays speichern kann, von denen es jeder Zeit auf jedes Element Zugriff hat. Und solche Strings kann es jeder Zeit aus jeder Datenbank holen, abgleichen oder zusammen führen.

Strukturen wie bash sind dafür nur bedingt konzipiert, würde ich sagen.

Edit....
Du sprichst VBA an. Ok, dann vergleiche mal DOS Batch-Programming mit bash. Und danach VBA mit DOS Batch. Würdest du sagen, daß Batch-Programme unter DOS VBA das Wasser reichen könnten, was Modularität und den Umgang mit Variablen und Kontrollstrukturen angeht? Das ist nämlich keine Frage ob Linux oder nicht, sondern ob du es mit einer ungeeigneten Umgebung umsetzen willst oder lieber mit einer, die 20 Jahre neuer ist und ... na ja, VBA wurde langsam mit Windows 9.x berühmt, da war Perl schon alt :D

Ok, mit Powershell und .NET hat jetzt sogar MS mal was eingeführt, was von der Idee her mehr an der Shell kann als DOS, und damit mußt du deine Idee mal vergleichen, eine relationale Datenbank mit einem Shellscript zu pflegen... und bei MS ist sogar die Shell eine grafische Anwendung inzwischen, die können nicht mal mehr im Bootprozeß Systemschriften ausgeben (außer im Bluescreen), sondern müssen die als Bild ausgeben und enorm lange dran herum interpretieren, bis bei einem schwächeren Rechner mal bei "F8" die auswahl der Startoptionen erscheint....
 
Zuletzt bearbeitet:
Ich denke die Shellprogrammierung reicht mir, da ich alle 30 Minuten das Skript ausführe und lediglich Daten aktualisiere.

Das kannst du auch mit einem perl-Programm oder python-Programm. Sogar Java-Programme oder Programme x die unter der bash funktionieren. Dafür gibt es cronjobs.

Bei der Abfrage kann eigentlich nichts schief laufen und der Server wird sowieso localhost sein.

Sei mir nicht böse. Es ist richtig erstmal zu coden, um erste Ergebnisse zu erhalten. Transaktionssicherheit muss trotzdem gewährleistet sein. Bei einem Stromausfall hat dein Skript gerade Daten aktualisiert. Jetzt muss du dich daran setzen und die aktualisierten Daten ermittteln und die Restmenge bilden, die noch hätten aktualsiert werden müssen. Kapselt du das in eine Transaktion, hat er überhaupt keine Daten aktualisiert und du kannst den Job/Skript einfach neu starten. Das hat mit dem Ort des Skriptes nichts zu tun. Es ist ein gut gemeinter Rat. Nicht mehr nicht weniger. Als DBA muss du Konsistenz gewährleisten können.

Siehe http://dev.mysql.com/doc/refman/5.1/de/ansi-diff-transactions.html
 
Zuletzt bearbeitet von einem Moderator:
Verstehe ich, ich bin auch gerade auf PERL "umgestiegen", also ich versuche mich einzuarbeiten, da auch das komplette Konstrukt auf PHP/PERL/Asterisk besteht.
Aber in meinem Fall ist es tatsächlich egal, weil nur ein Wert von der einen DB in die anderen geschrieben wird, wenn er nicht identisch ist.
Wenn das Skript 1x fehlschlägt, wird es beim nächsten Aufruf einfach die restlichen Werte übernehmen.
Aber ich gebe euch natürlich Recht, aber in diesem speziellen Fall würde es wohl über ein einfaches Skript reichen.
Aber da ich in Zukunft wohl mit PERL arbeiten muss, arbeite ich gerade mit Tutorials.
Bis heute Abend oder Montag muss es fertig sein, also hab ich noch reichlich Zeit :-)
Ich habe ja Programmiergrundkenntnisse, sollte also schon irgendwie möglich sein.

Danke für eure Tipps, werde mein Resultat dann posten.

Grüsse
Philip
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Hallo,
erstmal danke für die Tipps, ich habe mir jetzt ein kleines PERLchen gebaut,
für diejenigen die es vielleicht mal brauchen können:

Code:
root@ka-vici-dialer:/etc# cat GabCom_Lime_Amount_kopieren.pl
#!/usr/bin/perl
use warnings;
$SERVER = "192.168.203.22";
$DATABASE = "asterisk";
$USER = "user";
$PASS = "pass";

use DBI;

@dsn = ("DBI:mysql:database=$DATABASE;" .
           "host=$SERVER", $USER, $PASS);

# Datenbank andocken
$dbh = DBI->connect(@dsn,
    { PrintError => 0,
      AutoCommit => 1,
    }
    ) or die $DBI::errstr;

#alle Kampagnen mit LimeSurvey aktiv filtern
$aref = $dbh->selectall_arrayref("SELECT campaign_id, gabcom_lime_campid, gabcom_lime_umsatz_gruppeid, gabcom_lime_umsatz_frageid, gabcom_lime_active FROM vicidial_campaigns WHERE gabcom_lime_active = 'Y'")
               or die $dbh->errstr();
#jede Zeile einzeln ausgeben
for $row (@$aref)
  {
  ($campaign_id, $gabcom_lime_campid, $gabcom_lime_umsatz_gruppeid, $gabcom_lime_umsatz_frageid) = @$row;
  print "$campaign_id, $gabcom_lime_campid, $gabcom_lime_umsatz_gruppeid, $gabcom_lime_umsatz_frageid\n";


        #alle Adresslisten auswaehlen die der Kampagne zugeordnet sind
        $aref = $dbh->selectall_arrayref("SELECT list_id, campaign_id FROM vicidial_lists WHERE campaign_id = '$campaign_id'")
               or die $dbh->errstr();
        #jede Zeile einzeln ausgeben
        for $row (@$aref)
          {
          ($list_id) = @$row;
          print "$list_id\n";
          $gabcom_lime_string = "limedb.lime_survey_$gabcom_lime_campid." . "$gabcom_lime_campid" . "X" . "$gabcom_lime_umsatz_gruppeid" . "X" . "$gabcom_lime_umsatz_frageid\n";
          print "$gabcom_lime_string";


                $dbh->do("UPDATE vicidial_list
                          INNER JOIN limedb.lime_survey_$gabcom_lime_campid ON vicidial_list.lead_id = limedb.lime_survey_$gabcom_lime_campid.token
                          SET vicidial_list.AMOUNT = limedb.lime_survey_$gabcom_lime_campid.27422X5X18 #$gabcom_lime_string #limedb.lime_survey_$gabcom_lime_campid.27422X5X18
                          WHERE vicidial_list.status = 'sale' AND vicidial_list.list_id = '$list_id'");

          }

  }

#DB Verbindung beenden
$dbh->disconnect();
 
Zuletzt bearbeitet:
Zurück
Oben