PostgreSQL does not allow columns with text data type to contain null characters, and the rows you are trying to store in both data and imei columns begin with a null character
Instead you should use the bytea data bytea
In addition, you should use the I / O :raw mode when you read binary files, and instead of 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 instead of using unpack to add a string to an array and then pack to convert it to a string, it is much more convenient to use substr to select a part of a string like this
my $IMEI = substr $char_data, 0, 17
You need to do a little more than just pass strings to the execute method when using non-standard data types. Here is an example program that shows how to associate data types with placeholders in a recently prepared statement. This needs to be done only once for each instruction descriptor. After that, the DBI will know how to translate each parameter passed to execute
I called bind_param only for the second and third placeholders. PostgreSQL satisfied with a simple string value for time datatypes
I 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 received from the database. As you can see, they 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_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;
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" ]