2009-07-08 8 views
3

Ich versuche, Daten aus SQL Server-Datenbank mit Perl und dem DBI-Modul zu lesen. Meine Absicht ist es, die Daten zu lesen und sie in eine Textdatei (kommagetrennt) zu drucken. Wenn ich das tue, erhalte ich das Ergebnis wie folgt aus:Trimmen eines Arrays (gefüllt über DBI)

var1,var2,var3 
40406,20 ,783 
50230,78 ,680 
50230,78 ,680 
50230,78 ,680 
50230,78 ,680 

So gibt ein Leerzeichen zwischen den zweiten variablen Daten und dem Komma. Ich habe versucht, dies mit dem Code unten zu trimmen, aber es hat nicht funktioniert. Wie sollte ich meinen Code ändern, um diese Leerzeichen zu entfernen?

Mein Code ist hier:

#!/bin/perl 
use warnings; 
use strict; 
use DBI; 

sub trim; 

my $dbs = "dbi:ODBC:DRIVER={SQL Server};SERVER={xxxx}"; 
my ($username, $password) = ('un', 'pwd'); 

my $dbh = DBI->connect($dbs, $username, $password) 
       or die "Can't connect to $dbs: $DBI::errstr"; 

my $sth = $dbh->prepare("select var1, var2, var3 from db.dbo.table") 
       or die "Can't prepare statement: $DBI::errstr"; 

$sth->execute(); 

my $outfile = 'temp.txt'; 
open OUTFILE, '>', $outfile or die "Unable to open $outfile: $!"; 

print OUTFILE join(",", @{$sth->{NAME}}), "\n"; 

while (my @re = $sth->fetchrow_array) { 
    print OUTFILE join(",", trim(@re)), "\n"; 
} 

close OUTFILE; 

$sth->finish(); 
$dbh->disconnect(); 

############## subroutines ################## 
sub trim($) { 
    my $string = shift; 
    $string =~ s/^\s+//; 
    $string =~ s/\s+$//; 
    return $string; 
} 
+0

Sie sind neu, also werde ich Ihnen die Standard-SO-Etikette sagen: 1.- Upvote und Antworten annehmen, besonders wenn sie das sind, was Sie wollten (schlechte Antworten ablehnen) 2.- Ändern Sie Ihre Frage, anstatt Antworten hinzuzufügen, dies ist kein Forum. Froh, dass es funktioniert hat! –

+0

Als Echo auf Vinko empfehle ich Ihnen, seine Antwort zu akzeptieren und die Antworten zu löschen, die Sie als Antworten gepostet haben. –

Antwort

5

Ihre Funktion trim() die Liste nicht an Ort und Stelle nicht verändert (noch es behandelt eine Liste).

also in Echt TIMTOWTDI Art und Weise, sollten Sie entweder die Funktion ändern, um eine neue Array zurück:

sub trimArray { 
    my @arr = @_; 
    my @rv; 
    for my $val (@arr) { 
     $val =~ s/^\s+//; 
     $val =~ s/\s+$//; 
     push @rv, $val; 
    } 
    return @rv; 
} 

#and then 

print OUTFILE join(",", trimArray(@re)), "\n"; 

oder einen Verweis auf Ihre Funktion übergeben und dann das Array anstelle ändern

sub trimInPlace { 
    my $arrRef = shift; 
    for my $val (@$arrRef) { 
     $val =~ s/^\s+//; 
     $val =~ s/\s+$//; 
    } 
} 

#and then 

trimInPlace(\@re); #Note the \ 
print OUTFILE join(",", @re), "\n"; 

oder Nutzungskarte

#!/bin/perl 
use warnings; 
use strict; 
use DBI; 

#... the same 

while (my @re = $sth->fetchrow_array) { 
    print OUTFILE join(",", map { trim($_); } @re), "\n"; #Applies 
                 #trim() to each element 
} 

#... 

############## subroutines ################## 
sub trim { #Don't use prototypes 
    my $string = shift; 
    $string =~ s/^\s+//; 
    $string =~ s/\s+$//; 
    return $string; 
} 

oder versuchen chomp verwenden, um $ /, Änderung, die nur wieder wird Verschiebe einen nachgestellten Raum, nichts mehr.

#!/bin/perl 
use warnings; 
use strict; 
use DBI; 

#... the same 

my $old_sep = $/; 
$/ = " "; 
while (my @re = $sth->fetchrow_array) { 
    chomp(@re); #Modifies in place, returning number of changes 
    print OUTFILE join(",", @re), "\n"; 
} 
$/ = $old_sep; 
+0

trimInPlace funktionierte nicht aus irgendeinem Grund (hatte keine Zeit, um nach dem Grund zu suchen). Das Array innerhalb der Funktion ist getrimmt, aber außerhalb ist nicht betroffen. trimArray funktioniert gut. –

+0

trimInPlace arbeitet an lokaler Kopie '@ arr', sollte auf' @ $ arrRef' wirken: '... my $ arrRef = shift; für mein $ val (@ $ arrRef) {$ val = ~ s/\ s + $ //; } ' – tstrit

1

Sie können auch prüfen, ob DBD :: ODBC unterstützt die ChopBlanks Attribut:

my $dbh = DBI->connect($dbs, $username, $password, { ChopBlanks => 1 }) 

der ChopBlanks Attribut trimmt die nachfolgenden Leerzeichen von irgendwelchen CHAR-Feldern (dh wenn Ihr Treiber unterstützt wird. .. Ich bin mir nicht sicher, ob DBD :: ODBC das tut).

+0

DBD :: ODBC unterstützt ChopBlanks, solange die Spalte ein Zeichen ist. Wenn es nicht funktioniert, sende mir bitte ein Beispiel und ich werde es mir anschauen. – bohica

0

Warum hat dieses Feld nachgestellte Leerzeichen? Normalerweise deutet das auf ein Problem mit dem Datenbankmodell hin. Neben der trim() Funktion könnten Sie untersuchen, warum die Daten schmutzig sind.

+0

char (N) Spalten in MS SQL Server werden als N Zeichen zurückgegeben, auch wenn Sie nur N-M Zeichen eingefügt haben. Wenn Sie nicht möchten, dass Sie Varchar-Spalten verwenden. – bohica

Verwandte Themen