Hallo,
vorab drei Tipps:
-  nutze lexikalische Filehandles open (my $datei,'<',$druck) ... <$datei> ...
 -  verwende die 3-Argumenten-Form von open (s.o.) durchgängig
 -  für das Einlesen der CSV-Datei gibt es spezialisierte Module (z.B. 
Text::CSV). Verwende eins, denn das kümmert sich um Escapes und andere Sonderfälle, an die Du nicht denkst. Selbst wenn Du momentan mit Deinem einfachen split klar kommst, mit solch einem Modul bist Du auf der sicheren Seite. Welches Modul das beste für Deinen Zweck ist, kann ich Dir aus eigener Erfahrung nicht sagen, aber da gibt es hier im Forum ausreichend Tipps und Expertise 
Dann zu Deinen eigentlichen Problemen: 
Zeile 11: 
<DATEI> wird hier im skalaren Kontext ausgewertet, d.h. eine Zeile aus der Datei wird ausgelesen - und weggeworfen, weil Du das Ergebnis nicht speicherst. Du willst hier 
while (my $line = <$datei>) {...}
Zeile 12:
Da überschreibst Du für jeden Schleifendurchlauf den kompletten Hash 
%rolle. Beim Code für die Ausgabe ab Zeile 19 kommen also nur die Werte an, die Du im letzten Schleifendurchlauf ausgelesen hast.
Mit 
 %rolle = split m/;/, $line,7; wäre das die letzte Zeile - und die extrem verhackstückt, denn 
split spaltet die Zeile in eine Liste der einzelnen Felder auf und die wird dann in einen Hash gewandelt, nach dem Muster (key0, value0, key1, value1,...) Du bekommst dann z.B.
%rolle = (102 => 'StandortXX',
                    4049 => 9088,
                    12060 => -);
 
 
d.h. 102, 4049 und 12060 sind Keys.
Aber halt, Du verwendest in der Argumentenliste von 
split taucht bei Dir 
<DATEI> auf. D.h. das wird im List-Kontext ausgewertet. Dann werden alle verbleibenen Zeilen auf einen Schlag ausgelsene und als Argumente von 
split verwendet. D.h. nur die 2. Zeile Deiner Eingabedatei wird gesplittet (die 1. hast Du ja schon beim while weggeworfen), die 3. wird als Limit für split verwendet und der Rest wird wieder weggeworfen. Deine While-Schleife wird auch nur einmal durchlaufen.