2009-07-08 4 views
3

Я пытаюсь прочитать данные из базы данных SQL Server с помощью Perl и модуля DBI. Мое намерение состоит в том, чтобы прочитать данные и распечатать их в текстовый файл (запятая). Когда я делаю это, я получаю результат, как это:Обрезка массива (заполняется через 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.-Upvote и принимайте ответы, особенно если они то, что вы хотели (downvote плохие ответы) 2.- Измените свой вопрос вместо добавления ответов, это это не форум. Рад, что это сработало! –

+0

Echoing 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; 
} 

или попробовать использовать Chomp, изменяя $ /, который будет только вновь переместите конечное пространство, не более того.

#!/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; для my $ val (@ $ arrRef) {$ val = ~ s/\ s + $ //; } ' – tstrit

1

Вы также можете проверить, если DBD :: ODBC поддерживает атрибут ChopBlanks:

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

атрибута в ChopBlanks обрежет конечные пробела любой CH полей (то есть если ваш драйвер поддерживает его. .. Я не уверен, что DBD :: ODBC делает).

+0

DBD :: ODBC поддерживает ChopBlanks, пока столбец является символом. Если это не сработает, пришлите мне пример, и я посмотрю на него. – bohica

0

Почему у этого поля есть пробелы? Обычно это указывает на какую-то проблему с моделью базы данных. Помимо функции trim(), вы можете выяснить, почему данные загрязнены.

+0

столбцы char (N) в MS SQL Server возвращаются как N символов, даже если вы только вставили символы N-M. Если вы не хотите, чтобы вы использовали столбцы varchar. – bohica

Смежные вопросы