JulianB: Nutzung von $Variable nach IF Anweisung

Hallo Forum,

ich habe ein kleines oder großes Problem, was von Beidem weiß ich nicht, bin noch Anfänger.

Und zwar lese ich Parameter aus einer Textdatei in einen Hash, diesen durchsuche ich dann nach speziellen Schlüsseln, wenn diese vorhanden sind bearbeite ich sie, usw...

Das Ganze funktioniert natürlich mit einer IF-Anweisung:

if ($Daten{"RECORDS"})
{
  $ZEIL = $Daten{"RECORDS"};
  $ZEIL =~ m/^((.*))$/;
  $ZEILEN = $1;
}

So, nachdem ich nun den gewünschten Wert in $Zeilen geladen habe, möchte ich Ihn außerhalb der 1. IF-Anweisung in einer anderen IF-Anweisung wieder verwenden:

if($Daten{"DEFINE"} eq 'CLUSTER')
{

if(!($db = new Win32::ODBC("DSN=SNAME;UID=USER;PWD=PASS;")))
{
  print "Fehler beim Verbinden mit $DSN\n";
  print "Fehler: " . Win32::ODBC::Error() . "\n";
  exit;
}

$sql_string = ("CREATE TABLE T1 (A char($ZEICHEN), B char($ZEICHEN))");
$db->Sql($sql_string);
}

Wie ihr seht, benutze ich in dieser zweiten IF-Anweisung $ZEICHEN erneut! Allerdings bekomme ich nun folgende Warnmeldung:

Use of uninitialized value $ZEICHEN in concatenation (.) or string at prog.pl line 60

Wo ist mein Fehler oder wie kann ich diese Variable aus einer IF-Anweisung weiterbenutzen????

Liebe Grüße,

