NULL Date field is populated with SYSDATE by default - sql

I am running a query on clocking data for my company. I have a query with 2 fields: CLOCK_IN1 and CLOCK_OUT1. When I run the query I see the proper CLOCK_IN1 but the CLOCK_OUT1 is being populated with a date near SYSDATE. CLOCK_OUT1 is NULL in the database and it's replacing the NULL with this date.
Is there a setting that populates a date when it's NULL?

There's either
a DEFAULT value applied to that column, or
a database trigger that does it.
This is how the first works:
SQL> create table test
2 (clock_in1 date,
3 clock_out1 date default sysdate
4 );
Table created.
SQL> insert into test (clock_in1) values (date '2020-08-23');
1 row created.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
03.11.2020 20:23:03
SQL> select * from test;
CLOCK_IN1 CLOCK_OUT1
------------------- -------------------
23.08.2020 00:00:00 03.11.2020 20:22:48
SQL>
And this is the second:
SQL> drop table test;
Table dropped.
SQL> create table test
2 (clock_in1 date,
3 clock_out1 date
4 );
Table created.
SQL> create or replace trigger trg_bi_test
2 before insert on test
3 for each row
4 begin
5 :new.clock_out1 := nvl(:new.clock_out1, sysdate);
6 end;
7 /
Trigger created.
SQL> insert into test (clock_in1) values (date '2020-08-23');
1 row created.
SQL> select * from test;
CLOCK_IN1 CLOCK_OUT1
------------------- -------------------
23.08.2020 00:00:00 03.11.2020 20:24:23
SQL>
How to "fix" it?
SQL> alter table test modify clock_out1 default null;
Table altered.
SQL>
As of the trigger, well ... it depends on what it is doing, but - removing a line that sets column value would do.

Related

Need to insert date column along with time and mins

I need to insert the date column record along with hour,min,sec, for example my joining date is 10/10/2021 but i need to insert 10/10/2021 08:05:25 i need output like this to get inserted
My insert query:
INSERT INTO lease_rent_receipts
(billing_start_date, billing_end_date,
charge_category, due_amount,
due_date, client_id,total_payable, description)
VALUES (l_billing_start_date,l_billing_end_date,l_charge_category, l_due_amount,
l_due_date, l_client_id,l_total_payable, l_description);
Main for due_date column i need to insert along with hrs:min:sec
kindly assist
To demonstrate my earlier comments. Notice on the final query of the table, I am querying the same column - the same data - with three different formats:
SQL> create table my_demo
2 (demo_date date)
3 ;
Table created.
SQL> declare
2 l_demo_date date := to_date('2021-10-22 12:21:43','yyyy-mm-dd hh24:mi:ss');
3 begin
4 insert into my_demo (demo_date)
5 values (l_demo_date)
6 ;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> select demo_date,
2 to_char(demo_date,'dd-Mon-yyyy') demo1,
3 to_char(demo_date,'yyyy-mm-dd hh24:mi:ss') demo2
4 from my_demo;
DEMO_DATE DEMO1 DEMO2
--------- -------------------- -------------------
22-OCT-21 22-Oct-2021 2021-10-22 12:21:43
1 row selected.
SQL> --
SQL> drop table my_demo purge;
Table dropped.
Use timestamp
to_timestamp(date_col, 'DD/MM/YYYY 24hh:mm:ss' )
DECLARE
l_billing_start_date lease_rent_receipts.billing_start_date%TYPE;
l_billing_end_date lease_rent_receipts.billing_end_date%TYPE;
l_charge_category lease_rent_receipts.charge_category%TYPE;
l_due_amount lease_rent_receipts.due_amount%TYPE;
l_due_date lease_rent_receipts.due_date%TYPE;
l_client_id lease_rent_receipts.client_id%TYPE;
l_total_payable lease_rent_receipts.total_payable%TYPE;
l_description lease_rent_receipts.description%TYPE;
BEGIN
-- Use a DATE literal and add an INTERVAL DAY TO SECOND literal.
billing_start_date := DATE '2021-10-10' + INTERVAL '08:05:25' HOUR TO SECOND;
-- or use a TIMESTAMP literal.
billing_start_date := TIMESTAMP '2021-10-10 08:05:25';
-- Or use TO_DATE.
billing_start_date := TO_DATE('10/10/2021 08:05:25', 'DD/MM/YYYY HH24:MI:SS');
-- Set other variables.
INSERT INTO lease_rent_receipts(
billing_start_date, billing_end_date, charge_category, due_amount,
due_date, client_id,total_payable, description
) VALUES (
l_billing_start_date, l_billing_end_date, l_charge_category, l_due_amount,
l_due_date, l_client_id,l_total_payable, l_description
);
END;
/

