Is there a way to change the &_DATE variable in SQL Developer?
Whenever I run the following code, it just shows todays date:
DEFINE RUN_DATE = &_DATE
I'd like to find a way to format the query so it finds the last day in the month.
Also, if possible, to change the format to show as YYMMDD?
SQL> select '&_DATE' from dual;
old 1: select '&_DATE' from dual
new 1: select '23-JUN-20' from dual
'23-JUN-2
---------
23-JUN-20
SQL> alter session set NLS_DATE_FORMAT='YYYYMMDD';
Session altered.
SQL> select '&_DATE' from dual;
old 1: select '&_DATE' from dual
new 1: select '20200623' from dual
'2020062
--------
20200623
SQL>
_DATE is defined to store result of the SYSDATE function in the database. It's output is based on the NLS_DATE_FORMAT setting for your session.
Or in SQL Developer -
But, you want the last day of the month...we'll, we have the LAST_DAY() function for you!
select LAST_DAY('&_DATE')
from DUAL;
Returns '20200630' because we submitted _DATE which returns June 23 2020, so the function returns the last day of June 2020.
Related
I have a postgres timescale database running in docker. For the purposes of api testing I want SELECT NOW() to return lets say 2010-12-01 23:00:44.851242 +00:00. Basically every time I start up the container I want it to think the current date is some time in December 2010.
How can I achieve this? I cant seem to find any command to set current time in postgres. Do I need to change the system time in the docker container before the database shows up? Is that even something I can do?
You can achieve this by creating a custom now() function in a separate schema and then adjusting the search_path to prefer that function over the builtin now function:
CREATE SCHEMA test;
CREATE OR REPLACE FUNCTION test.now() RETURNS timestamptz LANGUAGE SQL AS $$ SELECT '2000-01-01 0:00'::timestamptz; $$;
SET search_path TO test,pg_catalog,public;
-- make search_path change permanent for a specific user
ALTER USER <testuser> SET search_path TO test,pg_catalog,public;
SELECT now();
now
------------------------
2000-01-01 00:00:00+01
(1 row)
Time: 1.826 ms
I am new to Firebird. I come from a SQL Server background.
To get current date I use following query in SQL Server
SELECT GETDATE()
I am looking for something similar in Firebird
select 'Now' from rdb$database
-- returns 'Now'
select cast('Now' as date) from rdb$database
-- returns e.g. 2008-08-13
select cast('now' as time) from rdb$database
-- returns e.g. 14:20:19.6170
select cast('NOW' as timestamp) from rdb$database
-- returns e.g. 2008-08-13 14:20:19.6170
Shorthand syntax for the last three statements:
select date 'Now' from rdb$database
select time 'now' from rdb$database
select timestamp 'NOW' from rdb$database
In addition to the string-based solution in the answer of stackoverflow, Firebird supports the SQL standard functions CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP (and with Firebird 2.5.9 and Firebird 3.0.5 in anticipation of introduction of time zones in Firebird 4: LOCALTIME and LOCALTIMESTAMP). The Firebird documentation sometimes refers to them as 'context variables'.
There is a difference between 'now' and the CURRENT_xxx functions: the CURRENT_xxx when used in PSQL code will be stable (same value) for the duration of execution of the outermost routine, while 'now' will be evaluated individually.
In a nutshell I need to select the resulting value from a column value of max date with the year portion replaced with year-1.
However, the "date" column is NUMERIC(8,0) with values stored as yyyymmdd. There is a separate "year" column - NUMERIC(4,0) - that stores just the yyyy value. (FYI - I didn't create this table but I have to work with it as-is)
Without using variables and logic I can manually create a select statement that produces the desired results knowing that the current year is 2018, eg:
SELECT REPLACE( MAX(MYDATE), 2018, 2017 ) FROM MYTABLE
I need to dynamically provide the values for the 2018 (max year) and 2017 (max year - 1) parameters.
This is what I have so far:
BEGIN
DECLARE VOUT CHAR;
DECLARE VYEAR CHAR;
SELECT MAX(MYYEAR) INTO VYEAR FROM MYTABLE;
SELECT REPLACE( MAX(MYDATE), #VYEAR, #VYEAR-1 ) INTO VOUT FROM MYTABLE;
END
I am getting the following error:
[IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0206 - Column or global variable #VYEAR not found.
If I remove the #VYEAR and #VYEAR-1 variables and hard code the 2018, 2017 values the statement block runs without error.
Also, I have no idea how to retrieve the VOUT variable value. How do I go about getting that value from the client that is executing this ?
The only thing I have found is something like this:
SET SERVEROUTPUT ON;
BEGIN
dbms_output.put_line( 'Hello' );
END;
But I get this error:
[IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0199 - Keyword ON not expected.
I have ERP application that uses the system date when posting transactions. The database is PostgreSQL. I'm able to use https://www.nirsoft.net/utils/run_as_date.html for backdate the application but I notice that the transactions are still posting as of "today" and I think that maybe because of PostgreSQL using the system date.
Is there any way I can set the date back for PostgreSQL? Or any other way to do this? The process in the ERP application does not have an option to back date.
The easiest would be to add a trigger to the database that would change the date for inserted rows:
create table testpast(
id serial primary key,
time timestamp with time zone not null default now()
);
insert into testpast (time) values (default);
select * from testpast;
id | time
----+-------------------------------
1 | 2018-03-16 00:09:20.219419+01
(1 row)
create function time_20_years_back() returns trigger as $$
begin
NEW.time = now()-'20 years'::interval;
return NEW;
end;
$$ language plpgsql;
create trigger testpast_time_20_years_back
before insert on testpast
for each row
execute procedure time_20_years_back();
insert into testpast (time) values (default);
select * from testpast;
id | time
----+-------------------------------
1 | 2018-03-16 00:09:20.219419+01
2 | 1998-03-16 00:09:55.741345+01
(2 rows)
Though I have no idea what would be the purpose of such a hack.
I am trying to write a query to insert a value into a timestamp with no timezone data type field. The value is coming from CSV file.
The version I am working with is PostgreSQL 8.1.21.
The CSV file upload is done by the client and it has a date column. The date sometimes comes as '28-Sep-13' and sometimes as '28/09/2013' formats.
I tried to use the following to cast the string into timestamp:
str_date::timestamp.
This works fine if str_date is something like '28-Sep-13' but it won't work if the incoming date has the format '28/09/2013', when this error occurs:
ERROR: date/time field value out of range: "28/09/2013"
HINT: Perhaps you need a different "datestyle" setting
Basically the client keeps changing the date format in the uploaded CSV file.
Is there a way to convert the date strings into timestamp depending on its actual format?
You need to set your datestyle to "ISO, DMY". It is set to "ISO, MDY" by default, and would cause your example to fail:
> show datestyle;
DateStyle
-----------
ISO, MDY
(1 row)
> select '28-Sep-13'::date;
date
------------
2013-09-28
(1 row)
> select '28/09/2013'::date;
ERROR: date/time field value out of range: "28/09/2013"
LINE 1: select '28/09/2013'::date;
^
HINT: Perhaps you need a different "datestyle" setting.
> set datestyle = 'ISO, DMY';
SET
> select '28-Sep-13'::date;
date
------------
2013-09-28
(1 row)
> select '28/09/2013'::date;
date
------------
2013-09-28
(1 row)
(examples done in PostgreSQL 9.1, but the DateStyle setting and associated behavior are ancient, so should work fine)
You can circumvent the problem with these steps:
Create an empty temporary table with the same structure as target table:
CREATE TEMP TABLE tmp AS SELECT * FROM real_tbl LIMIT 0;
Change the type of the problematic column to text:
ALTER TABLE tmp ALTER COLUMN str_date TYPE text;
Import data to the temp table. Should work fine now:
COPY tmp FROM '/path/to/my/file.txt';
INSERT into target table depending on depending on the actual content of the column:
INSERT INTO real_tbl (col1, col2, col3, date_col)
SELECT col1, col2, col3
, CASE WHEN str_date ~~ '%/%'
THEN to_date(str_date, 'DD/MM/YYYY')
WHEN str_date ~~ '%-%'
THEN to_date(str_date, 'DD-Mon-YYYY')
-- more cases?
ELSE ???
END AS date_col
FROM tmp;
-- DROP TABLE tmp; -- optional; dropped at end of session automatically
I agree with Erwin, but I would try create database function (PL/pgSQL, PL/Python or other language) that can convert various date strings into date. In Erwins answer you can see WHEN ... THEN and you can use it. Such function will be easier to test and maintain.