2009-07-08 3 views
3

Perl과 DBI 모듈을 사용하여 SQL Server 데이터베이스에서 데이터를 읽으려고합니다. 내 의도는 데이터를 읽고 텍스트 파일 (쉼표로 구분)로 인쇄하는 것입니다. 나는이 작업을 수행 할 때, 나는 결과를 다음과 같이 얻을 :배열 다듬기 (DBI로 채움)

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

그래서 두 번째 변수 데이터와 쉼표 사이에 공백이 있습니다. 나는 아래 코드를 사용하여 이것을 다듬 으려고했으나 작동하지 않았다. 해당 공백을 제거하기 위해 코드를 수정해야합니까?

내 코드는 여기에 있습니다 :

#!/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

당신이 새로운 것이므로 표준 SO 에티켓을 알려 드리겠습니다. 1.- 상향 회답을하고, 특히 그들이 원했던 것이라면 (나쁜 답변을 downvote) 2.- 답을 추가하는 대신 질문을 수정하십시오. 포럼이 아닙니다. 다행이야! –

+0

Vinko를 에코하여 답변을 수락하고 답변으로 게시 한 답변을 삭제하는 것이 좋습니다. –

답변

5

귀하의 트림() 함수는 장소의 목록을 수정하지 않습니다 (않으며이 목록을 처리합니다).

그래서, 실제 TIMTOWTDI 방식으로, 새로운 배열을 반환하는 기능을 수정해야 하나

:

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"; 

또는 함수에 대한 참조를 통과 한 후 자리에 배열을 수정

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"; 

또는 사용지도

#!/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; 
} 

않거나 다시 것이다 $ /를 수정하여, 씹는를 사용해보십시오 뒷 공간을 움직여 라.

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

ChopBlanks 속성은 CHAR 필드의 후행 공백 (드라이버가 지원하는 경우 즉 트림 : DBD :: ODBC는 ChopBlanks 속성을 지원하는 경우

#!/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가 어떤 이유로 작동하지 않았습니다 (이유를 확인할 시간이 없었습니다). 함수 내부의 배열은 다듬어 지지만 바깥 쪽은 영향을받지 않습니다. trimArray는 잘 작동합니다. –

+0

trimInPlace는 로컬 복사본'@ arr'에서 작업 중이며,'@ $ arrRef'에 작용해야합니다 :'... my $ arrRef = shift; 내 $ val (@ $ arrRef) {$ val = ~ s/\ s + $ //; }' – tstrit

1

또한 확인할 수 있었다. .. 만약 DBD :: ODBC가 잘 모르겠다.)

+0

DBD :: ODBC는 열이 char 인 동안 ChopBlanks를 지원합니다. 작동하지 않는다면 저에게 예제를 보내 주시면 보겠습니다. – bohica

0

왜 그 필드는 공백 문자가 뒤따 릅니 까? 대개 데이터베이스 모델에 문제가 있다고 지적합니다. trim() 기능 외에도 데이터가 더러운 이유를 조사 할 수 있습니다.

+0

N-M 문자 만 삽입 한 경우에도 MS SQL Server의 char (N) 열이 N 문자로 반환됩니다. 당신이 varchar 컬럼을 사용하고 싶지 않다면. – bohica