Skip to Main Content
  • Questions
  • Problem with NLS_DATE_FORMAT with instead of trigger

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Ahmad.

Asked: June 07, 2019 - 8:44 am UTC

Last updated: June 07, 2019 - 10:00 am UTC

Version: 11.2.0.4

Viewed 1000+ times

You Asked

Hi,

I have a Problem with formatting a date Format … i would like to Display the date like that 'DD.MM.YYYY HH24:MI:SS'.

i use an update Statement to update a view, an instead of trigger is created over the view, the trigger updates the master table.

i altered the session NLS_DATE_FORMAT in the trigger as displayed below, unfortunately the DATE is still not displayed as i wish…


Build scenario:

CREATE TABLE MYTAB (ID NUMBER(12), START_SEND DATE, ENDE_SEND DATE)
CREATE VIEW MYVIEW AS SELECT * FROM MYTAB;   
    
create or replace TRIGGER MYTRIGGER
INSTEAD OF UPDATE ON MYVIEW
REFERENCING OLD AS OLD NEW AS NEW
DECLARE
v_nls_old     VARCHAR2(40);
sql_stmt      VARCHAR2(80);

BEGIN 

 SELECT
        value
    INTO
        v_nls_old
    FROM
        nls_session_parameters
    WHERE
        parameter = 'NLS_DATE_FORMAT';

EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''DD.MM.YYYY HH24:MI:SS''';

UPDATE MYTAB
SET ID = :NEW.ID
,START_SEND    = TO_DATE(:NEW.START_SEND,'DD.MM.YYYY HH24:MI:SS')
,ENDE_SEND     = TO_DATE(:NEW.ENDE_SEND,'DD.MM.YYYY HH24:MI:SS')  
WHERE id  = :OLD.id;

sql_stmt := 'ALTER SESSION SET NLS_DATE_FORMAT = ''' || v_nls_old || '''';

EXECUTE IMMEDIATE sql_stmt;

EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001
,'TRIGGER - ' ||
SQLERRM);
END MYTRIGGER;
/

insert into mytab(id) values (1);
commit;

update myview  
set id=2, START_SEND=to_date('06.06.2019 10:00:00','DD.MM.YYYY HH24:MI:SS'),ENDE_SEND=to_date('06.06.2019 12:00:00','DD.MM.YYYY HH24:MI:SS') where id=1;

commit;

select * from myview;
        ID START_SEND ENDE_SEND
---------- --------  --------
         2 06.06.19 06.06.19


Could you please tell me where is the Problem?

Thank you

and Chris said...

The problem is using a trigger ;)

Seriously, there's no need. You can update the view and the database will resolve this to the base table:

CREATE TABLE MYTAB (ID NUMBER(12), START_SEND DATE, ENDE_SEND DATE);
CREATE VIEW MYVIEW AS SELECT * FROM MYTAB;

insert into mytab(id) values (1);
commit;

update myview 
set    id = 2, 
       START_SEND=to_date('06.06.2019 10:00:00','DD.MM.YYYY HH24:MI:SS'),
       ENDE_SEND=to_date('06.06.2019 12:00:00','DD.MM.YYYY HH24:MI:SS') 
where  id = 1;

commit;

select * from myview;

ID    START_SEND              ENDE_SEND              
    2 06-JUN-2019 10:00:00    06-JUN-2019 12:00:00    


Unless your real view is way more complex, just update the view.

But even if you need the trigger, setting the NLS format is a waste. The columns are already dates, so there's no need to to_date them again in the trigger.

Secondly, after the update the trigger reverts the format back to whatever it was before it fired. Which is why you don't have the format used inside the trigger.

Remember: clients can (and do!) set the NLS_DATE_FORMAT to whatever they want.

If you want to be certain of displaying a date in a given format, you should to_char it:

alter session set nls_date_format = 'YYYY-MM-DD';
select * from myview;

ID    START_SEND    ENDE_SEND    
    2 2019-06-06    2019-06-06    

select id, to_char ( start_send, 'DD.MM.YYYY' ),
       to_char ( ende_send, 'DD.MM.YYYY' ) 
from   myview;

ID    TO_CHAR(START_SEND,'DD.MM.YYYY')    TO_CHAR(ENDE_SEND,'DD.MM.YYYY')   
    2 06.06.2019                          06.06.2019 

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Ahmad, June 07, 2019 - 9:29 am UTC

Hi Chris,

Thank you for the prompt Reply, actually the view is way complex than this… i cant update the view directly..

I tried altering the NLS_DATE_FORMAT inside the trigger within a dynamic SQL.. i expected that the trigger updates the master table and the date columns are populated with the dateformat i required...the client issues an update like below:

update myview
set id=2, START_SEND=to_date('06.06.2019 10:00:00','DD.MM.YYYY HH24:MI:SS'),ENDE_SEND=to_date('06.06.2019 12:00:00','DD.MM.YYYY HH24:MI:SS') where id=1;
commit;

my requirement is that These two date columns get saved as same as i requested (DD.MM.YYYY HH24:MI:SS)


so again and in short, how can i save the datapermanently in the same dateFormat i requested ?


Thx

Chris Saxon
June 07, 2019 - 10:00 am UTC

Date data types are stored in an INTERNAL FORMAT!

How it's DISPLAYED is entirely controlled by the client.

You can't "force" the database to store a date in a given format. It doesn't matter what format mask you use in to_date(). The database will store it in its own way.

The columns are already dates in the view (right?) So in the trigger just set them WITHOUT to_date().

If you want to ensure that the dates always appear in a specific format, you MUST use to_char with your desired mask when you query them.

More to Explore

SQL

The Oracle documentation contains a complete SQL reference.