I am trying to insert dates extracted from JSON into a table but getting errors
My code is as follows:
create table tmp (
c TEXT
);
CREATE TEMP TABLE Channel_Info (
ID int NOT NULL,
ChannelID INT,
DeviceChannelID UUID,
SerialNumber VARCHAR(10),
DownloadTableName VARCHAR(100),
ReadingTrimDate timestamp without time zone,
BeginningDate timestamp without time zone,
EndDate timestamp without time zone
);
insert into tmp values
('{
"SerialNumber":"940860",
"ChannelIDs":[17,13,11,12,14],
"BeginningDate":"2023-05-20T11:53:39",
"EndDate":"2023-05-22T09:04:04"
}');
Now this is all defined , i am attempting to insert data from my JSON into the
temporary table Channel_Info as follows:
INSERT INTO Channel_Info(ID,ChannelID,SerialNumber,BeginningDate,EndDate)
select
row_number() over (order by ChannelID::text::int ) as ID,
ChannelID::text::int,
c::json ->> 'SerialNumber' as SerialNumber,
c::json ->> 'BeginningDate' as BeginningDate,
c::json ->> 'EndDate' as EndDate
from tmp
CROSS JOIN LATERAL json_array_elements(c::json -> 'ChannelIDs') as ChannelID
But get the following error:
[2023-11-07 13:12:18] [42804] ERROR: column "beginningdate" is of type timestamp without time zone but expression is of type text
[2023-11-07 13:12:18] Hint: You will need to rewrite or cast the expression.
[2023-11-07 13:12:18] Position: 241
Now i tried the following:
INSERT INTO Channel_Info(ID,ChannelID,SerialNumber,BeginningDate,EndDate)
select
row_number() over (order by ChannelID::text::int ) as ID,
ChannelID::text::int,
c::json ->> 'SerialNumber' as SerialNumber,
c::json::timestamp without time zone ->> 'BeginningDate' as BeginningDate,
c::json::timestamp without time zone ->> 'EndDate' as EndDate
from tmp
CROSS JOIN LATERAL json_array_elements(c::json -> 'ChannelIDs') as ChannelID
but got the following error :
[2023-11-07 13:15:08] [42846] ERROR: cannot cast type json to timestamp without time zone
[2023-11-07 13:15:08] Position: 173
2
Answers
You need to cast date columns from text (operator
->>
return JSON element as text) totimestamp
:Demo here
You shouldn’t need the cast at all, the string returned from
c::json ->> 'BeginningDate'
will be automatically cast on INSERT per this example:So:
c::json ->> 'BeginningDate' as BeginningDate
will work.
Your issue was
c::json::timestamp without time zone
which was trying to cast the entire JSON object:as
timestamp without time zone
instead of just the"BeginningDate"
value"2023-05-20T11:53:39"
.