为什么perl在我的数据库有空值时会为空?

时间:2016-01-31 06:04:56

标签: perl postgresql

我正在开发一个项目,我想将一些数据插入到数据库中。我创建了数据库和表,但是我遇到了一些问题。

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

#!/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);

这是我的db:

time -----> timestamp without time zone

data------->text

imei-------->varchar           

这是我打开的文件的内容:

^ @ ^ 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&GT; ^ @ ^^ \ 2458 \ 340 ^ UJ(\ 300 ^ d \ 351 ^ @ ^ @ ^ H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}?\ 254 \ 254 ^ @ ^^ \ 2458 \ 340 ^ UJ(\ 300 ^ d \ 347 ^ @ ^ @ ^ H ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ \ @ ^ @ ^ AR}&GT; \ 302 ^ P ^ @ ^^ \ 2458 \ 340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR} = \ 327j ^ @ ^^ \ 2458 \ 340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}&LT; \ 354 \ 330 ^ @ ^ \ ^ \ 2458 \ 340 ^ UJ(\ 300 ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}&LT; ^ B2 ^ @ ^ ^ \ 2458 \ 340 ^ UJ(\ 300 ^ d \ 213 ^ @(^ K ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ AR}; ^ W \ 226 ^ @ ^ ^ \ 2458 \ 340 ^ UJ(\ 300 ^ d \ \ 215 ^ @(^ L ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ K ^ @ ^ @〜A

我的问题是每次运行程序时,只有localtime插入数据库,imei和数据都将保持为空。

任何人都可以帮我吗?

1 个答案:

答案 0 :(得分:4)

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

您应该使用bytea的数据类型

此外,在阅读二进制文件时应使用:raw的IO模式,而不是连接多行,您应该将记录分隔符$/设置为undef,如下所示< / p>

my $char_data = do {
    open my $fh, '<:raw', '/root/testfile/1453800452_5.117.219.107.bin' or die $!;
    local $/;
    <$fh>;
};

而不是使用unpack将字符串变为数组,然后pack将其重组为字符串,使用substr选择部分字符串会更方便像这样的字符串

my $IMEI = substr $char_data, 0, 17


当您使用非标准数据类型时,您需要做的不仅仅是将字符串传递给execute方法。这是一个示例程序,向您展示如何在新准备的语句中将数据类型与占位符相关联。每个语句句柄只需要执行一次。此后,DBI将知道如何转换传递给execute

的每个参数

我仅为第二和第三个占位符调用了bind_param。 PostgreSQL对time数据类型

的简单字符串值感到满意

我使用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;

输出

"\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"
]