I have a table with the following format:
CREATE TABLE perflog(
REQ_TIME TIMESTAMP,
RESP_TIME TIMESTAMP,
OPERATION VARCHAR2(50),
STATUS_CODE VARCHAR2(10),
STATUS_BODY VARCHAR2(30)
);
-I want to insert a timestamp in the following format: e.g. 2020-07-27T23:33:41.427330
-I'm getting the following error:
SQL> insert into perflog(REQ_TIME) VALUES(2020-07-27T23:33:41.427330);
SP2-0552: Bind variable "33" not declared.
I don't get how to declare the timestamp in order to insert dates like the above. Sorry if it is a noob question but I'm a begginer.
Simply wrapping your value in single quotes isn't enough:
insert into perflog(REQ_TIME) VALUES('2020-07-27T23:33:41.427330');
ORA-01843: not a valid month
The actual error you get will depend on your session's NLS settings (and it's possible it would work - for you, if you set your session up in a certain way - but then not necessarily for anyone else.)
Oracle has timestamp literals which you can use instead of to_timestamp(), but unfortunately they don't allow the "T":
insert into perflog(REQ_TIME) VALUES(TIMESTAMP '2020-07-27T23:33:41.427330');
ORA-01861: literal does not match format string
and you can't remove it within the call (e.g. with replace) as that then isn't a literal; so you would have to change the "T" to a space externally:
insert into perflog(REQ_TIME) VALUES(TIMESTAMP '2020-07-27 23:33:41.427330');
If you're stuck with a string with that format then use an explicitly to_timestamp() call to convert your string to the data type you want, supplying the matching format mask, including a character-literal `"T"':
insert into perflog(REQ_TIME)
VALUES(TO_TIMESTAMP('2020-07-27T23:33:41.427330', 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
db<>fiddle
It's worth noting that timestamps (and dates) do not have a specific human-readable format when stored in the database. Oracle uses one of several internal representations, depending on the flavour of datetime you're using. Your client, IDE or application will format that as a readable string when you query the data, usually using your session NLS settings again. To get the data back as a string in a specific format you should use to_char() with the appropriate format supplied.
db<>fiddle with some examples.
Use a timestamp literal using a space character instead of a T:
insert into perflog(REQ_TIME) VALUES( TIMESTAMP '2020-07-27 23:33:41.427330');
db<>fiddle
Related
select mudel
from mudel
where 50 > TO_NUMBER(voimsus)
ERROR: ORA-01722: invalid number
Voimsus is a float number ex. 50.21 but datatype is VARCHAR2. Any idea how to convert it. Also I cant change datatype because there is data and there are child records.
Data
Datatypes
SOLUTION: I changed every comma to decimal with
UPDATE mudel
SET voimsus = REPLACE(voimsus, ',', '.')
WHERE voimsus LIKE '%,%'
and it worked
Assuming that your session's nls_numeric_characters setting specifies that a period is your decimal separator and a comma is your grouping separator (i.e. it has a value of ".,")
select *
from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS'
while the data in your table uses a comma as the decimal separator, that would be the problem. You could specify the NLS parameters you want to use in your to_number call
create table my_table( incorrect_data_type varchar2(10) );
insert into my_table( incorrect_data_type ) values( '123,45');
select to_number( incorrect_data_type,
'9999D99',
q'{nls_numeric_characters=',.'}')
from my_table;
Or you could change your session's settings
alter session set nls_numeric_characters = ',.'
select to_number( incorrect_data_type) from my_table;
Of course, if you solve the problem by changing your session's settings, that means that when you (or someone else) starts a new session, they'll need to change their session's settings as well (assuming they use the same NLS settings to establish the connection that you are).
The right answer, of course, is to use the correct data type for the column in the first place. Storing numeric data in a character column is going to cause plenty of grief-- this is just one of the ways that tends to go wrong. Fixing the data type now will save you lots of grief down the line.
Here's a fiddle showing the options working (and failing).
When converting strings to numbers, then don't rely on session settings by merely using
to_number(voimsus)
but specify the format stored in the string. For this you must tell the DBMS what the decimal separator is with NLS_NUMERIC_CHARACTERS. E.g.:
TO_NUMBER(voimsus, '9999999999D.99', 'NLS_NUMERIC_CHARACTERS='',.''')
But well, it is of course much better not to store numbers in string columns in the first place. Use a proper number type such as NUMBER(12,2) instead. (And I recommend not to use any float data type, such as (BINARY_FLOAT), because then your stored numbers are not exact, but approximate, e.g. 1.3 may be stored as something like 1.3000001).
This question already has answers here:
Not a valid month while inserting data in oracle
(2 answers)
Closed 1 year ago.
whenever I'm trying to insert this query I'm getting an error.
CREATE TABLE dateOfBirth(dateOfBirth date);
INSERT INTO dateOfBirth(dateOfBirth)VALUES('1967-11-17');
I'm getting this error:
ORA-01843: not a valid month
Let me try your code:
SQL> CREATE TABLE dateOfBirth(dateOfBirth date);
Table created.
SQL> INSERT INTO dateOfBirth(dateOfBirth)VALUES('1967-11-17');
INSERT INTO dateOfBirth(dateOfBirth)VALUES('1967-11-17')
*
ERROR at line 1:
ORA-01861: literal does not match format string
SQL>
Doesn't work either, but - failed with a different error.
Basically, that's what happens (I mean - you get errors) when you're trying to enter a string into a date datatype column. Although it is clear at the first glance that - if you're inserting '1967-11-17' into dateOfBirth - that someone was born on 17th of November 1967. Oracle, unfortunately, isn't that enthusiastic about it. It will try to implicitly convert string to date, but - as you can see, in both your and my case it miserably failed.
Besides, what if you tried to enter e.g. 12-07-05. What is what in this string? Is 12 year (could be), month (could be) or day (could be as well)? The same goes for 07 and 05. Simply, don't do that, don't rely on implicit conversion from anything to something else.
So, what can you do about it? Obviously, insert a valid DATE datatype value! How? For example:
use date literal which always looks like date 'yyyy-mm-dd':
SQL> insert into dateofbirth (dateofbirth) values (date '1967-11-17');
1 row created.
or, use to_date function with appropriate format mask:
SQL> insert into dateofbirth (dateofbirth) values (to_date('17.11.1967', 'dd.mm.yyyy'));
1 row created.
or, alter session and set date format so that Oracle recognizes it (as you'll see, your "initial" insert will now succeed):
SQL> alter session set nls_date_format = 'yyyy-mm-dd';
Session altered.
SQL> INSERT INTO dateOfBirth(dateOfBirth)VALUES('1967-11-17');
1 row created.
Quite a few options. Therefore, if you take control over it, there'll be no problem at all.
Your insert statement tries to squeeze a string into a date column. Oracle must use implicit conversion in order to allow this to happen, this will use the sessions NLS parameters. In your example, the implicit conversion does not work with the string you have given it.
Implicit conversion is an easy way to end up with corrupt data or errors (as you are seeing now), you should always use explicit conversion so that you can be sure the string is being converted with the correct date format no matter what the session's settings are:
CREATE TABLE dateOfBirth(dateOfBirth date);
INSERT INTO dateOfBirth(dateOfBirth)VALUES(to_date('1967-11-17','yyyy-mm-dd'));
Once the data is stored in the table as a date, it can be displayed with whatever date format you prefer:
select to_char(dateOfBirth,'dd/mm/yyyy') dateOfBirth from dateOfBirth;
Or you can leave it up to the client's session settings to decide how to display it (making it the responsibility of the client to make it correct).
select dateOfBirth from dateOfBirth;
From what I have seen so far, when inserting into a table that has date value such as "27-10-2004", the following format DD-MON-YYYY is used
insert into tableName values('27-Oct-2004')
Is it possible to insert the date in its original format '27-10-2004' into the table? In general how many variations of this date may be considered correct for inserting into tables (this is without using any built-in functions, just SQL)?
Use a date literal in Oracle:
insert into tableName
values (DATE '2004-10-27');
This defines a date constant using the ISO standard format YYYY-MM-DD.
If you wanted to use a specific format -- which I wouldn't recommend -- then you can convert to a date using to_date():
insert into tableName
values (to_date('27-10-2004', 'DD-MM-YYYY'));
Any particular string that you use is interpreted based on system settings, so it can vary by language and geography.
Note: When inserting a value, you should include the column names. I assume that your code is just for illustrative purposes.
can we insert date into varchar2 in oracle without converting by to_char?
Oracle will convert the date into a string using what localization settings are in place during the insert. This is true not only of Oracle but of any database. For a date, that might commonly be in the format "DD-MON-YY".
Here is an example of inserting a date into a varchar2 column.
That said, you should not do this. You should be storing date/time values in the database using the correct data type -- and that would be either date or timestamp. If you want to insert a constant, then use the date or timestamp qualifier with the appropriate value following it.
Question1:
Do i have to use to_date while inserting date?
INSERT INTO some_table (date1, date2)
VALUES (to_date('2012-10-24','YYYY-MM-DD'), to_date('2012-10-24','YYYY-MM-DD'));
Or can just insert as string? Will everything be OK this way too? I've tried and it worked.
INSERT INTO some_table (date1, date2)
VALUES ('2012-10-24',2012-10-24');
Question2:
What happens if i won't name columns that i'm inserting into? It works, but my question is if it inserts randomly now or it takes order of columns during creation of table?
INSERT INTO some_table
VALUES ('2012-10-24',2012-10-24');
1 seems to only work with the 'YYYY-MM-DD' format:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements003.htm#SQLRF51049 says
You can specify a DATE value as a string literal ... to specify a DATE value as a literal, you must use the Gregorian calendar. You can specify an ANSI literal... The ANSI date literal contains no time portion, and must be specified in the format 'YYYY-MM-DD'.
However, it might work with time if you use the
Alternatively you can specify an Oracle date value... The default date format for an Oracle DATE value is specified by the initialization parameter NLS_DATE_FORMAT.
For question 2, it uses the order at definition of the table. However you have to give values for all columns in that case.
Oracle supports Standard SQL date literals (since 9i).
It's DATE followed by a string with 'yyyy-mm-dd' format
DATE '2014-05-10'
It's much shorter than TO_DATE and it's independent of any NLS settings.
Similar for timestamps:
TIMESTAMP '2014-05-10 09:52:35'
Regarding your 2nd question: It's the order of columns as defined within the CREATE TABLE.
You could even do it like this one:
ALTER SESSION SET NLS_DATE_FORMAT = 'MM:YYYY:DD';
INSERT INTO some_table (date1) VALUES ('05:2014:10');
...but doing it like this is not recommended. Use TO_DATE or DATE Literal, e.g. DATE '2014-05-10' instead. It makes your life easier.