Why perl put empty on my database while it has value? Why perl put empty on my database while it has value? postgresql postgresql

Why perl put empty on my database while it has value?


PostgreSQL doesn't allow columns with a data type of text to contain null characters, and the strings you are trying to store in both your data and imei columns start with a null character

You should use a data type of bytea instead

Also, you should use an IO mode of :raw when you are reading binary files, and rather than concatenating multiple lines you should set the record separator $/ to undef like this

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

And rather than use unpack to aplit your string into an array and then pack to reform it into a string, it is much more convenient to use substr to select part of the string like this

my $IMEI = substr $char_data, 0, 17



You need to do a little more than just pass the strings to the execute method when you are using non-standard data types. Here's an example program that shows you how to associate data types with the placeholders in a newly-prepared statement. It needs to be done only once for each statement handle. Thereafter, DBI will know how to translate each parameter passed to execute

I have called bind_param only for the second and third placeholders. PostgreSQL is happy with a simple string value for time datatypes

I have used Data::Dumper to display the contents of the $imei variable before it is written to the database, as well as all the values in the record after it is retrieved from the database. As you can see, the two match as they should

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_SQLmy $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;

output

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