SQL Server 2000 Function for record created datetime - sql

I was given a task to display when a record in the database was added, however the previous developers never made a field for this, and I can't go back and make up dates for all the existing records. Is there an easy way to extract out a record Creation date from a SQL server 2000 query.
SELECT RECORD_CREATED_DATE FROM tblSomething WHERE idField = 1
The RECORD_CREATED_DATE isn't a field in the existing table. Is there some sort of SQL Function to get this information ?

If it's not stored as a field, the info is lost after the transaction log recycles (typically daily), and maybe even sooner.

No, unfortunately date of insert or last update are not automatically stored with each record.
To do that, you need to create two datetime columns in your table (e.g. CreatedOn, UpdatedOn) and then in an INSERT trigger set the CreatedOn = getdate() and in the UPDATE trigger set the UpdatedOn = getdate().
CREATE TRIGGER tgr_tblMain_Insert
ON dbo.tblMain
AFTER INSERT
AS
BEGIN
set nocount on
update dbo.tblMain
set CreatedOn = getdate(),
CreatedBy = session_user
where tblMain.ID = INSERTED.ID
END
I also like to create CreatedBy and UpdatedBy varchar(20) columns which I set to session_user or update through other methods.

I would start with putting this information in from now on. Create two columns, InsertedDate, LastUpdatedDate. Use a default value of getdate() on the first and an update trigger to populate the second (might want to consider UpdatedBy as well). Then I would write a query to display the information using the CASE Statement to display the date if there is one and to display "Unknown" is the field is null. This gets more complicated if you need to store a record of all the updates. Then you need to use audit tables.

I'm not aware of a way you can get this information for existing records. However, going forward you can create an audit table that stores the TableName and RecordCreateDate (or something similar.
Then, for the relevant tables you can make an insert trigger:
CREATE TRIGGER trigger_RecordInsertDate
ON YourTableName
AFTER INSERT
AS
BEGIN
-- T-SQL code for inserting a record and timestamp
-- to the audit table goes here
END

create another column and give it a default of getdate() that will take care of inserted date, for updated date you will need to write an update trigger

Related

Delete new record if same data exists