is this possible? adding 4 new columns: createdDate,modifiedDate,createdBy,modifiedBy?

I'm on sql developer. I have a table. I Want to add those 4 new columns which I know how to do, but I want those values to not be entered by the user when he enters a new row or edits an existing row, I want those values to be automatically filled
For example if the user enters
insert into tableName values (val1,val2,val3)
then the table will have the 7 new values in the new row:
val1,val2,val3,createdDate,modifiedDate,createdBy,modifiedBy
same when the user modifies a value in an existing row
update TAbleName set val1 = newVal where id = id1
and then the "modifiedDate" and "modifiedBy" fields in that row will be automatically modified
What database do you use?
For auto fill when you add a new row, you need to setup "default binding" aka "default field"
ALTER TABLE YourTable
ADD CONSTRAINT DF_YourTable DEFAULT GETDATE() FOR YourColumn
For update, you need to make a trigger to edit the column
How to: Create trigger for auto update modified date with SQL Server 2008
Partially, column's default value can do that (for created date and user who did that); for modifications, use a trigger.
Here's an example:
SQL> create table test (id number, name varchar2(20));
Table created.
SQL> alter table test add
2 (created_date date default sysdate,
3 created_by varchar2(30) default user,
4 modified_date date,
5 modified_by varchar2(30)
6 );
Table altered.
SQL> insert into test (id, name) values (1, 'Little');
1 row created.
SQL> select * From test;
ID NAME CREATED_DATE CREATED_BY MODIFIED_DATE MODIFIED_B
---------- -------------------- ------------------- ---------- ------------------- ----------
1 Little 13.02.2020 22:23:17 SCOTT
Updating a row a little bit later - nothing has changed (for created and modified columns):
SQL> update test set name = 'Foot' where id = 1;
1 row updated.
SQL> select * From test;
ID NAME CREATED_DATE CREATED_BY MODIFIED_DATE MODIFIED_B
---------- -------------------- ------------------- ---------- ------------------- ----------
1 Foot 13.02.2020 22:23:17 SCOTT
Let's create a trigger. It's a simple one:
SQL> create or replace trigger trg_testmod_bu
2 before update on test
3 for each row
4 begin
5 :new.modified_date := sysdate;
6 :new.modified_by := user;
7 end;
8 /
Trigger created.
SQL> update test set name = 'Bigfoot' where id = 1;
1 row updated.
SQL> select * From test;
ID NAME CREATED_DATE CREATED_BY MODIFIED_DATE MODIFIED_B
---------- -------------------- ------------------- ---------- ------------------- ----------
1 Bigfoot 13.02.2020 22:23:17 SCOTT 13.02.2020 22:26:38 SCOTT
Right; the trigger updated both modified columns.

Decimal point is removed before update to character variable

I have data in the below format and I want to update a destination table column of type varchar2 with below values. But the problem is it updates as .462 instead of 0.462 by using trim with leading '0'.
source destination column
----------------- ------------------
0000004.304300000 4.3043
0000005.504500000 5.5045
0000141.400000000 141.4
0000138.900000000 138.9
0000000.462000000 0.462
0000000.000297000 0.000297
A little bit of TO_CHARing and TO_NUMBERing with appropriate format mask might do the job. Have a look at the example:
SQL> create table test (source varchar2 (20), destination varchar2(20));
Table created.
SQL> insert into test (source)
2 select '0000004.304300000' from dual union all
3 select '0000000.462000000' from dual union all
4 select '0000141.400000000' from dual union all
5 select '0000033.000000000' from dual;
4 rows created.
SQL> alter session set nls_numeric_characters = '.,';
Session altered.
SQL> update test set
2 destination = rtrim(to_char(to_number(source), 'fm999990D99999999'), '.');
4 rows updated.
SQL> select * From test;
SOURCE DESTINATION
-------------------- --------------------
0000004.304300000 4.3043
0000000.462000000 0.462
0000141.400000000 141.4
0000033.000000000 33
SQL>

check for valid date which is declared in varchar2

