How to create a column with specific timestamp? - oracle

create table my_table(
id NUMBER(5),
my_date TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
constraint customers_pk primary key (id)
);
I want to make the TIMESTAMP like this: 'YYYY-MM-DD HH24:MI:SS',
and what does the number in brackets of timestamp mean?

timestamps don't have a format.
They are stored in a binary representation. If you want to display the values in a specific format, use to_char() to format it as a string or do that in your application.

as far as I know, you cannot change its format on CREATE TABLE.
on querying if you use proper NLS Format, you wont deal with this again and again

Related

Automatic adjustment of a field in Oracle

Hello I'm trying to create a table under Oracle 18.1 (SQL Dev).
But I have an error "ORA-00906: missing right parenthesis"
CREATE TABLE DIM_TAB (
ID Number PRIMARY KEY,
TEST nvarchar2,
TEST_2 nvarchar,
DATE DATE not null
);
How to create a field without specifying the size of it in nvarchar (or nvarchar2) on Oracle? (I want the field size to adjust automatically)
Thank you
You have three problems. One, you must specify a maximum number of characters for a VARCHAR2 or NVARCHAR2 column. If you have data that will exceed 4000 bytes (not characters), then just use a CLOB. Second, there is no NVARCHAR data type. Third, you cannot create a column named "date," since that's a reserved word. What you want is something like this:
CREATE TABLE DIM_TAB (
id number PRIMARY KEY,
test nvarchar2(30),
test_2 nvarchar2(30),
the_date date not null
);
Personally, I would use a NUMBER(10) for your id, but that's a minor quibble.
You might want to read up on the NCHAR and NVARCHAR data types.

Add constraint to already existing column to store Record Created Timestamp

