SQL - literal does not match format string in INSERT INTO - sql

I've created an empty table--in my website that holds a bunch of tables-- that has the following columns/data types:
NAME -- VARCHAR2
MRN -- NUMBER
DATE_S -- DATE
E -- DATE
DELI -- DATE
WB -- VARCHAR2
ST_ID -- VARCHAR2
COMMENTS --VARCHAR2
EI -- NUMBER
Below is one of almost 800 rows of code I am using to populate the table.
INSERT INTO SANDBOX.W_C VALUES ('S,E',11300033,'2012-02-18 00:00:00','2012-03-01 00:00:00','2013-02-18 00:00:00','N','006i',NULL,NULL);
When I run that piece of code I get the following message: literal does not match format string. What am I doing wrong?

You need to_Date
INSERT INTO SANDBOX.W_C VALUES ('S,E',11300033,
TO_DATE('2012-02-18', 'yyyy-mm-dd'),
TO_DATE('2012-03-01', 'yyyy-mm-dd'),
TO_DATE('2013-02-18', 'yyyy-mm-dd'),'N','006i',NULL,NULL);

When you provide a date as a string, the database uses it's default settings to try to convert the string. The best way to handle this is the use of to_date, as in scaisEdge's answer.
However, you can also change the default date mask using alter session before you run the insert statements:
ALTER SESSION SET NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss';

Related

Oracle sysdate format change from dd/mm/yy to ddmmyy

The data length in our production DB, DATE data type, is 7, the sysdate function return 8 characters (dd/mm/yy) .
Is there any way to eliminate '/' and only populate 'ddmmyy'.
Tried the below but no luck.
INSERT INTO TESTER(tablename,columnname,defaultdate,prime_number) VALUES ('tabL7845','field894',REPLACE(SYSDATE,'/',''),105);
INSERT INTO TESTER(tablename,columnname,defaultdate,prime_number) VALUES ('ta68888','fiG987',TO_CHAR(sysdate,'MMDDYY'),180);
INSERT INTO TESTER(tablename,columnname,defaultdate,prime_number) VALUES ('tab345','field464',TRIM(BOTH '/' FROM SYSDATE),65);
Row is getting inserted but in table i could find the same sysdate format,
for eg ) 07/08/20
How can i populate as 070820
Trigger code :
SET SERVEROUTPUT ON;
CREATE OR REPLACE TRIGGER def_trig
BEFORE INSERT OR UPDATE OF datedef ON Test
REFERENCING OLD AS O NEW AS N
FOR EACH ROW
DECLARE
V_DATA_LENGTH NUMBER;
V_DATA_TYPE VARCHAR2(15);
BEGIN
SELECT DATA_LENGTH,DATA_TYPE
INTO V_DATA_LENGTH,V_DATA_TYPE
FROM all_tab_columns
WHERE table_name = :n.tablename
AND column_name =:n.columnname
IF INSERTING THEN
IF v_data_type = 'DATE' THEN
IF length(:n.datedef) > V_DATA_LENGTH THEN
RAISE_APPLICATION_ERROR(-20001,'DATE FIELD LENGTH IS MORE THAN THE CORESPONDING COLUMN DATA LENGTH');
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE('INSERT IS SUCCESSFUL');
END IF;
END if;
END;
/
Dates in Oracle do not have any internal sort of text formatting; they are stored as binary. If you want to view a SYSDATE value in a certain text format, then use TO_CHAR with the appropriate format mask:
INSERT INTO TESTER (tablename, columnname, defaultdate, prime_number)
VALUES ('ta68888', 'fiG987', sysdate, 180); -- just insert plain SYSDATE here
SELECT
tablename,
columnname,
TO_CHAR(defaultdate, 'DDMMYY'), -- then view SYSDATE however you want
prime_number
FROM TESTER;
Here is the output from the above query:
Demo
Internally dates are stored as a structure of 7 1byte integers, that's where the length 7 comes from. From that structure any valid format can be displayed without any data change. To see this select the same column with multiple formats. For example:
alter session st nls_date_format = 'hh24:mi:ss dd-Mon-yyyy';
select defaultdate
from teaster
where defaultdate is not null
and row_num<2;
alter session set nls_date_format = 'Dy dd-Mon-yyyy # hh24:mi:ss' ;
select defaultdate
from teaster
where defaultdate is not null
and row_num<2;
To get a glimpse at the internal format run:
select defaultdate, dump(defaultdate) from teaster;
This will show you the default date (interpreted as directed by nls_date_format) and a glimpse of the internal structure.

Inserting a TIMESTAMP value in SQL Developer

Hello I'm having a trouble inserting this value in Oracle SQL Developer Version 19.4.0.354.
'2013-01-01 00:00:00.0000'
Here is the value that I want to insert in one of my tables.
I tried DATE and TIMESTAMP data types but they don't work. I also tried altering the sessions and other possible solutions all over the internet.
Column datatype should be TIMESTAMP. Use appropriate format mask in TO_TIMESTAMP function.
SQL> create table test (col timestamp);
Table created.
SQL> insert into test (col) values (to_timestamp('2013-01-01 00:00:00.0000', 'yyyy-mm-dd hh24:mi:ss:ff6'));
1 row created.
What's in there? (alter session is here just to display the result in desired format; it doesn't affect the value stored in that column):
SQL> alter session set nls_timestamp_format = 'dd.mm.yyyy hh24:mi:ss.ff6';
Session altered.
SQL> select * From test;
COL
---------------------------------------------------------------------------
01.01.2013 00:00:00.000000
SQL>
The simplest approach is to use a literal timestamp, so you don't rely on implicit conversion:
select timestamp '2013-01-01 00:00:00.0000' from dual;
You can also use to_timestamp():
select to_timestamp('2013-01-01 00:00:00.0000', 'yyyy-mm-dd hh24:mi:ss:ff4') from dual;
On the other hand, if you really want to work with a string, then you would need to change the nls setting to your own format before:
alter session set nls_timestamp_format = 'yyyy-mm-dd hh24:mi:ss:ff4';
You can then use pass your string value directly in the query, and Oracle will implicitly convert it to the target datatype while inserting.
You have no time component, so I would just use:
date '2013-01-01'
This is the safest syntax (and clearest and standard too!) for providing a date value.
If Oracle wants a timestamp, it will convert this correctly.

ORA-01481: invalid number format model in oracle insert query

I have below query where i am getting error as
ORA-01481: invalid number format model
The user is attempting to either convert a number to a string via TO_CHAR or a string
to a number via TO_NUMBER and has supplied an invalid number format model parameter.
I am using this query in stored procedure. The day_id column is number data type and the value stored in this column as YYYYMMDD. The month_id column is also number data type and i want to stored the value in this column as YYYYMM
INSERT INTO TEST_CHECK(MONTH_ID) VALUES
(to_char(REC.day_id, 'YYYYMM'));
You're applying a conversion to a number as if it was a date, trying to use the result (a string) as a number.
SQL> create table TEST_CHECK(MONTH_ID number);
Table created.
SQL> INSERT INTO TEST_CHECK(MONTH_ID) VALUES(to_char(20180101, 'YYYYMM'));
INSERT INTO TEST_CHECK(MONTH_ID) VALUES(to_char(20180101, 'YYYYMM'))
*
ERROR at line 1:
ORA-01481: invalid number format model
You may need something like:
SQL> INSERT INTO TEST_CHECK(MONTH_ID) VALUES(substr(to_char(20180101), 1, 6));
1 row created.
I would remember that storing dates and months in such a way is not a good idea.
Use
INSERT INTO TEST_CHECK(MONTH_ID) VALUES
(substr(REC.day_id, 1, 6));
instead, since both day_id and month_id are numbers.
If day_id were in date format you could make such a conversion to char but this not the case.
You may apply to_char conversion for REC.day_id as to_char(REC.day_id) but if there's no non-numeric character, oracle considers number as char implicitly without to_char, during a string operation such as substr.

Remove non-date values from a varchar column in oracle

