2012-05-22 46 views
1

我使用的代碼:分裂在Perl字符串轉換成數據庫

$data_read=$port_obj->read($buffer); 
print "$data_read\n"; 

輸出是這樣的:

T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165 

我希望把它在這:

$T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K 

所以我可以將它寫入MySQL數據庫。我該怎麼做 ?

我的數據庫處理程序:

$query = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) 
      VALUES ($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K)"; 

$query_handle = $connect->prepare($query); 

$query_handle->execute(); 
+5

你不應該在查詢插值變量。改爲使用[佔位符](http://search.cpan.org/perldoc?DBI#Placeholders_and_Bind_Values)。 – TLP

+2

如果它們都是數字,那麼沒有太大的危險,但是應該完成驗證它們都是數字。 –

回答

0

我喜歡這樣說:

use strict; 
use warnings; 

my $data_read = "T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165"; 
my %data = split(/\s+|=/, $data_read); 

my @cols = keys %data; 
my $cols = join(', ', @cols); 
my $placeholders = join(', ', ('?')x scalar @cols); 

my $query = "INSERT INTO table ($cols) VALUES ($placeholders)"; 
    # execute like this: 
# $dbh->do($query, undef, @data{@cols}); 

print "$query\n"; 
1

我不知道該把它們放入單獨命名的變量是最好的選擇,但客戶永遠是對的:

use strict; 
use warnings; 

my $data_read = "T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165"; 

my $data = $data_read; 
$data =~ s/[A-KT]=//g; 

print "$data\n"; 

my($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K) = split /\s+/, $data; 

my $query = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) VALUES\n" . 
      "($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K)"; 

print "$query\n"; 

print "\nAlternative:\n"; 
my(@list) = split /\s+/, $data; 
print "@list\n"; 

my $query2 = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K)\nVALUES(" . 
      join(",", @list) . ")"; 

print "$query2\n"; 

當這個片段它會生成:

3420499518 914 97 49 436 428 863 34 771 214 493 165 
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) VALUES 
(3420499518,914,97,49,436,428,863,34,771,214,493,165) 

Alternative: 
3420499518 914 97 49 436 428 863 34 771 214 493 165 
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) 
VALUES(3420499518,914,97,49,436,428,863,34,771,214,493,165) 

腳本的後半部分顯示了一個更簡單的ALT使用數組來保存讀取的值。

顯然,如果您願意,您可以檢查是否將值分配給了所有變量以及其他此類錯誤檢查。

+0

我在想,使用哈希將是最佳的,但我不確定字段名稱可以插入佔位符。 'my%data = map {split/= /} split'',$ data; .... $ dbh-> execute(鍵%data,values%data);'我相信雖然哈希不保存順序,但它們在鍵和值之間保持相同的無序。 – TLP

+0

我隱約想知道如何使用散列,但決定陣列的保證位置性質適合位置輸入。您必須以正確的順序AFAIK將密鑰放入準備好的語句中,然後將值輸入到列表中。我認爲''dbh-> execute()'符號應該在預期值的數目和提供的數目之間產生不匹配; Perl沒有辦法從一個列表中區分兩個列表,而SQL也不提供合適的機制。 –

+0

Tnx Jonathan Leffler ..它的工作原理...最好的版本看起來像「替代」 - 還有一個小問題: –

5

您應該將數據值存儲在散列中,在準備好的SQL語句中使用佔位符,並將散列片傳遞給execute方法。

代碼看起來像擴展上評論喬納森·萊弗勒的回答這個

my $data_read = 'T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165'; 

my %data = $data_read =~/([A-Z0-9]+)/g; 

my $query_handle = $connect->prepare(<<SQL); 
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?) 
SQL 

$query_handle->execute(@data{ qw/ T A B C D E F G H I J K/}); 
2

perldoc keys告訴我們:

哈希的密鑰在一個明顯的隨機順序返回。所述 實際隨機的順序是受試者在Perl, 未來版本的改變,但作爲valueseach 函數產生(假定散列未被修改)它保證是相同的順序。

(重點煤礦)這意味着我們可以使用哈希來收集所有字段名及其相關值,而不需要明確地列舉他們在代碼:

#!/usr/bin/env perl 

use 5.010; 
use strict; 
use warnings; 

my $in = 'T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165'; 

my %data = $in =~ /([A-Z])=([0-9]+)/g; 

my $query = 'INSERT INTO myhouse (' . join(',', keys %data) 
      . ') VALUES (' . join(',', values %data) . ')'; 

say $query; 

(注意,TLP在原始問題的評論中提到,這是只有安全,因爲填充%data的正則表達式保證我們所有的密鑰都將是單個大寫字母,並且值將只包含英文數字如果有任何可能惡意輸入可能導致中的不受控制的鍵或值,那麼您需要對字段名稱進行硬編碼併爲值使用佔位符,除非您想要訪問little Bobby Tables。)