为什么perl在我的数据库有空的时候放空?

far*_*ane 5 postgresql perl

我正在研究一个项目,我想将一些数据插入到数据库中.我创建了数据库和表,但我遇到了一些问题.

我决定写一个测试程序,这是我的程序代码:

#!/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和数据都将保持为空.

谁能帮我这个?

Bor*_*din 4

PostgreSQL 不允许数据类型为 的列text包含空字符,并且您尝试在dataimei列中存储的字符串以空字符开头

您应该使用数据类型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)