将标量变量保存到DB(sqlite3)时遇到问题?

时间:2017-01-01 16:16:23

标签: perl sqlite

#我将输出保存到数组中,数组如下所示: -

60=20130624-09:45:02.046|21=1|38=565|52=20130624-09:45:02.046|35=D|10=085|40=1|9=205|100=MBTX|49=11342|553=2453|34=388|1=30532|43=Y|55=4323|54=1|56=MBT|11=584|59=0|114=Y|8=FIX.4.4|

#然后我将这个数组转换为标量变量,如下所示: -

$ scal = join('',@ arr);

#现在我想把它保存到db: -

my $st = qq(INSERT INTO demo (fix)
      VALUES ($scal));
my $r = $dbh->do($st) or die $DBI::errstr;

#And my table schema is:-

CREATE TABLE demo (fix varchar);

And I keep getting errors :- DBD::SQLite::db do failed: near ":45": syntax error at pdb.pl line 92, <STDIN> line 1.
DBD::SQLite::db do failed: near ":45": syntax error at pdb.pl line 92, <STDIN> line 1.

Any help will be appreicated

1 个答案:

答案 0 :(得分:3)

表示阵列的方式有点奇怪。通常你会把它写成

my @arr = ( '60=20130624-09:45:02.046',
            '21=1',
            '38=565',
            ... );

或您的实际内容。但这不是问题所在,因为无论如何你将它展平为字符串$scal

将此字符串插入数据库的一种方法是在其周围添加刻度线('):

my $st = qq(INSERT INTO demo (fix) VALUES ('$scal'));
my $r = $dbh->do($st) or die $DBI::errstr;

但这很糟糕因为它容易受到SQL注入(http://imgs.xkcd.com/comics/exploits_of_a_mom.png)的攻击。 考虑一下你的字符串是foo'); delete from demo; --的情况。最后的结果将是

INSERT INTO demo (fix) VALUES ('foo'); delete from demo; --')

这是错误的第二个原因:你的字符串可能包含刻度线($scal="foo's bar"),这也会弄乱最终的INSERT语句:

INSERT INTO demo (fix) VALUES ('foo's bar');

结论:使用参数化查询总是

my $st = 'INSERT INTO demo (fix) VALUES (?)';
my $r = $dbh->do($st, undef, $scal) or die $DBI::errstr;

undef用于其他SQL选项(我很少看到与此处undef不同的任何内容)。语句中的?替换了以下参数。 DB驱动程序会为您完成所有引用。您使用的?越多,您必须为do()提供的参数越多:

my $st = 'INSERT INTO sample_tbl (col1, col2, col3) VALUES (?, ?, ?)';
my $r = $dbh->do($st, undef, 'foo', 42, $scal) or die $DBI::errstr;