Anzeige:
Ergebnis 1 bis 4 von 4

Thema: Perl/Oracle: fetchhash Problem

  1. #1
    Registrierter Benutzer
    Registriert seit
    10.06.2003
    Beiträge
    19

    Perl/Oracle: fetchhash Problem

    Hi,

    Ich möchte aus einer Datenbank ein paar ausgewählte Datensätze auslesen und diese als Hash in einem Array speichern.

    DB:
    Spalte1 Spalte2 Spalte3

    Test1A Test1B Test1C

    Test2A Test2B Test2C

    Test3A Test3B Test3C

    Test4A Test4B Test4C

    Ein Hash soll nun so aussehen:
    %hash1 = (Spalte1 => "Test1A", u.s.w.)

    Für jede Zeile soll ein Hash erstellt werden.

    Schliesslich sollen die Hash in einem Array zwischengespeichert werden. Also @temp = (%hash1,%hash2,u.sw.)

    Dieser Array wird nun durchlaufen und es wird ein neuer Hash gebildet, der NUR Elemente enthält, die in jedem einzelnen %hash von vorhin vorkommen.

    Soviel zur Aufgabe... Mein Versuch war nun das ganze mittels Fetchhash abzuholen:
    Code:
    sub get_it { 
    	my $dbh = shift;
    	my $tabletemp = shift;
    	my $id = shift;
    	my %temphash;
    	my %controlhash;
    	my @results;
    
    	# begin dbaccess
    	my $sql="SELECT * FROM $tabletemp WHERE ID='$id'";
    	
    	my $sth = $dbh->prepare($sql) or die $dbh->errstr();
    	$sth->execute or die $dbh->errstr();  
    	while (%temphash = $sth->fetchhash()){
    		push @results, \%temphash;
    	}
    	
    	$sth->finish ();
    	# end dbaccess
    
    	# begin compare
    	foreach my %hash (@results){
    		foreach(keys(%hash)){
    			if ($hash{$_} eq $controlhash{$_} || !defined $controlhash{$_}){
    				$controlhash{$_} = $hash{$_};
    			}
    			else {
    				$controlhash{$_} = "";
    			}
    		}
    	}
    	# end compare
    	
    	return %controlhash;
    }
    Ich bin mir ziemlich sicher, dass mein Code oben noch viele kleine Fehler hat. Aber stimmt das Prinzip mit dem speichern der Hashes im Array? Der Datenbankzugriff funktioniert. Leider crashed mir das Skript ohne Fehlermeldung. Er sagt etwas von wegen: "Too many headers".

    Hat jemand einen guten Tipp für mich, oder kann mir einen Tipp geben wo suchen?

    Vielen Dank!

  2. #2
    Registrierter Benutzer Avatar von Molaf
    Registriert seit
    15.11.2004
    Beiträge
    127
    Die Zeile sieht mir verdächtg aus:

    push @results, \%temphash;

    Ohne den Backslash wird der Hash einfach in ein neues Arrayfeld geschrieben, so sieht es eher so aus als ob Du eine Refferenz darauf übergibst. Da %temphash aber ohnehin nach jedem Schleifendurchlauf verfällt kann das eigentlich nichts werden.

    Ich habe nicht genug Zeit das Skript selber zu testen, werde es bei bestehenden Problemen aber gerne die nächsten Tage mal probieren.

    mfg Molaf

  3. #3
    Registrierter Benutzer
    Registriert seit
    10.06.2003
    Beiträge
    19
    So, ich bin ein grosses Stück weitergekommen:

    Code:
    sub get_it { 
    # generates datacache from tempdb using dbid or from dataimport. dataimport has higher priority.
    # if multiple datasets are selected, only the values that are equal are returned.
    	my $dbh = shift;
    	my $tabletemp = shift;
    	my $id = shift;
    	
    	my $str="";
    	my %resulthash;
    	my %controlhash;
    	my @names;
    
    	my $sql="SELECT * FROM $tabletemp WHERE ID='$id'";
    	
    	my $sth = $dbh->prepare($sql) or die $dbh->errstr();
    	$sth->execute or die $dbh->errstr();  
    	while (my $hash_ref = $sth->fetchrow_hashref) {
    		foreach(keys(%{$hash_ref})){
    			$str .= "push(\@$_,\$hash_ref->{$_});";
    			push(@names,$_);
    		}
    		eval $str;
    	}
    	
    	$sth->finish ();
    	
    	foreach $names(@names){
    		$controlhash{$names} = "empty";
    		foreach @poss(eval "\@$names"){
    			foreach $var($poss){
    				$controlhash{$names} = $var;
    			}
    		}
    		$resulthash{$names} = $controlhash{$names};
    	}
    	
    	return %resulthash;
    }
    Das gute Ding kann die Daten auslesen und speichert sie im Hash, der Zurückgegeben wird. Natürlich überschreibt er den controlhash jeweils mit dem letzten Wert aus dem Array @$names. Nun möchte ich diese Werte vor dem überschreiben miteinander vergleichen.

    Ich habe mir gedacht, dass das so funktionieren könnte:

    Code:
    if ($controlhash{$names} eq "empty" || $controlhash{$names} eq $var){
    	$controlhash{$names} = $var;
    }
    else {
    	$controlhash{$names} = "";
    }
    Hat jemand eine Idee, wieso das nicht geht?

    Vielen Dank!

  4. #4
    Registrierter Benutzer
    Registriert seit
    10.06.2003
    Beiträge
    19
    Ok... Das Problem ist gelöst:

    Code:
    			foreach $var($poss){
    				if (defined $controlhash{$names} && $controlhash{$names} ne $var){
    					$controlhash{$names} = "item_locked";
    				}
    				else {
    					$controlhash{$names} = $var;
    				}
    			}


    Gruss

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •