Perl-在从数组中读取列时将数据插入到SQL中?

时间:2017-06-16 15:48:20

标签: sql perl dbi dbd

问题比听起来简单(我认为)。 我有一个名为table的数据库表,我试图在名为first的列中插入数据。 以下是代码的一部分:

 my $stmt = $dbh->prepare($sql);
@array=("first","second","third");    
$sql = "INSERT INTO table($array[0]) VALUES(?)";
$stmt->execute($some_value); 

程序在没有警告的情况下运行,但它只是用0填充表,这与$some_value不同。

1 个答案:

答案 0 :(得分:5)

首先,命名一个表table是一个坏主意,因为你可能不时地逃避它的名字。

其次,你的陈述是错误的。首先准备一些语句(包含未知内容),然后只为该变量分配一个SQL语句。

试试这个:

my @columns = ("first","second","third");    
my $sql = "INSERT INTO table(" . $dbh->quote_identifier($columns[0]) . ") VALUES(?)";
my $stmt = $dbh->prepare($sql);
$stmt->execute($some_value);

我没有对此进行测试,但可能需要编写

my $sql = "INSERT INTO `table` (" . $dbh->quote_identifier($columns[0]) . ") VALUES(?)";

因为table是SQL中的关键字。最好根据它所包含的东西来命名,而不是它的形状。

正如@ikegami在评论中指出的那样,让DBI驱动程序引用列名称(使用quote_identifier()而不是直接使用它们)也更好,因为它总是危险的从(不可信的)变量构建SQL语句。

也许您对语句准备的工作方式感到困惑。调用prepare后,基本陈述无法改变,这意味着在

INSERT INTO mytable (col1, col2) VALUES (?,?)

您只能为两个?占位符提供不同的值,然后使用这些?的不同值重新执行相同的语句。 例如,无法编写

INSERT INTO ? (?, ?) VALUES (?,?)

然后prepare该语句然后运行

$sth->execute('my_table', 'col1', 'col2', 'val1', 'val2');

这不会奏效。

如果要运行两个不同的INSERT语句(对于两个不同的列),则需要准备两次。根据您的实际情况,您可以

my $stmt_for_col1 = $dbh->prepare("INSERT INTO my_table (col1) VALUES (?)");
my $stmt_for_col2 = $dbh->prepare("INSERT INTO my_table (col2) VALUES (?)");

然后根据需要随意执行两个语句:

$stmt_for_col1->execute('value_for_col1');
$stmt_for_col2->execute('value_for_col2');
$stmt_for_col1->execute('value_for_col1');

一次只使用一个语句:

my $stmt = $dbh->prepare("INSERT INTO my_table (col1) VALUES (?)");
$stmt->execute('value_for_col1');
$stmt->execute('value_for_col1');

$stmt = $dbh->prepare("INSERT INTO my_table (col2) VALUES (?)");
$stmt->execute('value_for_col2');
$stmt->execute('value_for_col2');

prepare步骤在每个语句中完成一次,execute步骤可以(通常是)在循环中运行,以使语句以不同的值执行。