如何在 Perl 中构建具有灵活列数的动态 MySQL INSERT 语句?
How do I build a dynamic MySQL INSERT statement with a flexible column count in Perl?
我知道如何使用 perl 将基本插入 mysql,但我不确定这个问题的标题是否完全准确。
我正在尝试做的事情如下:
-我得到一个带有一些参数的文本文件
"COUNTER","DATE","TIME","ACCEL LAT","ACCEL LONG","ACCEL VERT"
^举个例子。然后我得到这些的 csv 值。
为此,您只需执行以下操作:
$query = "insert into table(counter, date, time, accel_lat, accel_long, accel_vert)
values (?, ?, ?, ?, ?, ?) ";
$statement = $connection->prepare($query);
$statement->execute(MY DATA IN HERE);
但是,我遇到的问题是,我得到的参数是
- a) mysql table 中的子集(从 1 到全部)
- b) 在文本文件中以随机顺序给出
- c) 与 table 中的列名称不同(我想我需要构建一个数据字典来说明哪个 = 什么)
无论如何,我想我的实际问题是我可以让它不是静态的吗?
"insert into table(counter, date, time, accel_lat, accel_long, accel_vert)
假设我的参数文件是:日期、时间、计数器,accel_vert
我可以把语句变成
"insert into table(date, time, counter, accel_vert)
喜欢根据我从文本文件中读取的内容来定义我的插入语句(比如我们如何使用 ? 因为我们还不知道值,我需要一种方法来使用 ? 因为我不知道列他们还没有)。
这可能吗?抱歉,如果我不清楚,如果你问可以解释。
你走在正确的轨道上。您需要动态构建查询。对列名使用变量插值是完全没问题的。您不应该直接使用 CSV 列中的那些。你对字典的想法是正确的。
我写了一个简单的例子。诀窍是在 SQL 中使用正确数量的占位符 ?
。 x
repetition operator 对此很有用。
use strict;
use warnings;
use Text::CSV;
use DBI;
my $dbh = DBI->connect(...);
# csv => mysql
my %column_mapping = (
qux => 'Qux',
foo => 'Foo',
bar => 'Bar',
baz => 'Baz',
);
my $csv = Text::CSV->new or die "Cannot use CSV: " . Text::CSV->error_diag();
# get the headline
my $headers = $csv->getline( \*DATA );
# build the INSERT query based on those column headers
my $sql = sprintf 'INSERT INTO tablename ( %s ) VALUES ( %s )',
join( ',', map { $column_mapping{$_} } @$headers ),
join( ',', ('?') x scalar @$headers ); # note the list around the '?'
my $sth = $dbh->prepare($sql);
while ( my $row = $csv->getline( \*DATA ) ) {
$sth->execute( @$row ) or die $dbh->errstr;
}
__DATA__
foo,bar,baz
1,2,3
5,5,5
在我的示例中,$sql
具有以下值:
INSERT INTO tablename ( Foo,Bar,Baz ) VALUES ( ?,?,? )
另请参阅:
我知道如何使用 perl 将基本插入 mysql,但我不确定这个问题的标题是否完全准确。
我正在尝试做的事情如下: -我得到一个带有一些参数的文本文件
"COUNTER","DATE","TIME","ACCEL LAT","ACCEL LONG","ACCEL VERT"
^举个例子。然后我得到这些的 csv 值。
为此,您只需执行以下操作:
$query = "insert into table(counter, date, time, accel_lat, accel_long, accel_vert)
values (?, ?, ?, ?, ?, ?) ";
$statement = $connection->prepare($query);
$statement->execute(MY DATA IN HERE);
但是,我遇到的问题是,我得到的参数是
- a) mysql table 中的子集(从 1 到全部)
- b) 在文本文件中以随机顺序给出
- c) 与 table 中的列名称不同(我想我需要构建一个数据字典来说明哪个 = 什么)
无论如何,我想我的实际问题是我可以让它不是静态的吗?
"insert into table(counter, date, time, accel_lat, accel_long, accel_vert)
假设我的参数文件是:日期、时间、计数器,accel_vert
我可以把语句变成
"insert into table(date, time, counter, accel_vert)
喜欢根据我从文本文件中读取的内容来定义我的插入语句(比如我们如何使用 ? 因为我们还不知道值,我需要一种方法来使用 ? 因为我不知道列他们还没有)。
这可能吗?抱歉,如果我不清楚,如果你问可以解释。
你走在正确的轨道上。您需要动态构建查询。对列名使用变量插值是完全没问题的。您不应该直接使用 CSV 列中的那些。你对字典的想法是正确的。
我写了一个简单的例子。诀窍是在 SQL 中使用正确数量的占位符 ?
。 x
repetition operator 对此很有用。
use strict;
use warnings;
use Text::CSV;
use DBI;
my $dbh = DBI->connect(...);
# csv => mysql
my %column_mapping = (
qux => 'Qux',
foo => 'Foo',
bar => 'Bar',
baz => 'Baz',
);
my $csv = Text::CSV->new or die "Cannot use CSV: " . Text::CSV->error_diag();
# get the headline
my $headers = $csv->getline( \*DATA );
# build the INSERT query based on those column headers
my $sql = sprintf 'INSERT INTO tablename ( %s ) VALUES ( %s )',
join( ',', map { $column_mapping{$_} } @$headers ),
join( ',', ('?') x scalar @$headers ); # note the list around the '?'
my $sth = $dbh->prepare($sql);
while ( my $row = $csv->getline( \*DATA ) ) {
$sth->execute( @$row ) or die $dbh->errstr;
}
__DATA__
foo,bar,baz
1,2,3
5,5,5
在我的示例中,$sql
具有以下值:
INSERT INTO tablename ( Foo,Bar,Baz ) VALUES ( ?,?,? )
另请参阅: