0

I have a table with columns(year,day-month) -date type- in my database. and a form with a text field for the user to enter a date. how can I split the entered date to save it on db as following

year     day_month
----     ---------
2018     03-04

I tried SUBSTR(TO_CHAR(TO_DATE(block.field)) in a trigger , but it didn't work bcz the column type is date, and I tried to add TO_DATE() as outer but the result was

year           day_month
----------     ----------
03-04-2018     03-04-2018

How can I do it without changing my columns type?

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
Samah_Bari
  • 21
  • 5

4 Answers4

3

I'd suggest you NOT to do that. Always store DATE values into DATE datatype columns. ALWAYS.

Later, if you want to present them differently, apply appropriate functions (such as TO_CHAR) to those values and display them any way you want.

In your example, that would be

TO_CHAR(date_column, 'yyyy') year
or
EXTRACT (year from date_column) year

and

TO_CHAR(date_column, 'dd-mm') day_month

[EDIT]

Once again (to repeat what I've said in a comment): the fact that you named columns in the database "year" (whose datatype is DATE) and "day_month" (whose datatype is also DATE) is completely useless.

Right now is (dd.mm.yyyy hh24:mi) 03.04.2018 10:32.

DATE datatype contains both date and time, so - how do you plan to put "2018" into the "year" column? What will you do with its month/day/hour/minutes/seconds component? It can't just "vanish", has to have some value. Is it the first of January at 00:00:00? Or what?

The same goes to your "day_month" column - it'll contain year, as well as hours/minutes/seconds, whether you want it or not.

Let's start with the "year": if you want to extract it from the Form item, that would be TO_CHAR, such as

to_char(:block.some_item, 'yyyy')

which results in a string, '2018'. You can't store it into a DATE datatype column, so you have to apply TO_DATE to it:

to_date(to_char(:block.some_item, 'yyyy'), 'yyyy')

and it will result in 01.04.2018 00:00:00 >>> see? Day, month, hours ... everything is here.

The alternative is to create those columns as VARCHAR2, but that's even worse.

Seriously, don't do that.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
  • I need to store them as discussed in my question – Samah_Bari Apr 03 '18 at 07:26
  • @Samah_Bari As mentioned by Littlefoot, always use the correct data types. `Date` should not be stored in data types other than `date` or `timestamp` data types. – Jacob Apr 03 '18 at 07:41
  • I know and that what I'm trying to do, but i have to **split** the date in two **date** columns – Samah_Bari Apr 03 '18 at 07:51
  • DATE datatype contains date & time; how do you plan to "split" those values and put year (say, 2018) into one DATE(!!!) datatype column, and day-month (say, 04-03) into another DATE datatype column? If they are split, they go to VARCHAR2. But, as I said - don't do that. Store dates as they are, split them any way you want in *presentation* layer. – Littlefoot Apr 03 '18 at 08:07
  • this is a task that is requested from me, so changing it wont help much :) – Samah_Bari Apr 03 '18 at 08:13
  • 1
    @Samah_Bari what you are asking is not possible without changing data types. – Subir Kumar Sao Apr 03 '18 at 08:31
  • That must be a "business request"; is it? If so, tell your businessmen that they should mind their business, and let you properly do yours . I've added some more text into my message, have a look. If it still doesn't make you change your mind, I'm afraid I'm out of here as this discussion becomes useless. – Littlefoot Apr 03 '18 at 08:39
  • @Littlefoot I know exactly what you mean and I'm stuck in this for more that 24 hrs now and I already asked them to change the columns data type so i guess i will be in this miss till they relies it :( – Samah_Bari Apr 03 '18 at 08:43
1

Try the following and make the necessary changes in Oracle Forms, substitute block and columns names instead of variables.

DECLARE
   p_year   VARCHAR2 (8);
   p_date   VARCHAR2 (8);
BEGIN
   SELECT TO_CHAR (SYSDATE, 'YYYY') INTO p_year FROM DUAL;


   SELECT TO_CHAR (SYSDATE, 'DD-MM') INTO p_date FROM DUAL;

   DBMS_OUTPUT.put_line ('p_year --> ' || p_year || ' p_date --> ' || p_date);
END;
Jacob
  • 14,463
  • 65
  • 207
  • 320
  • @Samah_Bari What is your expected output? I presume `2018` and `03-04` is your expected result. – Jacob Apr 03 '18 at 08:29
  • yes but the date should be entered by the user in a form, and stored in two **date** columns in db as year, day-month – Samah_Bari Apr 03 '18 at 08:30
  • `TRN_DATE` and `TRN_YEAR` are of date datatype? – Jacob Apr 03 '18 at 08:31
  • exactly @user75ponic – Samah_Bari Apr 03 '18 at 08:32
  • @Samah_Bari How is it possible to store `2018` and `03-04` in date datatypes? – Jacob Apr 03 '18 at 08:43
  • @Samah_Bari See the [documentation](https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT413) which provides coherence. – Jacob Apr 03 '18 at 08:50
  • 1
    Why `select from dual`, especially in a client-server application where (unless there is some optimisation in the Forms engine) it requires a network round trip? The PL/SQL language has a handy [assignment operator](https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#GUID-356CB656-68ED-4869-8C67-FE93A78AEC9A). – William Robertson Apr 03 '18 at 08:54
  • @WilliamRobertson I have illustrated the OP another option using PL/SQL block. Variables and modifications can be made in Oracle Forms which I have mentioned in the answer. Thanks – Jacob Apr 03 '18 at 09:45
1

If your column is a DATE type, expect that it will require you to input a date data also.

In your case, you don't need to split a date. For the YEAR column, if the year value only matters to you, then you can use the TRUNC function

:BLK.YEAR_DATE_FIELD := TRUNC(:BLK.DATE_VALUE, 'YYYY');

and for the MONTH column, just save the date value there.

:BLK.MONTH_DATE_FIELD := :BLK.DATE_VALUE;

Also, maybe you just need to set the format mask of those two fields in Oracle forms. You can set the Format Mask of YEAR field to YYYY and MM-DD to the MONTH field.

eifla001
  • 1,137
  • 8
  • 8
0

The DATE data type is stored dates in tables as 7-bytes

byte 1 - century + 100
byte 2 - (year MOD 100 ) + 100
byte 3 - month
byte 4 - day
byte 5 - hour + 1
byte 6 - minute + 1
byte 7 - seconds+ 1

You CANNOT have a DATE data type that just stores year or month + day; it will always store all the components of the date/time.

So you either store the correct values in each column or you will have to make up values for the components you are not storing and will need to make sure that all the made up values are appropriate for the real values. It is just easier to use the real values in both columns.

So just do:

INSERT INTO your_table(
  year,
  day_month
) VALUES (
  :BLK1.T_DATE,
  :BLK1.T_DATE
);

Without splitting the date because a day_month without a year does not make sense (is 29th February a valid date? For the majority of years, no it isn't).

When you want to output it with a format then just format it as a string on output:

SELECT TO_CHAR( year, 'yyyy' ) AS year,
       TO_CHAR( day_month, 'dd-mm' ) AS day_month
FROM   your_table;
MT0
  • 143,790
  • 11
  • 59
  • 117