I have strings like this: '2022-02-28T04:45:37.123456789Z'
Does anyone know why this fails:
select '2022-02-28T04:45:37.123456789Z'::timestamp9
SQL Error [22008]: ERROR: invalid input format for timestamp9, required format y-m-d h:m:s.ns +tz "2022-02-28T04:45:37.123456789Z"
Position: 8
whereas this is fine:
select '2022-02-28T04:45:37Z'::timestamp9
What I found, using timestamp9 extension.
create extension timestamp9 ;
select '2022-02-28T04:45:37.123456789Z'::timestamp9;
ERROR: invalid input format for timestamp9, required format y-m-d h:m:s.ns +tz "2022-02-28T04:45:37.123456789Z"
LINE 1: select '2022-02-28T04:45:37.123456789Z'::timestamp9;
--What I thought would work, but didn't
select '2022-02-28T04:45:37.123456789 +0000'::timestamp9;
ERROR: invalid input format for timestamp9, required format y-m-d h:m:s.ns +tz "2022-02-28T04:45:37.123456789 +0000"
LINE 1: select '2022-02-28T04:45:37.123456789 +0000'::timestamp9;
--What does work
select '2022-02-28 04:45:37.123456789 +0000'::timestamp9;
timestamp9
-------------------------------------
2022-02-27 20:45:37.123456789 -0800
--A quick and dirty solution
select replace(replace('2022-02-28T04:45:37.123456789Z', 'T', ' '), 'Z', ' +0000')::timestamp9;
replace
-------------------------------------
2022-02-27 20:45:37.123456789 -0800
Related
I am facing a issue to load a csv resulting froma query that encryts a text.
This is the query I run:
select
id,
encode(encrypt_iv(raw_address::bytea, '<aes_key>', '<iv>', 'aes-cbc/pad:pkcs'), 'base64') raw_address
from some_table;
But I got a multiline text as result for raw_address column. So I tried:
select
id,
encode(encrypt_iv(replace(raw_address, chr(92), chr(47))::bytea, '<aes_key>', '<iv>', 'aes-cbc/pad:pkcs'), 'base64') raw_address
from some_table;
This because I just wanted to make this \ into this / (to avoid \n)
This is the result example:
But got the same result. Then I found this answer and realize that + char was present, so I tried:
select
id,
replace(encode(encrypt_iv(replace(raw_address, chr(92), chr(47))::bytea, '<aes_key>', '<iv>', 'aes-cbc/pad:pkcs'), 'base64'), chr(10), '')
from, some_table;
Then I got one line:
But I don't know if I am modifing the original value, I can not decrypt the value. I tried:
select encode(decrypt_iv('55WHZ7tyGAlQxTIM0fPfY5tOKpbYzwdXCsemIgYV5TRG+h45IW1nU/zCqZbkIeiXQ3OXZSlHo0RPgq5wcgJ0xQ==', '<aes_key>', '<iv>', 'aes-cbc/pad:pkcs'), 'base64') ;
But I got:
ERROR: decrypt_iv error: Data not a multiple of block size
Any suggestion will be appreciated.
Thanks in advance!
Current Date Format: 12-18-2018-03:14:48
I want to convert to: 2018-12-18 03:14
Currently using SQL Server 2008
I'm using this code syntax:
DECLARE #input VARCHAR(35) = '12-18-2018-03:14:48'
SELECT CONVERT(DATETIME, #input, 120)
Error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
Please help. Thank you!
I'm not sure that your current datetime literal falls into any mask which SQL Server can recognize. But we can try using TRY_CONVERT here, replacing the middle dash with a space:
SELECT TRY_CONVERT(datetime, STUFF(#input, 11, 1, ' ')) AS output;
18/12/2018 03:14:48
Demo
Edit:
If you are using an earlier version of SQL Server which does not support TRY_CONVERT, then we can try explicitly using CONVERT:
SELECT CONVERT(datetime, STUFF(#input, 11, 1, ' ')) AS output;
I have a var: acc_date with type date.
It takes its value from a cursor and when I insert its value to logger table as:
insert into logger values(1,acc_date);
the out put when a select it from logger is
1 01-JAN-10
but when i use it to compare with another Date value in another cursor as
OPEN c_get_date_id
for 'SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE='||acc_date;
EXIT WHEN c_get_date_id%NOTFOUND;
FETCH c_get_date_id
INTO date_id;
insert into logger values (1,'Now with date_id'||date_id);
CLOSE c_get_date_id;
an error occurs:
Error report:
ORA-00904: "JAN": invalid identifier
ORA-06512: at "HW.FILLFACT", line 82
ORA-06512: at line 1
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
strong text
You need at least add some quotes around the date:
....' where Date_D.DATEVALUE='''||acc_date||'''';
Double apostrophes within a string will be concatenated to a single apostrophe, so that the expression becomes
where Date_D.DATEVALUE='....';
In order to make the thing more foolprof, I'd also add a specific to_date:
.... ' where Date_D.DATEVALUE=to_date(''' || acc_date || ', ''dd-mon-yy'')';
At the moment your dynamic query is being interpreted as:
SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE=01-JAN-10
The error is because string representation of the date isn't being quoted, so it's seeing JAN as an identifier - and nothing matches that name. You could enclose the date value in quotes:
open c_get_date_id
for 'SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE='''||acc_date||'''';
But you're treating the date as a string, and forcing conversion of all your table values to strings to be compared, using your session's NLS_DATE_FORMAT. It would be better to compare it as a date (although this somewhat assumes all your values have the time portion set to midnight):
open c_get_date_id
for select date_d.datekey from date_d where date_d.datevalue = acc_date;
Your exit is in the wrong place though, and you aren't looping, so maybe you want:
open c_get_date_id
for select date_d.datekey from date_d where date_d.datevalue = acc_date;
loop
fetch c_get_date_id into date_id;
exit when c_get_date_id%notfound;
insert into logger values (1, 'Now with date_id'||date_id);
end loop;
close c_get_date_id;
If you only have one value in the first place though, you probably don't want a loop or cursor at all, and could do a simple select ... into instead:
select date_d.datekey into date_id from date_d
where date_d.datevalue = acc_date;
insert into logger values (1, 'Now with date_id'||date_id);
Though of course that would error if you had no matching date in your table, or more than one, and you'd need to deal with that - but then I guess you'd want to anyway.
I have a Table with coloumnname description
description //character varying
LZ000834_28-02-14
LZ000834_28-02-14
LA20683_30-04-15
LA20683_30-04-15
LA20300_31-01-15
LA20300_31-01-2015
LA20264_31-01-15
LA20264_31-01-2016
LAN2078_31-03-16
LAN2078_31-03-15
LAN8394_31-04-14
L2Z82736_31_03_2015 //has 1million rows
here description means batchname_expirydate
my question is how do I normalize my description column convert all those dates to DD-MM-YY format
i have tried this two queries
select substring(description from position('_' in description) +1) from attributesetinstance;
above query will give me all the strings then i tried date conversion like this
select to_date(substring(description from position('_' in description) +1), 'DD-MM-YY') from attributesetinstance;
now this gives me error
ERROR: invalid value "_3" for "DD"
DETAIL: Value must be an integer.
********** Error **********
ERROR: invalid value "_3" for "DD"
SQL state: 22007
Detail: Value must be an integer.
how do update/recorrect all my database ?
update:
tried with another sql
with product_dates AS (
select description, ((val[2])||'-'||val[3]||'-'||val[4])::date as expir_date
from (
select description,regexp_matches(description, '([a-zA-Z0-9]+)_([0-9]+)[-_]([0-9]+)[-_]([0-9]+)') as val
from attributesetinstance
) a
), expiring_dates AS (
select description from product_dates
)
select description from expiring_dates
i get following error:
ERROR: date/time field value out of range: "31-04-14"
********** Error **********
ERROR: date/time field value out of range: "31-04-14"
SQL state: 22008
update
my postgres datestyle
show datestyle;
"ISO, DMY"
This error message is not well - this date 2014-04-31 is invalid. So you cannot to cast this string to date with algorithm, that you used. But to_date function is fault tolerant
postgres=# select '2014-04-31'::date;
ERROR: date/time field value out of range: "2014-04-31"
LINE 1: select '2014-04-31'::date;
^
Time: 0.551 ms
postgres=# select to_date('2014-04-31','YYYY-MM-DD');
to_date
────────────
2014-05-01
(1 row)
This code works
postgres=# select to_date(replace(substring('LA20683_30_04_15' from '\d+[-_]\d+[-_]\d+$'),'_','-'), 'DD-MM-YY');
to_date
────────────
2015-04-30
(1 row)
Time: 57.840 ms
postgres=# select to_date(replace(substring('LA20683_30_04_2015' from '\d+[-_]\d+[-_]\d+$'),'_','-'), 'DD-MM-YY');
to_date
────────────
2015-04-30
(1 row)
workaround for 8.4:
CREATE OR REPLACE FUNCTION to_date_DD_MM_YY_2_4(text)
RETURNS date AS $$
SELECT CASE WHEN $1 ~ e'\\d+-\\d+-\\d{2}$' THEN to_date($1, 'DD-MM-YY')
ELSE to_date($1, 'DD-MM-YYYY')
END$$
LANGUAGE sql;
CREATE FUNCTION
Time: 25.229 ms
postgres=# SELECT to_date_DD_MM_YY_2_4('30-04-2015');
to_date_dd_mm_yy_2_4
----------------------
2015-04-30
(1 row)
In PostgreSQL: I convert string to timestamp with to_timestamp():
select * from ms_secondaryhealthcarearea
where to_timestamp((COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS')
> to_timestamp('20121128191843','YYYYMMDDHH24MISS')
But I get this error:
ERROR: syntax error at end of input
LINE 1: ...H24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
^
********** Error **********
ERROR: syntax error at end of input
SQL state: 42601
Character: 176
Why? How to convert a string to timestamp?
One too many opening brackets. Try this:
select *
from ms_secondaryhealthcarearea
where to_timestamp(COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
You had two opening brackets at to_timestamp:
where to_timestamp((COA.. -- <-- the second one is not needed!
#ppeterka has pointed out the syntax error.
The more pressing question is: Why store timestamp data as string to begin with? If your circumstances allow, consider converting the column to its proper type:
ALTER TABLE ms_secondaryhealthcarearea
ALTER COLUMN update_datetime TYPE timestamp
USING to_timestamp(update_datetime,'YYYYMMDDHH24MISS');
Or use timestamptz - depending on your requirements.
Another way to convert a string to a timestamp type of PostgreSql is the above,
SELECT to_timestamp('23-11-1986 06:30:00', 'DD-MM-YYYY hh24:mi:ss')::timestamp without time zone;
I had the same requirement as how I read the title. How to convert an epoch timestamp as text to a real timestamp. In my case I extracted one from a json object. So I ended up with a timestamp as text with milliseconds
'1528446110978' (GMT: Friday, June 8, 2018 8:21:50.978 AM)
This is what I tried. Just the latter (ts_ok_with_ms) is exactly right.
SELECT
data->>'expiration' AS expiration,
pg_typeof(data->>'expiration'),
-- to_timestamp(data->>'expiration'), < ERROR: function to_timestamp(text) does not exist
to_timestamp(
(data->>'expiration')::int8
) AS ts_wrong,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) AS ts_ok,
to_timestamp(
LEFT(
data->>'expiration',
10
)::int8
) + (
CASE
WHEN LENGTH(data->>'expiration') = 13
THEN RIGHT(data->>'expiration', 3) ELSE '0'
END||' ms')::interval AS ts_ok_with_ms
FROM (
SELECT '{"expiration": 1528446110978}'::json AS data
) dummy
This is the (transposed) record that is returned:
expiration 1528446110978
pg_typeof text
ts_wrong 50404-07-12 12:09:37.999872+00
ts_ok 2018-06-08 08:21:50+00
ts_ok_with_ms 2018-06-08 08:21:50.978+00
I'm sure I overlooked a simpler version of how to get from a timestamp string in a json object to a real timestamp with ms (ts_ok_with_ms), but I hope this helps nonetheless.
Update: Here's a function for your convenience.
CREATE OR REPLACE FUNCTION data.timestamp_from_text(ts text)
RETURNS timestamptz
LANGUAGE SQL AS
$$
SELECT to_timestamp(LEFT(ts, 10)::int8) +
(
CASE
WHEN LENGTH(ts) = 13
THEN RIGHT(ts, 3) ELSE '0'
END||' ms'
)::interval
$$;