My table looks like below which is declared in VARCHAR2:
YMD
20101010
20101112
20100231
20150101
20160101
I have to check for valid dates and filter future dates from sysdate, which are in valid format.
I write the function as below to check for valid dates:
create or replace FUNCTION VALIDATE_DATE (p_string in string) return date is
begin
return to_date(p_string, 'YYYYMMDD');
exception when others then
begin
return to_date(p_string, 'YYYY-MM-DD');
exception when others then
begin
return to_date(p_string, 'RR-MON-DD');
exception when others then
return null;
end;
end;
end;
and written this query to check for valid dates and replace with null for invalid dates
select ymd, VALIDATE_DATE(ymd) as Valid
from temp
and to check future dates I wrote the following query, but it throws error
ORA-01839
select ymd
from temp
where validate_date(ymd)='YES'
and to_date(ymd,'yyyymmdd')>sysdate
How to check future dates in my table if exists?
I will rather fix the design issue as a permanent fix rather than wasting time on the workaround.
Firstly, NEVER store DATE as VARCHAR2. All this overhead is due to the fact that your design is flawed.
'20100231'
How on earth could that be a valid date? Which calendar has a 31 days in FEBRUARY?
Follow these steps:
Add a new column with DATE DATA TYPE.
Update the new column with date values from the old column using TO_DATE.
Do the required DATE arithmetic on the new DATE column, or handle this in the UPDATE statement in step 2 itself.
Drop the old column.
Rename the new column to the old column.
UPDATE Adding a demo
Setup
SQL> CREATE TABLE t
2 (ymd varchar2(8));
Table created.
SQL>
SQL> INSERT ALL
2 INTO t (ymd)
3 VALUES ('20101112')
4 --INTO t (ymd)
5 -- VALUES ('20100231')
6 INTO t (ymd)
7 VALUES ('20150101')
8 INTO t (ymd)
9 VALUES ('20160101')
10 SELECT * FROM dual;
3 rows created.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
Add new column:
SQL> ALTER TABLE t ADD (dt DATE);
Table altered.
SQL>
DO the required update
SQL> UPDATE t
2 SET dt =
3 CASE
4 WHEN to_date(ymd, 'YYYYMMDD') > SYSDATE
5 THEN NULL
6 ELSE to_date(ymd, 'YYYYMMDD')
7 END;
3 rows updated.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
Let's check:
SQL> SELECT * FROM t;
YMD DT
-------- ---------
20101112 12-NOV-10
20150101 01-JAN-15
20160101
SQL>
Drop the old column:
SQL> ALTER TABLE t DROP COLUMN ymd;
Table altered.
SQL>
Rename the new column to old column name
SQL> ALTER TABLE t RENAME COLUMN dt TO ymd;
Table altered.
SQL>
You have just fixed the issue
SQL> SELECT * FROM t;
YMD
---------
12-NOV-10
01-JAN-15
SQL>

Roll back Update or delete data Through Flashback query

I have done some changes and commited but i want to roll back those changes through Flashback query.
Can you please help me how to do this?
I am using Oracle 11g Version.
From below tables i have deleted the data..Now i want to revert back those records..
Customer,
Address,
Employee,
Alignemnt
Many Thanks for your help.
Sunitha.
There are two things,
1.Flashback by SCN
SELECT column_list
FROM table_name
AS OF SCN scn_number;
2.Flashback by TIMESTAMP
SELECT column_list
FROM table_name
AS OF TIMESTAMP TO_TIMESTAMP('the timestamp value');
To get current_scn and systimestamp, query :
SELECT current_scn, SYSTIMESTAMP
FROM v$database;
Update Example as requested by OP.
To flashback the table to the old scn, use FLASHBACK TABLE..TO SCN clause.
SQL> DROP TABLE string_ex PURGE;
Table dropped.
SQL> CREATE TABLE string_ex (sl_ps_code VARCHAR2(20) );
Table created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14ASM0002');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0018');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0019');
1 row created.
SQL> INSERT INTO string_ex (sl_ps_code) VALUES ('AR14SFT0062');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201277 29-OCT-14 03.02.17.419000 PM +05:30
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201280 29-OCT-14 03.02.22.785000 PM +05:30
SQL> SELECT current_scn, SYSTIMESTAMP FROM v$database;
CURRENT_SCN SYSTIMESTAMP
-------------------- --------------------------------------------
13818123201282 29-OCT-14 03.02.26.781000 PM +05:30
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14ASM0002
AR14SFT0018
AR14SFT0019
AR14SFT0062
SQL>
I have four rows in the table.
SQL> ALTER TABLE string_ex ENABLE ROW MOVEMENT;
Table altered.
SQL>
Row movement is required.
SQL> DELETE FROM string_ex WHERE ROWNUM =1;
1 row deleted.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14SFT0018
AR14SFT0019
AR14SFT0062
I deleted a row now and committed the changes.
SQL> FLASHBACK TABLE string_ex TO SCN 13818123201277;
Flashback complete.
Flashback is complete
SQL> SELECT * FROM string_ex;
SL_PS_CODE
---------------
AR14ASM0002
AR14SFT0018
AR14SFT0019
AR14SFT0062
SQL>
I now have my table to old state and the row is back