In a table called customers I have a varchar2 column(financial_month).
This column is supposed to be a date column but since it is a varchar2 column and due to some wrong coding, there are many data which aren't in date format.
For eg: 0.15 has been stored in one record and many other wrong entries.
Now I want to eliminate all the wrong entries.
What process should I follow?
I have no clue whatsoever. I am not able to identify the wrong entries as well. The only thing I know is that there are more than 1000 wrong entries.
How to remove all the wrong entries from this column?
Assuming that the format of the "financial months" must be MM/YYYY:
CREATE TABLE fm_t (fm VARCHAR2(30));
INSERT INTO fm_t VALUES ('01/2015');
INSERT INTO fm_t VALUES ('0.5');
INSERT INTO fm_t VALUES ('whatsever');
INSERT INTO fm_t VALUES ('02/2015');
SELECT * FROM fm_t;
CREATE OR REPLACE FUNCTION fm_f(fm IN VARCHAR2) RETURN INTEGER IS
d DATE;
BEGIN
d := TO_DATE(fm, 'FMMM/YYYY');
RETURN 1;
EXCEPTION WHEN OTHERS THEN
RETURN 0;
END;
/
DELETE fm_t WHERE fm_f(fm) <> 1;
SELECT * FROM fm_t;
DROP FUNCTION fm_f;
DROP TABLE fm_t;
You may use something like
WHERE REGEXP_LIKE(financial_month, '^[0-9]{2}[.][0-9]{2}[.][0-9]{4}$')
to find rows with date values
(this is for date format DD.MM.YYYY or MM.DD.YYYY)
or more precise regexp
'^[0-3][0-9][.][0-1][0-9][.](19|20)[0-9]{2}$'
for DD.MM.YYYY format.

Wrong date format for input parameter?

CREATE OR REPLACE PROCEDURE PROC1(
V_STARTTIME IN DATE,
V_ENDTIME IN DATE)
BEGIN
INSERT INTO TAB1
SELECT COINS FROM TAB2
WHERE DATE BETWEEN TO_DATE(V_STARTTIME,'MM/DD/YYYY') AND TO_DATE(V_ENDTIME,'MM/DD/YYYY');
COMMIT;
END;
SAMPLE DATE in Tab2 IS TIMESTAMP DATATYPE 5/5/2014 9:46:38.000000 AM
When I try to execute
Execute PROC1(TO_DATE('5/5/2014','MM/DD/YYYY'),TO_DATE('5/6/2014','MM/DD/YYYY'));
the procedure is successfully completed but my Insert into was ignored.
I tried printing the input date through dbms_output.put_line and the date did not return.
This is very, very similar to the question you asked yesterday.
If v_starttime and v_endtime are of type date, it makes no sense to call to_date on them. to_date does not take an argument of type date. It takes a parameter of type varchar2. If you try to pass a date to to_date, Oracle has to implicitly cast the date to a varchar2 using the session's NLS_DATE_FORMAT. If that doesn't match the format mask you're passing to to_date, you may get an error or you may get an incorrect result. As in yesterday's question, you want to avoid implicit conversions.
A date in Oracle has both a day and a time component (to the second). If you are doing the to_date in order to ensure that the time component is midnight, use the trunc function instead.
INSERT INTO TAB1( column_name )
SELECT COINS
FROM TAB2
WHERE <<timestamp column>> BETWEEN trunc( v_starttime ) AND trunc( v_endtime );
You say that your "insert was ignored". That seems highly unlikely. It's much more likely that your SELECT statement returned 0 rows so your INSERT inserted 0 rows. That's not an error. If you want to treat it as an error, you'd need to check SQL%ROWCOUNT after the INSERT and throw an error if the INSERT statement inserts 0 rows.
If the SELECT was not selecting any rows because of an implicit conversion error, then getting rid of the to_date and potentially adding the trunc would fix the problem.
The function TO_DATE requires string as first parameter.
CREATE OR REPLACE PROCEDURE PROC1(
V_STARTTIME IN DATE,
V_ENDTIME IN DATE)
BEGIN
INSERT INTO TAB1
SELECT COINS FROM TAB2 WHERE DATE BETWEEN V_STARTTIME AND V_ENDTIME;
COMMIT; --You should not use commit in procedure.
END;