我正在研究一个项目,我想将一些数据插入到数据库中.我创建了数据库和表,但我遇到了一些问题.
我决定写一个测试程序,这是我的程序代码:
#!/us/bin/perl
use strict;
use warnings;
use Data::Dumper;
use DBI;
my $localtime = localtime(time);
print $localtime,"\n",;
my $char_data;
open(my $fh, "<", "/root/testfile/1453800452_5.117.219.107.bin");
while (<$fh>){
$char_data .= $_;
}
print $char_data,"\n",;
my @Record = unpack('C*',$char_data);
my @IMEI = splice @Record,0,17;
my $IMEI = pack('C*',@IMEI);
#print$IMEI,"\n";
my $dbh = DBI->connect("DBI:Pg:dbname=test;host=localhost","postgres", "", {PrintError=>0,RaiseError=>1});
my $sth=$dbh->prepare(qq/insert into testtime(time,data,imei) values(?,?,?)/);
$sth->execute($localtime,$char_data,$IMEI);
Run Code Online (Sandbox Code Playgroud)
这是我的数据库:
time -----> timestamp without time zone
data------->text
imei-------->varchar
Run Code Online (Sandbox Code Playgroud)
这是我打开的文件的内容:
^ @ ^ O356307043839678 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AM ^ H ^ K ^ @ ^ @ ^ AR} DB ^ H ^ @ ^^\2458\340 ^ UJ(\ 300 ^ d\356 ^ @ ^ @ ^ H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} CW0 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ d\357 ^ @ ^ @ ^\H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} Bl\224 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ D\356 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} A\201\344 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ D\357 ^ @ ^ @ ^ @ ^ @\^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} @\227> ^ @ ^^\2458\340 ^ UJ(\ 300 ^ D\351 ^ @ ^ @ ^ H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}?\ 254\254 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ d\347 ^ @ ^ @ ^ H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^\@ ^ @ ^ AR}>\302 ^ P ^ @ ^^\2458\340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} =\327j ^ @ ^^\2458\340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} <\ 354\330 ^ @ ^\^\2458\340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} <^ B2 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ d\213 ^ @( ^ K ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}; ^ W\226 ^ @ ^^\2458\340 ^ UJ(\ 300 ^ D\\ 215 ^ @ (^ L ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ K ^ @ ^ @〜甲
我的问题是每次运行程序时,只有localtime插入数据库,imei和数据都将保持为空.
谁能帮我这个?
PostgreSQL 不允许数据类型为 的列text包含空字符,并且您尝试在data和imei列中存储的字符串以空字符开头
您应该使用数据类型bytea代替
另外,当您读取二进制文件时,您应该使用 IO 模式:raw,而不是连接多行,您应该将记录分隔符设置$/为undef这样
my $char_data = do {
open my $fh, '<:raw', '/root/testfile/1453800452_5.117.219.107.bin' or die $!;
local $/;
<$fh>;
};
Run Code Online (Sandbox Code Playgroud)
与使用unpack将字符串拆分为数组然后pack将其重新转换为字符串相比,使用substr像这样选择字符串的一部分要方便得多
my $IMEI = substr $char_data, 0, 17
Run Code Online (Sandbox Code Playgroud)
execute当您使用非标准数据类型时,您需要做的不仅仅是将字符串传递给方法。下面是一个示例程序,向您展示如何将数据类型与新准备的语句中的占位符关联起来。对于每个语句句柄只需执行一次。此后,DBI 将知道如何翻译传递给的每个参数execute
我bind_param只呼吁了第二和第三名的占位者。timePostgreSQL 对数据类型的简单字符串值感到满意
我曾经在变量写入数据库之前Data::Dumper显示变量的内容,以及从数据库检索记录后显示记录中的所有值。$imei正如你所看到的,两者应该是匹配的
use strict;
use warnings 'all';
use feature 'say';
use DBI;
use DBD::Pg qw/ PG_BYTEA /;
use Data::Dumper;
$Data::Dumper::Useqq = 1;
$Data::Dumper::Terse = 1;
my $char_data = do {
open my $fh, '<:raw', '1453800452_5.117.219.107.bin';
local $/;
<$fh>;
};
my $imei = substr $char_data, 0, 17;
say Dumper $imei;
my $dbh = DBI->connect(
"DBI:Pg:dbname=test;host=localhost",
'postgres', '',
{
PrintError => 0,
RaiseError => 1,
}
);
$dbh->do('DROP TABLE test');
$dbh->do(<<'END_SQL');
CREATE TABLE test (
"time" timestamp without time zone,
"data" bytea,
"imei" bytea
)
END_SQL
my $insert = $dbh->prepare('INSERT INTO test (time, data, imei) VALUES (?, ?, ?)');
$insert->bind_param(2, undef, { pg_type => PG_BYTEA });
$insert->bind_param(3, undef, { pg_type => PG_BYTEA });
$insert->execute(scalar localtime, $char_data, $imei);
my @row = $dbh->selectrow_array('SELECT * FROM test');
say Dumper \@row;
Run Code Online (Sandbox Code Playgroud)
"\0\017356307043839678"
[
"2016-01-31 17:20:08",
"\0\017356307043839678\0\0\0\0\0\0\1M\b\13\0\0\1R}DB\b\0\36\\2458\\340\25J(\\300\4\\356\0\0\b\0\0\0\0\0\0\0\0\0\0\1R}CW0\0\36\\2458\\340\25J(\\300\4\\357\0\0\34 H\0\0\0\0\0\0\0\0\0\0\1R}Bl\\224\0\36\\2458\\340\25J(\\300\4\\356\0\0 \0\0\0\0\0\0\0\0\0\0\1R}A\\201\\344\0\36\\2458\\340\25J(\\300\4\\357\0\0 \0\0\\ \0\0\0\0\0\0\0\0\1R}\@\\227>\0\36\\2458\\340\25J(\\300\4\\351\0\0\b\0\0\0\0\0\0\0\0\0\0\1R}?\\254\\254\0\36\\2458\\340\25J(\\300\4\\347\0\0\b\0\0\0\0\0\0\0\0\34 \@\0\1R}>\\302\20\0\36\\2458\\340\25J(\\300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1R}=\\327j\0\36\\2458\\340\25J(\\300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1R}<\\354\\330\0\34 \0342458\\340\25J(\\300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1R}<\0022\0\36\\2458\\340\25J(\\300\4\\213\0(\13\0\0\0\0\0\0\0\0\0\0\1R};\27\\226\0\36\\2458\\340\25J(\\300\4\\ \\215\0(\f\0\0\0\0\0\0\0\0\13\0\0~A\n",
"\0\017356307043839678"
]
Run Code Online (Sandbox Code Playgroud)