Julian

  1. Use of uninitialized value $ZEICHEN in concatenation (.) or string at prog.pl line 60

    Wo ist mein Fehler oder wie kann ich diese Variable aus einer IF-Anweisung weiterbenutzen????

    Du musst ihr einen Leerstring zuweisen, damit diese Warnung nicht mehr kommt. Denn wenn die erste Bedingung nicht erfüllt ist, ist $ZEICHEN undefiniert.

    Struppi.

    1. Okay, jetzt bin ich endgültig verwirrt.

      Ich poste einmal den Teil vom Code um den es gerade geht (Achtung wie gesagt ich bin Anfänger):

      ___________CODE___________

      %Daten = ($BEFEHL, $REST);

      my $TabNAME = '';

      if ($Daten{"NAME"})
       {
        $tNAME = $Daten{"NAME"};
        $tNAME =~ m/^((.*?).(.*).(.*))$/;
        $TabNAME = $3;
        print "\nTablename: ",$TabNAME,"\n";
       }

      my $ZEILEN = '';

      if ($Daten{"RECORDS"})
        {
         $ZEIL = $Daten{"RECORDS"};
         $ZEIL =~ m/^((.*))$/;
         $ZEILEN = $1;
         print "Create Table with: ",$ZEILEN," rows\n";
        }

      my $ZEICHEN = '';

      if ($Daten{"RECORDSIZE"})
         {
          $ZEIC = $Daten{"RECORDSIZE"};
          $ZEIC =~ m/^((.*) {1}(.*))$/;
          $ZEICHEN = $1;
          print "Row filled with: ",$ZEICHEN," spaces\n";
         }

      if($Daten{"DEFINE"})
          {

      if($Daten{"DEFINE"} eq 'CLUSTER')
           {

      if(!($db = new Win32::ODBC("DSN=SNAME;UID=USER;PWD=PASS;")))
            {
             print "Fehler beim Verbinden mit $DSN\n";
             print "Fehler: " . Win32::ODBC::Error() . "\n";
             exit;
            }

      $sql_string = ("CREATE TABLE $TabNAME (Nr varchar(20), Zeichen char($ZEICHEN))");
      $db->Sql($sql_string);

      for ($i=0;$i<$ZEILEN;$i++)
      {
      $sql_string2 = ("INSERT INTO $TabNAME (Nr) VALUES ('$i')");
      $db->Sql($sql_string2);
      }
      }

      ___________ENDE___________

      So, habe es geändert, funktioniert aber leider immer noch nicht....

      Ich lese aus dem Hash die Daten aus weiße sie den Variablen $ZEICHEN, $ZEILE und $TabNAME zu und möchte sie unten in der SQL-Anweisung wieder benutzen, sprich sie sollen die Werte übergeben.

      Vielen Dank für eure Mühen,

      Julian

      1. Ich habe vergessen zu erwähnen, die Warnmeldung kommt jetzt nicht mehr, ich gehe davon aus, das mein SQL Befehl jetzt mit den leeren Strings arbeitet....

        Liebe Grüße,

        Julian

        1. Ich habe vergessen zu erwähnen, die Warnmeldung kommt jetzt nicht mehr, ich gehe davon aus, das mein SQL Befehl jetzt mit den leeren Strings arbeitet....

          Verwendest du
          use strict;

          ????

          mfg Beat

          --
          Woran ich arbeite:
          X-Torah
          ><o(((°>      ><o(((°>
             <°)))o><                      ><o(((°>o
          1. Ich habe vergessen zu erwähnen, die Warnmeldung kommt jetzt nicht mehr, ich gehe davon aus, das mein SQL Befehl jetzt mit den leeren Strings arbeitet....

            Verwendest du
            use strict;

            ????

            mfg Beat

            Nein ich verwende kein strict, wie gesagt ich bin wirklich totaler neuling ^^

            Liebe Grüße,

            Julian

            1. Nein ich verwende kein strict, wie gesagt ich bin wirklich totaler neuling

              Dann verwende es,
              lass dich von den Errormessages nicht erschlagen,
              sondern deklariere alle deine Variablen mit my im richtigen Scope.

              Ansonsten wird für uns Hilfe zur Selbsthilfe eine Übung, die wir nur bei Totalausfall des Internets freiwillig auf uns nehmen.

              mfg Beat

              --
              Woran ich arbeite:
              X-Torah
                 <°)))o><                      ><o(((°>o
              1. Nein ich verwende kein strict, wie gesagt ich bin wirklich totaler neuling

                Dann verwende es,
                lass dich von den Errormessages nicht erschlagen,
                sondern deklariere alle deine Variablen mit my im richtigen Scope.

                Ansonsten wird für uns Hilfe zur Selbsthilfe eine Übung, die wir nur bei Totalausfall des Internets freiwillig auf uns nehmen.

                mfg Beat

                Hab ich getan, mein Problem bleibt aber. Keine Fehlermeldungen mehr, aber auch keine übergebenen Werte.

                Irgendwo ist der Wurm drin und ich werd langsam Irre.

                LG,

                Julian

                1. Irgendwo ist der Wurm drin und ich werd langsam Irre.

                  Dann gehe Schritt für Schritt vor:

                  1. Was steht im errorlog des Servers?

                  2. use strict;

                  3. Versieh Deine if-Abfragen mit einem else-Zweig:

                  if ($Daten{"NAME"}) {  
                    $tNAME = $Daten{"NAME"};  
                    $tNAME =~ m/^\((.*?)\.(.*)\.(.*)\)$/;  
                    $TabNAME = $3;  
                    print "\nTablename: ",$TabNAME,"\n";  
                  }  
                  else {  
                    print 'Error: $Daten{NAME} is not defined';  
                  }
                  

                  So erkennst Du Fehler bereits hier und baust in Dein SQL-Statement keinen Müll ein.

                  4. Beachte den Gültigkeitsbereich von mit my deklarierten Variablen:

                  my $outer_var;  
                  if(1) {  
                    $outer_var = 666;  
                    my $inner_var = 42;  
                  }  
                  print $outer_var;  # 666  
                  print $inner_var;  # Scriptabbruch
                  

                  Siehe hierzu auch Coping with scoping (deutsche Übersetzung)

                  5. Frage Fehler ab, wo immer es möglich ist und gib diese aus.

                  Lies hierzu: Dokumentation zu Win32::ODBC

                  Ohne dass Du Deinen Code vernünftig debuggst, wird das hier nur ein wildes Rumgerate.

                  Siechfred

                  --
                  Obacht, hinter jedem noch so kleinen Busch könnte ein Indianer sitzen!
                  1. Dann gehe Schritt für Schritt vor:

                    1. Was steht im errorlog des Servers?
                    1. use strict;
                    1. Versieh Deine if-Abfragen mit einem else-Zweig:
                    1. Beachte den Gültigkeitsbereich von mit my deklarierten Variablen:
                    1. Frage Fehler ab, wo immer es möglich ist und gib diese aus.

                    Ohne dass Du Deinen Code vernünftig debuggst, wird das hier nur ein wildes Rumgerate.

                    Siechfred

                    Ja Danke, du hast Recht. Ich werd erstmal mit Geduld rangehen. Ich melde mich bei euch wenn es wieder Probleme gibt, ich hoffe aber das es keine gibt und WENN welche die besser zu erklären sind.

                    Also vielen Dank an euch,

                    LG Julian

                    1. Hach Mensch, es wäre auch wirklich zu schön gewesen...

                      Neues (altes) Problem:

                      Die Fehlfunktion lag nicht daran das die Parameter nicht übergeben wurden, denn das wurden sie problemlos.

                      Das Problem liegt (immernoch) darin, das ich diese Werte aus einer Datei auslese, und mein Hauptprogramm die betreffenden Zeilen aus der Datei -> Zeilenweise <- an meine Subroutine schickt!

                      So durchläuft meine Sub jede Zeile einzeln, dann findet sie etwas schreibt es in den String, doch sobald mein Hauptprogramm die nächste Zeile übergibt, wird der alte Wert gelöscht und durch einen neuen Überschrieben, der, wenn die Bedingung false ist, natürlich leer ist.

                      Deswegen bekomme ich generell leere Strings an mein SQL Statement geschickt!

                      Hier vielleicht sieht man es anhand des Codes:

                      Zu filternde Datei:

                        
                      * $$ JOB JNM=KALAS1,CLASS=0,DISP=D  
                      * $$ LST CLASS=A,DISP=D,DEST=(,UUSER)  
                      // JOB KALAS1 UTFF-MAIN-FILES  
                      // EXEC IDCAMS  
                         DEFINE CLUSTER                        -  
                                (NAME       (AKL.VSAM.UTFFL1)  -  
                                 VOLUMES    (XXXXXX)           -  
                                 RECORDS    (850)              -  
                                 RECORDSIZE (4096 4096)        -  
                                 CISZ       (4096)             -  
                                 SHR        (9 9)              -  
                                 NUMBERED)                     -  
                         CATALOG  (VSEKL.USER.CATALOG)  
                      /*  
                      /&  
                      * $$ EOJ  
                      
                      

                      Hauptprog:

                        
                      use IDCAMS;  
                        
                      use strict;  
                        
                      my $BEFEHL = '';  
                      my $REST = '';  
                      my $exec = '';  
                      my $buffer = '';  
                      my $dlbl = '';  
                      my $job = '';  
                      my $Programm = '';  
                      my $cmd = '';  
                      my $BINDESTRICH = '';  
                        
                      open(DB, "<$ARGV[0]") || die "Kann Datei nicht öffnen!";  
                      while(<DB>)  
                                {  
                                $buffer = $_;  
                        
                                    if(index($buffer,"// JOB ") != -1)  
                                    {  
                                     $job = $buffer;  
                                     $job =~ m/^(.*?)JOB (.*)$/;  
                                     print " \n";  
                                     print "---------------------------------------\n";  
                                     print "JOBNAME => $2\n";  
                                    }  
                                    if(index($buffer,"// DLBL ") != -1)  
                                    {  
                                     $dlbl = $buffer;  
                                     $dlbl =~ m/^(.*?)DLBL (.*),(.*),,(.*)$/;  
                                     print "DLBL => $2\n";  
                                    }  
                                    if(index($buffer,"// EXEC ") != -1)  
                                    {  
                                     $exec = $buffer;  
                                     $exec =~ m/^(.*?)EXEC ([A-Z]*),*(.*)$/;  
                                     $Programm = $2;  
                                     print "EXEC => $Programm\n";  
                                    }  
                        
                                    if((index($buffer,"/") == -1)&&(index($buffer,"*") == -1))  
                                    {  
                                     $cmd = $buffer;  
                                     $cmd =~ m/^.*( - ).*$/;  
                                     $BINDESTRICH = $1;  
                        
                                     if(defined $BINDESTRICH)  
                                     {  
                                     $cmd = $buffer;  
                                     $cmd =~ m/^[^A-Z]*([A-Z]*)[^A-Z0-9]* (.*) +- .*$/;  
                                                   #print "Buffer=$cmd\n#$1#$2#\n";  
                                     $BEFEHL = $1;  
                                     $REST = $2;  
                        
                                     $REST =~ s/\s+$//g;  
                                     }  
                        
                                     else  
                                     {  
                                     $cmd = $buffer;  
                                     $cmd =~ m/^[^A-Z]*([A-Z]*)[^A-Z0-9]* (.*) .*$/;  
                                                   #print "Buffer=$cmd\n#$1#$2#\n";  
                                     $BEFEHL = $1;  
                                     $REST = $2;  
                        
                                     $REST =~ s/\s+$//g;  
                                     }  
                        
                                     if(defined $BINDESTRICH == 0 )  
                                     {  
                        
                                      if($Programm eq "IDCAMS")  
                                      {  
                        
                                       IDCAMS($BEFEHL,$REST);  
                                      }  
                        
                                     }  
                        
                                    }  
                        
                                }  
                      close(DB);  
                      
                      

                      Und das dazugehörige Modul:

                        
                      use Win32::ODBC;  
                      use strict;  
                        
                      sub IDCAMS  
                      {  
                      my ($TabNAME, $tNAME, $ZEILEN, $ZEIL, $ZEICHEN, $ZEIC, $sql_string, $sql_string2, $db, %Daten);  
                      my $BEFEHL = *_;  
                      my $REST = *_;  
                        
                          $BEFEHL = shift;  
                          $REST = shift;  
                        
                           %Daten = ($BEFEHL, $REST);  
                        
                             if ($Daten{"NAME"})  
                             {  
                              $tNAME = $Daten{"NAME"};  
                        
                              $tNAME =~ m/^\((.*?)\.(.*)\.(.*)\)$/;  
                              $TabNAME = $3;  
                             }  
                        
                             if ($Daten{"RECORDS"})  
                             {  
                              $ZEIL = $Daten{"RECORDS"};  
                        
                              $ZEIL =~ m/^\((.*)\)$/;  
                              $ZEILEN = $1;  
                              $ZEILEN++;  
                             }  
                        
                             if ($Daten{"RECORDSIZE"})  
                             {  
                              $ZEIC = $Daten{"RECORDSIZE"};  
                        
                              $ZEIC =~ m/^\((.*) {1}(.*)\)$/;  
                              $ZEICHEN = $1;  
                             }  
                        
                               if($Daten{"DEFINE"})  
                               {  
                        
                                  if($Daten{"DEFINE"} eq 'CLUSTER')  
                                  {  
                        
                                     if(!($db = new Win32::ODBC("DSN=SNAME;UID=User;PWD=PASS;")))  
                                     {  
                                      print "Fehler beim Verbinden\n";  
                                      print "Fehler: " . Win32::ODBC::Error() . "\n";  
                                      exit;  
                                     }  
                        
                                      $sql_string = ("CREATE TABLE $TabNAME (Nr varchar(20), Zeichen char($ZEICHEN))");  
                                      $db->Sql($sql_string);  
                        
                                     for (my $i=1;$i<$ZEILEN;$i++)  
                                     {  
                                      $sql_string2 = ("INSERT INTO $TabNAME (Nr) VALUES ($i)");  
                                      $db->Sql($sql_string2);  
                                     }  
                        
                                       print "\nTablename: ",$TabNAME,"\n";  
                                       print "Create Table with: ",$ZEILEN," rows\n";  
                                       print "Row filled with: ",$ZEICHEN," spaces\n";  
                                       print "---------------------------------------";  
                                  }  
                        
                               }  
                      }  
                      1;  
                      
                      

                      Die Datei wird zeilenweise eingelesen und jede einzelne Zeile wird an die Sub übergeben, die läuft einmal komplett durch bis sie die nächste Zeile bekommt,das Ganze bis die Datei endet. Und deswegen bekomme ich nur leere Strings an das SQL Statement gesendet.

                      Vielleicht hat ja jemand eine Idee, wenn ja wäre ich sehr dankbar.

                      Liebe Grüße,

                      Julian

                      1. Ich kommentiere mal nur einen Abschnitt

                        if ($Daten{"NAME"})

                        Hier fragst du, ob $Daten{"NAME"} true ist.
                        Was aber, wenn der Hashkey "NAME" nicht existiert, dann hast du ihn soeben erzeugt, mit der möglichen Warnung: match auf nicht initialisierte Variable.

                        if( exists $Daten{"NAME"} )

                        {
                                $tNAME = $Daten{"NAME"};
                                $tNAME =~ m/^((.*?).(.*).(.*))$/;
                                $TabNAME = $3;

                        Dein Pattern und deine Zuweisung ist kompliziert und braucht hier eine überflüssige Variable $tName
                                                                        $1
                        statt dessen direkte Zuweisung:
                        Wir verwenden non capturing parantheses (?: )

                                  $Daten{"NAME"} =~ m/^\((?:.*?)\.(?:.*)\.(.*)\)$/  
                                        and $TabNAME = $1;  
                        
                        

                        Die Zuweisung ist damit vom Erfolg des Matches abhängig.
                        Die weiteren Abschnitte sind analog.

                        if($Daten{"DEFINE"})

                        Hoffentlich existiert der Schlüssel? Du meinst eher if( exists( ... )){}
                        lerne das Problem Autovivikation von Hashkeys durch abfragen wie
                        if ( $Hash{key} )
                        oder
                        if ( defined $Hash{key} )

                        Diese Autovovokation des Keys kann nur verhindert werden durch:

                        if( exists $Hash{key} )

                        mfg Beat

                        --
                        Woran ich arbeite:
                        X-Torah
                        ><o(((°>    ----       ><o(((°>
                           <°)))o><                      ><o(((°>o
                        1. DANKE!!! - DANKE!!! - DANKE!!!

                          Es funktioniert, ganz ohne Probleme, es ist alles gelöst. Neben deinen Tipps habe ich noch ein wenig rumfummeln müssen aber es geht!!!
                          Und der Code ist viiiiiel kürzer jetzt.

                          Gott ich bin überglücklich ^^ vielen vielen Dank an euch alle.

                          Liebe Grüße,

                          Julian

      2. So, habe es geändert, funktioniert aber leider immer noch nicht....

        was heißt nicht funktionieren?

        Struppi.

  2. Moin, moin!

    Du füllst die Variable $ZEILEN, verwendest aber später $ZEICHEN!

    Alles klar?

    Norbert

  3. Hallo Forum,

    ich habe ein kleines oder großes Problem, was von Beidem weiß ich nicht, bin noch Anfänger.

    Und zwar lese ich Parameter aus einer Textdatei in einen Hash, diesen durchsuche ich dann nach speziellen Schlüsseln, wenn diese vorhanden sind bearbeite ich sie, usw...

    Das Ganze funktioniert natürlich mit einer IF-Anweisung:

    Ist $ZEILEN hier überhaupt deklariert?
    my $ZEILEN = '';

    if ($Daten{"RECORDS"})
    {
      $ZEIL = $Daten{"RECORDS"};
      $ZEIL =~ m/^((.*))$/;
      $ZEILEN = $1;
    }

    So, nachdem ich nun den gewünschten Wert in $Zeilen geladen habe,

    Oder auch nicht...

    möchte ich Ihn außerhalb der 1. IF-Anweisung in einer anderen IF-Anweisung wieder verwenden:

    Welchen Wert, wenn die obige IF Anweisung nicht zutraf?
    Entweder du hängst eine else{} Alternative an, oder du schreibst die weiter Verarbeitung in den if(){} Block

    Verwendest du überhaupt
    use strict;   # ???

    mfg Beat

    --
    Woran ich arbeite:
    X-Torah
    ><o(((°>      ><o(((°>
       <°)))o><                      ><o(((°>o