I have a Existing column called CREATED DATE whose data type is "Date". I am trying to add a constraint to this CREATED DATE Column which will store "Record created time stamp". I have a following query in place but its working out. Any suggestions will be helpful.
ALTER TABLE CONTAINER_SCAN_LOG
MODIFY (CREATED_DATE DEFAULT (sysdate());
what is the error exactly ? what is the default date? anyway try to remove the parenthesis
ALTER TABLE ex_employee
MODIFY START_TIME DEFAULT (sysdate);
use timestamp instead of date
alter table t add (created_datetime timestamp default systimestamp)
or modify existing created_date to be of timestamp datatype and systimestamp default

converting sybase datetime format to oracle timestamp

I am getting bellow datetime format from sybase DB
2015-08-12T11:49:50.196+01:00
and i need to insert this value into oracle database column of type TIMESTAMP(6).
i am not able to specify the correct format to insert the above datetime in to Timestamp column in oracle.
can any one help me in this.
thanks in advance.
Are you sure that you don't want to store time zone information (thus type TIMESTAMP(6) WITH TIME ZONE)?
CREATE TABLE timestamp (value TIMESTAMP(6));
INSERT INTO timestamp VALUES (TO_TIMESTAMP_TZ('2015-08-12T11:49:50.196+01:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF3 TZH:TZM'));

Oracle Partition by 2 columns Interval

Im trying to find on google my situation but no one talk about this situation.
i have a table thats is gonna be partitionized with 2 columns.
for 2 columns partitions can anyone show an example for the interval?
In this case i have only one.
For this example how do i use an interval with 2 columns
INTERVAL( NUMTODSINTERVAL(1,'DAY'))
My table:
create table TABLE_TEST
(
PROCESS_DATE DATE GENERATED ALWAYS AS (TO_DATE(SUBSTR("CHARGE_DATE_TIME",1,10),'yyyymmdd')),
PROCESS_HOUR VARCHAR(10) GENERATED ALWAYS AS (SUBSTR("CHARGE_DATE_TIME",12,2)),
ANUM varchar(100),
SWTICH_DATE_TIME varchar(100),
CHARGE_DATE_TIME varchar(100),
CHARGE varchar(100),
)
TABLESPACE TB_LARGE_TAB
PARTITION BY RANGE (PROCESS_DATE, PROCESS_HOUR)
INTERVAL( NUMTODSINTERVAL(1,'DAY'))
Many Thanks,
Macieira
You can't use an interval if your range has more than one column; you'd get: ORA-14750: Range partitioned table with INTERVAL clause has more than one column. From the documentaion:
You can specify only one partitioning key column, and it must be of NUMBER, DATE, FLOAT, or TIMESTAMP data type.
I'm not sure why you're splitting the date and hour out into separate columns (since a date has a time component anyway), or why you're storing the 'real' date and number values as strings; it would be much simpler to just have columns with the correct data types in the first place. But assuming you are set on storing the data that way and need the separate process_date and process_hour columns as you have them, you can add a third virtual column that combines them:
create table TABLE_TEST
(
PROCESS_DATE DATE GENERATED ALWAYS AS (TO_DATE(SUBSTR(CHARGE_DATE_TIME,1,10),'YYYYMMDD')),
PROCESS_HOUR VARCHAR2(8) GENERATED ALWAYS AS (SUBSTR(CHARGE_DATE_TIME,12,2)),
PROCESS_DATE_HOUR DATE GENERATED ALWAYS AS (TO_DATE(CHARGE_DATE_TIME, 'YYYYMMDDHH24')),
ANUM VARCHAR2(100),
SWTICH_DATE_TIME VARCHAR2(100),
CHARGE_DATE_TIME VARCHAR2(100),
CHARGE VARCHAR2(100)
)
PARTITION BY RANGE (PROCESS_DATE_HOUR)
INTERVAL (NUMTODSINTERVAL(1,'DAY'))
(
PARTITION TEST_PART_0 VALUES LESS THAN (DATE '1970-01-01')
);
Table table_test created.
I've also changed your string data types to varchar2 and added a made-up initial partition. process_hour probably wants to be a number type, depending on how you'll use it. As I don't know why you're choosing your current data types it's hard to tell what would really be more appropriate.
I don't really understand why you'd want the partition range to be hourly and the interval to be one day though, unless you want the partitions to be from, say, midday to midday; in which case the initial partition (test_part_0) would have to specify that time, and your range specification is still wrong for that.
Interval partitioning could be built only on one column.
In your case you have proper partition key column - CHARGE_DATE_TIME. Why do you create virtual columns as VARCHAR2? And why do you need to create partition key on them? Interval partitioning could be built only on NUMBER or DATE columns.

Oracle create table to handle valid_from and valid_to data

I am in the middle of designing a table which include two columns valid_from and valid_to to track historical changes. For example, my table structure is like below:
create table currency_data
(
currency_code varchar(16) not null,
currency_desc varchar(16) not null,
valid_from date not null,
valid_to date,
d_insert_date date,
d_last_update date,
constraint pk_currency_data primary key (currency_code, valid_from)
)
The idea is to leave the valid_to as blank to start with, and if the currency_desc changes in the future, I will need to set a valid_to to the date that the old description is not valid any more, and create a new rows with a new valid_from. But how can I ensure that there will be never a overlap between these 2 rows. For example the query below should only yield one row.
select currency_desc
from currency_data
where currency_code = 'USD'
and trunc(sysdate) between valid_from and nvl(valid_to, sysdate)
Is there a better way to achieve this please other than make sure all developers/end users aware of this rule. Many thanks.
There is a set of implementation approaches known as slowly changing dimensions (SCD) for handling this kind of storage.
What you are currently implementing is SCD II, however, there are more.
Regarding your possible interval overlap issue - there is no simple way to enforce table-level (instead of row-level) consistency with standard constraints, so I guess a robust approach would be to restrict direct DML to this table and wrap it into some standartized pl/sql API which will enforce your riles prior to insert/update and which every developer will use.

Resources