How to get created time of record in Oracle? - database

I have a problem with data in Oracle database:
I want to get created time of some record in table. I can get ora_rowscn of the record, but I cannot run to change this ora_rowscn to timestamp by query SELECT SCN_TO_TIMESTAMP(ora_rowscn) because SCN_TO_TIMESTAMP() may not be available for older data (my data was inserted about 1 month ago).
Anyone have solution to resolve this problem for me to get created time?

Perhaps the best thing to do here, assuming you have a long term need for this requirement, would be to alter your current table and add a bona-fide timestamp column. You could give this timestamp column a default value of the current timestamp, e.g.
CREATE TABLE yourTable (
...
created_time TIMESTAMP(6) default CURRENT_TIMESTAMP
);
Then, when inserting a new record, omit mention of the created_time column, letting Oracle back fill it with the current timestamp.

Related

SSIS data flow - copy new data or update existing

I queried some data from table A(Source) based on certain condition and insert into temp table(Destination) before upsert into Crm.
If data already exist in Crm I dont want to query the data from table A and insert into temp table(I want this table to be empty) unless there is an update in that data or new data was created. So basically I want to query only new data or if there any modified data from table A which already existed in Crm. At the moment my data flow is like this.
clear temp table - delete sql statement
Query from source table A and insert into temp table.
From temp table insert into CRM using script component.
In source table A I have audit columns: createdOn and modifiedOn.
I found one way to do this. SSIS DataFlow - copy only changed and new records but no really clear on how to do so.
What is the best and simple way to achieve this.
The link you posted is basically saying to stage everything and use a MERGE to update your table (essentially an UPDATE/INSERT).
The only way I can really think of to make your process quicker (to a significant degree) by partially selecting from table A would be to add a "last updated" timestamp to table A and enforcing that it will always be up to date.
One way to do this is with a trigger; see here for an example.
You could then select based on that timestamp, perhaps keeping a record of the last timestamp used each time you run the SSIS package, and then adding a margin of safety to that.
Edit: I just saw that you already have a modifiedOn column, so you could use that as described above.
Examples:
There are a few different ways you could do it:
ONE
Include the modifiedOn column on in your final destination table.
You can then build a dynamic query for your data flow source in a SSIS string variable, something like:
"SELECT * FROM [table A] WHERE modifiedOn >= DATEADD(DAY, -1, '" + #[User::MaxModifiedOnDate] + "')"
#[User::MaxModifiedOnDate] (string variable) would come from an Execute SQL Task, where you would write the result of the following query to it:
SELECT FORMAT(CAST(MAX(modifiedOn) AS date), 'yyyy-MM-dd') MaxModifiedOnDate FROM DestinationTable
The DATEADD part, as well as the CAST to a certain degree, represent your margin of safety.
TWO
If this isn't an option, you could keep a data load history table that would tell you when you need to load from, e.g.:
CREATE TABLE DataLoadHistory
(
DataLoadID int PRIMARY KEY IDENTITY
, DataLoadStart datetime NOT NULL
, DataLoadEnd datetime
, Success bit NOT NULL
)
You would begin each data load with this (Execute SQL Task):
CREATE PROCEDURE BeginDataLoad
#DataLoadID int OUTPUT
AS
INSERT INTO DataLoadHistory
(
DataLoadStart
, Success
)
VALUES
(
GETDATE()
, 0
)
SELECT #DataLoadID = SCOPE_IDENTITY()
You would store the returned DataLoadID in a SSIS integer variable, and use it when the data load is complete as follows:
CREATE PROCEDURE DataLoadComplete
#DataLoadID int
AS
UPDATE DataLoadHistory
SET
DataLoadEnd = GETDATE()
, Success = 1
WHERE DataLoadID = #DataLoadID
When it comes to building your query for table A, you would do it the same way as before (with the dynamically generated SQL query), except MaxModifiedOnDate would come from the following query:
SELECT FORMAT(CAST(MAX(DataLoadStart) AS date), 'yyyy-MM-dd') MaxModifiedOnDate FROM DataLoadHistory WHERE Success = 1
So the DataLoadHistory table, rather than your destination table.
Note that this would fail on the first run, as there'd be no successful entries on the history table, so you'd need you insert a dummy record, or find some other way around it.
THREE
I've seen it done a lot where, say your data load is running every day, you would just stage the last 7 days, or something like that, some margin of safety that you're pretty sure will never be passed (because the process is being monitored for failures).
It's not my preferred option, but it is simple, and can work if you're confident in how well the process is being monitored.

