Good day. Please help me figure it out. Below is a piece of code that I want to get from the table the value of one column, in this case $ PG1 ... $ PG10 should have the value 600 ... 610, respectively. But when printing, they are duplicated several times, that is, it is displayed:

600 601 ... 610 600 601 ... 610 

How to get each value only once and assign it to a variable?

 my $dbqueryPRODGRP = $db->prepare("select f1 from DPTDAT group by f1"); $dbqueryPRODGRP->execute(); my @rowPRODGRPs; while (my ($rowPRODGRP)=$dbqueryPRODGRP->fetchrow_array()) { push @rowPRODGRPs, $rowPRODGRP; foreach $rowPRODGRP(@rowPRODGRPs) { my ( $PG1,$PG2,$PG3,$PG4,$PG5,$PG6,$PG7,$PG8,$PG9,$PG10,)=@rowPRODGRPs; print $PG1."\n", $PG2."\n",$PG3."\n",$PG4."\n",$PG5."\n",$PG6."\n",$PG7."\n",$PG8."\n",$PG9."\n",$PG10."\n"; } } 

The corrected version that worked.

 my $dbqueryPRODGRP = $db->prepare("select f1 from DPTDAT group by f1 order by f1"); $dbqueryPRODGRP->execute(); my @rowPRODGRPs;#Задаем имя массиву while (my ($rowPRODGRP)=$dbqueryPRODGRP->fetchrow_array()) { push @rowPRODGRPs, $rowPRODGRP;#Записываем каждый результат в лист массива } 
  • one
    You take the first line in the loop, add it to the array. Immediately print the entire array. Then take the second line, add to the array (now there are 2 lines in the array) and print the entire array again. If you need an array, first fill it all up, and after the read cycle from the database (after } related to while ) type. Or, without any arrays, type the string as soon as it is received from the database - Mike
  • one
    Yes, in addition, you do foreach by array, i.e. iterate through its elements and for each element you get the first 10 elements of the same array into variables and type them all. Those. if in the array 3, the foreach elements are executed 3 times and you print the entire array 3 times and that 9 values ​​will be printed - Mike
  • "Revised version" - that is, you decided to go the hard way by everything simple? - PinkTux
  • The SQL query "select distinct f1 from DPTDAT order by f1" returns a sorted list of all unique values ​​(without repeats) found in the table. After receiving the list, you can use it "as is", without additional tweaks in the code. Bonus - if there are a lot of records in the table, then in the current version you first read them all from the database, load everything into the memory of your software, and then all but ten, simply discard. Using distinct, only 10 entries are involved in all the above processes. By the way, values ​​from 600 to 610 are 11 pieces, and you have 10 variables. - bobzer

2 answers 2

About errors in logic you have already written. I can only note that all the same can be done much easier:

 use DDP; my $rowPRODGRPs = $db->selectcol_arrayref( 'select f1 from DPTDAT group by f1' ); p $rowPRODGRPs; 

Now $rowPRODGRPs contains a reference to an array of f1 values. Assuming that the table has the values 1 , 2 and 3 , it will be displayed (by the line p $rowPRODGRPs; ):

 \ [ [0] 1, [1] 2, [2] 3 ] 

Assign values ​​of array elements to variables:

 my ( $PG1, $PG2, $PG3 ) = @{$rowPRODGRPs}; 

But two questions arise:

  1. What for?
  2. What happens if more values ​​are read than the variables you have written?

In any case, by itself, the need to assign the values ​​of an array to individual variables raises at least questions. In fact, you are simply creating duplicates of already available data, and this event does not seem to be very meaningful.

    use a hash for unique values.

     for $value ( 1, 2, 3, 2, 3, 2 ) { $uniq{ $value }++; } print keys %$uniq; # 1 2 3 ( $var1, $var2, $var3, $var4 ) = keys %$uniq; # Количество сколько раз встречалось значение print values %$uniq; # 1 3 2