I want to delete new record if the same record created before.
My columns are date, time and MsgLog. If date and time are same, I want to delete new one.
I need help .
You can check in the table whether that value exists or not in the column using a query. If it exists, you can show message that a record already exists.
To prevent such kind of erroneous additions you can add restriction to your table to ensure unique #Date #Time pairs; if you don't want to change data structure (e.g. you want to add records with such restrictions once or twice) you can exploit insert select counstruction.
-- MS SQL version, check your DBMS
insert into MyTable(
Date,
Time,
MsgLog)
select #Date,
#Time,
#MsgLog
where not exists(
select 1
from MyTable
where (#Date = Date) and
(#Time = Time)
)
P.S. want to delete new one equals to do not insert new one
You should create a unique constraint in the DB level to avoid invalid data no matter who writes to your DB.
It's always important to have your schema well defined. That way you're safe that no matter how many apps are using your DB or even in case someone just writes some inserts manually.
I don't know which DB are you using but in MySQL can use to following DDL
alter table MY_TABLE add unique index(date, time);
And in Oracle you can :
alter table MY_TABLE ADD CONSTRAINT constaint_name UNIQUE (date, time);
That said, you can also (not instead of) do some checks before inserting new values to avoid dealing with exceptions or to improve performance by avoiding making unnecessary access to your DB (length \ nulls for example could easily be dealt with in the application level).
You can avoid deleting by checking for duplicate while inserting.
Just modify your insert procedure like this, so no duplicates will entered.
declare #intCount as int;
select #intCount =count(MsgLog) where (date=#date) and (time =#time )
if #intCount=0
begin
'insert procedure
end
> Edited
since what you wanted is you need to delete the duplicate entries after your bulk insert. Think about this logic,
create a temporary table
Insert LogId,date,time from your table to the temp table order by date,time
now declare four variables, #preTime,#PreDate,#CurrTime,#CurrDate
Loop for each items in temp table, like this
while
begin
#pkLogID= ' Get LogID for the current row
select #currTime=time,#currDate=date from tblTemp where pkLogId=#pkLogID 'Assign Current values
'Delete condition check
if (#currDate=#preDate) and (#currTime=#preTime)
begin
delete from MAINTABLE where pkLogId=#pkLogID
end
select #preDate=#currDate,#preTime=#currTime 'Assign current values as preValues for next entries
end
The above strategy is we sorted all entries according to date and time, so duplicates will come closer, and we started to compare each entry with its previous, when match found we deleting the duplicate entry.

Can you tell me when data was inserted into a table

I am using MS SQL Server 2008 and I have an sql table with some data that is inserted daily at 6 am by an sql job. The problem I have is that some data has been inserted separately into the job and I need to know when this data was added.
Is there a query I can run that will show me this?
I think the short answer is NO, there's no magic, ad hoc SQL query that will let you go back after the fact and find out when a row was inserted.
If you want to know when a row is inserted, the easiest thing would be to simply add a date or timestamp field with a default value (like getDate()) that automatically fills in the date/time when the row is inserted.
There are, of course, SQL logs available that will let you track when rows are inserted, updated, deleted, etc., but those require set up and maintenance.
Third option would be to have the program that's inserting the data perform some logging.
Add a date field to the table. You can give it a default value of GETDATE()
Then ORDER BY that field.
SELECT Column1, Column2, NewDateColumn
FROM YourTable
ORDER BY NewDateColumn
what i would do is :
/* add new column to keep inserted row date */
ALTER TABLE [schemaName].[tableName] ADD [RecTime] DATETIME;
/* update the existing rows with the current date since there is no way to guess their insertion date */
UPDATE [schemaName].[tableName] SET [RecTime] = GETDATE();
/* and set a constraint to the RecTime column to set current date on every new row added */
ALTER TABLE [schemaName].[tableName] ADD CONSTRAINT [DF_tableName_RecTime] DEFAULT (GETDATE()) FOR [RecTime]
then you can get those rows like :
SELECT *
FROM [schemaName].[tableName]
WHERE NOT(DATEPART(hh, RecTime) = 6 AND DATEPART(mi, RecTime) <= 20)
you can 'play' with '20' if you know how long sql job run
you probably need to look at SQL CREATE TRIGGER to add the logic to know when the data is being added and log that info in another table for further actions. Without further details I am not sure we can say more than that.
As you're referring to data which has already been inserted, the answer is No, unless you already have a datetime column which has a default value of GETDATE(). The best you can manage after the event has occurred is to look at the sequence of rows and determine that it was between two known times.

sql when set default value getdate(), does it set value when run update statement?

I know when you insert a value into db, it set that column value as current datetime,
does it apply to it when you run a update statement?
e.g.
table schema:
Id, Name, CreatedDate(getdate())
when i insert into table id = 1 , name = 'john' it will set createdDate = current date
if i run an update statement
update table set name="john2" where id =1
Will it update the createdDate?
No, a DEFAULT CONSTRAINT is only invoked on INSERT, and only when (a) combined with a NOT NULL constraint or (b) using DEFAULT VALUES. For an UPDATE, SQL Server is not going to look at your DEFAULT CONSTRAINT at all. Currently you need a trigger ( see How do I add a "last updated" column in a SQL Server 2008 R2 table? ), but there have been multiple requests for this functionality to be built in.
I've blogged about a way to trick SQL Server into doing this using temporal tables:
Maintaining LastModified Without Triggers
But this is full of caveats and limitations and was really only making light of multiple other similar posts:
A System-Maintained LastModifiedDate Column
Tracking Row Changes With Temporal
Columns
How to add “created” and “updated” timestamps without triggers
Need a datetime column that automatically updates
wow - hard to understand...
i think NO based on the clues.
if you insert a record with a NULL in a column, and that column has a default value defined, then the default value will be stored instead of null.
update will only update the columns specified in the statement.
UNLESS you have a trigger that does the special logic - in which case, you need to look at the trigger code to know the answer.
if your update statement tell to update a column with getfate() it will, but if you just update a name for example and you have a createdate column (which was inserted with getdate()), this columns wont be affected.
You can achieve this using DEFAULT constraint like i did it with OrderDate field in below statement.
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
OrderDate date DEFAULT GETDATE()
)

Most efficient way to sustain a maximum number of entries in SQL Server database table

I was wondering, what is the most efficient way of doing the following?
I'm trying to implement some sort of an auditing system where each logon to my page will be stored in a database. I use SQL Server 2005 database. The table that stores the auditing data obviously cannot grow without an upper limit. So, say, it should have a maximum of 1000 entries and then any older entries must be deleted when new ones are inserted. The question is how do you do this in a most efficient way -- do I need to add any special columns, like, say an ordinal entry number for easier clean-up?
EDIT:
Say, if the structure of my table is (pseudo code):
`id` BIGINT autoincrement
`date` DATETIME
`data1` NVARCHAR(256)
`data2` INT
How would you write this cleanup procedure?
As Tony mentioned, use dates to identify the inserts. In addition, use a clustered index on the date field, so that inserts are always at the end of the table and it is easy and efficient to scan through and delete the old rows.
If you use a number, something like this should work:
DELETE FROM myTable WHERE someField < (SELECT MAX(someField) - 1000 FROM myTable)
For a date, deleting everything older than one day would be something like:
DELETE FROM myTable WHERE someField < DateAdd('d', -1, getdate())
Do it by date not number. Have a look at your stats, see how many days 1000 is / will be. Delete anything older than that. Auditing is never particularly efficient, but if you have loads of data that doesn't help you that's very inefficient....
If I understand your needs, this should work. I've tested it on SQL 2008R2, but I can not see any reason why it would not work on SQL Server 2005.
Use a logon trigger to insert a row into your audit table.
Create an AFTER INSERT trigger on your audit table that deletes the row with MIN(ID).
Here's some code to play with:
/* Create audit table */
CREATE TABLE ServerLogonHistory
(SystemUser VARCHAR(512),
ID BIGINT,
DBUser VARCHAR(512),
SPID INT,
LogonTime DATETIME)
GO
/* Create Logon Trigger */
CREATE TRIGGER Tr_ServerLogon
ON ALL SERVER FOR LOGON
AS
BEGIN
INSERT INTO TestDB.dbo.ServerLogonHistory
SELECT SYSTEM_USER, MAX(ID)+1 , USER,##SPID,GETDATE()
FROM TestDB.dbo.ServerLogonHistory;
END
GO
/* Create the cleanup trigger */
CREATE TRIGGER AfterLogin
ON TestDB.dbo.ServerLogonHistory
AFTER INSERT
AS
DELETE
FROM TestDB.dbo.ServerLogonHistory
WHERE ID =
(SELECT MIN(ID) FROM TestDB.dbo.ServerLogonHistory);
GO;
A word of warning. If you create an invalid logon trigger, you'll not be able to logon to the database. But don't panic! It's all part of learning. You'll be able to use 'sqlcmd' to drop the bad trigger.
I did try to delete the row with the min ID in the logon trigger, but I was not able to get that to work.
Is the "ID" column a Identity column with step 1?
after you insert one row
delete column where id<IDENTITY_CURRENT(YOUR_TABLE)-1000

getting last modified time in sql

I have a datetime column in sql2005. it's default value is getdate().
How can I update it's value automatically when others value update?
Use a trigger on the table!
CREATE TRIGGER updateDate
ON dbo.Table
AFTER UPDATE
AS
UPDATE Table
SET ModifiedDate = GetDate() -- or sysdatetimeoffset()
where table.Id = inserted.Id
You can use timestamp variable, basicly it updates itself everytime the row is changed and you can have only one timestamp variable per specific table.
Take a look at:
http://msdn.microsoft.com/en-us/library/aa260631(SQL.80).aspx
You can make a trigger for this, but depending on how often you update it could be cumbersome.
Are most of your updates batch updates or individual records? Is it ad-hoc or done through a stored proc? If it is a stored proc and/or batch updates, it may be more performant to declare a variable for the current datetime, and use that to update this value.
Simply create a trigger.
After update, set this value to getdate(). I currently can't find some articles about the syntax, but I'm sure you can do better ;)
This is base of SilverSkin answer. I just update his statement to include the necessary JOIN.
CREATE TRIGGER updateDate
ON dbo.Table
AFTER UPDATE
AS
UPDATE Table
SET ModifiedDate = GetDate() -- or sysdatetimeoffset()
JOIN Table t JOIN Inserted i ON t.Id = i.Id
This is a syntax for SQL Server 2005.