How to get the the most recent queries in Oracle DB

I have a web application and I doubt some others have deleted some records manually. Upon enquiry nobody is admitting the mistakes. How to find out at what time those records were deleted ?? Is it possible to get the history of delete queries ?
If you have access to v$ view then you can use the following query to get it. It contains the time as FIRST_LOAD_TIME column.
select *
from v$sql v
where upper(sql_text) like '%DELETE%';
If flashback query is enabled for your database (try it with select * from table as of timestamp sysdate - 1) then it may be possible to determine the exact time the records were deleted. Use the as of timestamp clause and adjust the timestamp as necessary to narrow down to a window where the records still existed and did not exist anymore.
For example
select *
from table
as of timestamp to_date('21102016 09:00:00', 'DDMMYYYY HH24:MI:SS')
where id = XXX; -- indicates record still exists
select *
from table
as of timestamp to_date('21102016 09:00:10', 'DDMMYYYY HH24:MI:SS')
where id = XXX; -- indicates record does not exist
-- conclusion: record was deleted in this 10 second window

TSQL Ranking using timestamp and datetime

I'm trying to rank a series of transactions, however my source data does not capture the time of a transaction which can happen multiple times a day, the only other field I can use is a timestamp field - will this be ranked correctly?
Here's the code
SELECT [LT].[StockCode]
, [LT].[Warehouse]
, [LT].[Lot]
, [LT].[Bin]
, [LT].[TrnDate]
, [LT].[TrnQuantity]
, [LT].[TimeStamp]
, LotRanking = Rank() Over (Partition By [LT].[Warehouse],[LT].[StockCode],[LT].[Lot] Order By [LT].[TrnDate] Desc, [LT].[TimeStamp] Desc)
From [LotTransactions] [LT]
Results being returned are as below
StockCode |Warehouse |Lot |Bin |TrnDate |TrnQuantity |TimeStamp |LotRanking
2090 |CB |3036 |CB |2016-02-16 00:00:00.000 |2.000000 |0x0000000000500AB9 |1
2090 |CB |3036 |CB |2016-02-16 00:00:00.000 |2.000000 |0x0000000000500A4E |2
First, you should be using rowversion rather than timestamp for keeping track of row versioning information. I believe timestamp is deprecated. At the very least, the documentation explicitly suggests [rowversion][1].
Second, I would strongly recommend that you add an identity column to the table. This will provide the information that you really need -- as well as a nice unique key for the table.
In general, a timestamp or rowversion is used just to determine whether or not a row has changed -- not to determine the ordering. But, based on this description, what you are doing might be correct:
Each database has a counter that is incremented for each insert or
update operation that is performed on a table that contains a
timestamp column within the database. This counter is the database
timestamp. This tracks a relative time within a database, not an
actual time that can be associated with a clock. A table can have only
one timestamp column. Every time that a row with a timestamp column is
modified or inserted, the incremented database timestamp value is
inserted in the timestamp column.
I would caution that this might not be safe. Instead, it gives a reason why such an approach might make sense. Let me repeat the recommendation: add an identity column, so you are correctly adding this information, at least for the future.
You can use something like this to get datetime of transaction:
SELECT LEFT(CONVERT(nvarchar(50),[LT].[TrnDate],121),10) + RIGHT(CONVERT(nvarchar(50),CAST([LT].[TimeStamp] as datetime),121),13)
For first string it will be:
2016-02-16 04:51:25.417
And use this for ranking.

Date and Time in SQL Developer

I have 2 tables, 1 table has a date column, 1 table has a time column. I want to have date and time works seperatedly. This is what i use :
ALTER SESSION SET nls_date_format='dd/mm/yyyy';
I use this for the 1st table and then use this for the 2nd table :
ALTER SESSION SET nls_date_format='hh24:mi';
But it doesn't work right. When i do the select * from it all changes back to hh24:mi type. How can i have date and time seperatedly ?
As noted Oracle always has a date and time. If you want to see and use just the date or just the time you could use, for example to only work with the time, TO_CHAR(ColumnA, 'HH24:MI:SS')

How to retrieve the updated column values in sql server

I have "Order" table with more than 5,000 records. When I ran the update query unfortunately I forgot to give the ‘where’ condition.
Now the Date column in all the records has been updated. Is it possible to retrieve my existing column values.
Example:
Update Order
set ordered = getdate()
where Cusid=50
(here I forget to mention the where condition).
I am afraid NO, cause the update has already been committed. Unless you have a backup of the table it's no more can be undone.

Resources