delete data information - sql-server-2005

One of my colleague deleted records from a tables 15 days before. I could not know who are deleted those records. I want know their information on which machine, username and modified date in sqlserver2005. How can i get these information? please suggest?
Thanks,
Mailam

You can't unless you have the appropiate columns and/or history tables and/or features like CDC enabled.
By default, there is no in-built automatic mechanism to record data changes

Related

How to identify deleted transactions in the Netsuite Transactions table

I'm working on building reports outside of NetSuite (in order to join this data with data from other source systems) using data pulled into Redshift from the NetSuite back-end tables. I have several tables that have been completely piped into Redshift against which I write my queries. In trying to recreate some values from the monthly P&Ls, I noticed my totals were not tying out with what is shown in the NS UI. After troubleshooting with our finance team, it appears as they there are 3 invoices that they deleted but are still showing up in the Transactions table. I do not as an IsDeleted field or something similar. How can I identify which records in the table have been deleted in order to filter them out of my results?
For Transactions has other posters have said use deleted records but a word to the wise here, deleted record only track the transactions themselves. Therefore, if your end users delete some lines in your transactions, deleted record WONT show said transactions in deleted records.
Some commenter said to look in system notes but in our cases, we only have the new and old version_id for the type impact in the system notes. Moreover, we never found a way to get what it mapped to on the ODBC side. (Correct me if I am wrong I would be more than happy to get a better way that the shitty hack we found)
The only workaround we found in our process here is to load all transactions with last_modified_date > {ts'last Import date'} in a temporary table and check if some lines for those transactions were deleted. In addition, to looking into deleted record to find the deleted transactions themselves. That is the only way we were able to match for our P&L reports long therm.
The logic behind this is that luckily in our processes, the end user must always edit the transaction themselves to delete some lines. Therefore, when they save their changes the transaction itself get a new modified date.
We asked NetSuite support directly and they told us that they do not officially have an official table to track the deletions of lines.
You can create a saved search of deleted records(record type of invoice) in NetSuite. Export it via CSV or Excel then use this CSV/Excel to update Redshift table and tag deleted record.
In the future you can create an API call to Redshift(if available) when a NetSuite record got deleted that will update/tag the deleted record in Redshift. This way you don't need to generate the deleted record.
DELETE is logged in TRANSACTION_HISTORY

Taking snapshot of SQL tables

I have a set of referential tables with different schema which we use as a reference data during integration of files. The reference data can be modified from the GUI.
And the requirement is, I need to create a snapshot of data if there are any changes. For eg., Users should be able to see which referential data has been used for particular date.
Option 1: Historize all the tables over night everyday with date. This way when users want to see the data used for particular date, we can easily query the corresponding history table. As users doesnt change the data everyday, this way we will make the database bigger day by day.
Option 2: Historize only the data(rows) which has been modified with modified date and use the view to fetch the data for particular days. But this way I need to write many views as the schema is different for different tables.
If you know of the best way I can use, I would appreciate it if you share your knowledge.
Thanks,
Not sure if possible but:
Option 3: Create/Edit triggers OnInsert/Update/Delete to write new values to an "historical table" and include a timestamp.
To get the Admin data used on day "X" just use the timestamp.
Another option (again not sure if possible) is to add "start_dt/end_dt" to the admin tables and have the processes lookup only the active data
Sérgio

Best practice for auditing data in SQL Server and retrieving point in time data

I've been doing history tables for some time now in databases, but never put too much effort or thought into it. I wonder what is the best practice out there.
My main goal is to record any changes to a record for a particular day. If more than one change happens in a day then then only one history record will exist. I need to record the date the record was changed, also when I retrieve data I need to pull the correct record from history as it was at a particular time. So for example I have a customers table and want to pull out what their address was for a particular date. My Sprocs like get Cust details will take in an optional date and if no date is passed in then it returns the most recent record.
So here's what I was looking for advice on:
Do I keep the history table in the same table and use a logical delete flag to hide the historical ones? I normally don't do this as some tables can change a lot and have lots of records. Do I use a separate table that mirrors the main table? I usually do this. Should I only put change records into the history table and not the current one? What is the most efficient way given a date to pull out the right record at a point in time, get every record for a customer <= date passed in, and then sort by most recent date and take the top?
Thanks for all the help... regards M
Suggestion is to use trigger based auditing and create triggers for all tables you need to audit.
With triggers you can accomplish the requirement for not storing more than one record update per day.
I’d suggest you check out ApexSQL Audit that generates triggers for you and try to reverse engineer what triggers they use, how storage tables look like and such.
This will give you a good start and you can work form there.
Disclaimer: not affiliated with ApexSQL but I do use their tools on a daily basis.
I'm no expert in the field but a good sql consultant once told me that a good aproach is generally to use the same table if all data can be changed. Otherwise have the original table contain only core nonchangable data and the historical table contain only stuff that can be changed.
You should defintely read this article on managing bitemporal data. The nice thing about this approach is it enables an auditable way of correcting historical data.
I beleive this will address your concerns about modidying the history data
I've always used a modified version of the audit table described in this article. While it does require you to pivot data so that it resembles your table's native structure, it is resilient against changes to the schema.
You can create a UDF that returns a table and accepts a table name (varchar) and point in time (datetime) as parameters. The UDF should rebuild the table using the audit (historical values) and give you the effective values at that date & time.

sql server get only updated record

I am using sql server 2000. I need to get only updated records from remote server and need to insert that record in my local server on daily basis. But that table did not have created date or modified date field.
Use Transactional Replication.
Update
If you cannot do administrative operations on the source then you'll going to have to read all the data every day. Since you cannot detect changes (and keep in mind that even if you'd have a timestamp you still wouldn't be able to detect changes because there is no way to detect deletes with a timestamp) then you have to read every row every time you sync. And if you read every row, then the simplest solution is to just replace all the data you have with the new snapshot.
You need one of the following
a column in the table which flag new or updated records in a fashion or other (lastupdate_timestamp, incremental update counter...)
some trigger on Insert and Update, on the table, which produces some side-effect such as adding the corresponding row id into a separate table
You can also compare row-by-row the data from the remote server against that of the production server to get the list of new or updated rows... Such a differential update can also be produced by comparing some hash value, one per row, computed from the values of all columns for the row.
Barring one the above, and barring some MS-SQL built-in replication setup, the only other possibility I can think of is [not pretty]:
parsing the SQL Log to identify updates and addition to the table. This requires specialized software; I'm not even sure if the Log file format is published/documented, though I have seen this types of tools. Frankly this approach is more one for forensic-type situations...
If you can't change the remote server's database, your best option may be to come up with some sort of hash function on the values of a given row, compare the old and new tables, and pull only the ones where function(oldrow) != function(newrow).
You can also just do a direct comparison of the columns in question, and copy that record over when not all the columns in question are the same between old and new.
This means that you cannot modify values in the new table, or they'll get overwritten daily from the old. If this is an issue, you'll need another table in which to cache the old table's values from the day before; then you'll be able to tell whether old, new, or both were modified in the interim.
I solved this by using tablediff utility which will compare the data in two tables for non-convergence, and is particularly useful for troubleshooting non-convergence in a replication topology.
See the link.
tablediff utility
TO sum up:
You have an older remote db server that you can't modify anything in (such as tables, triggers, etc).
You can't use replication.
The data itself has no indication of date/time it was last modified.
You don't want to pull the entire table down each time.
That leaves us with an impossible situation.
You're only option if the first 3 items above are true is to pull the entire table. Even if they did have a modified date/time column, you wouldn't detect deletes. Which leaves us back at square one.
Go talk to your boss and ask for better requirements. Maybe something that can be done this time.

How can I determine the last time any record changed in a specific Sql Server 2000 database?

I have a SQL Server 2000 database instance that is rarely updated. I also have a database table which has no columns holding each row's created date or modified date.
Is there any way that I can determine the last time an update or insert was performed on the database as a whole, so that I can at least put a bound on when the specific records in the table may have changed?
Note: I am looking for information about transactions that have already occurred. Triggers may help we should I require this again in the future, but does not address the problem I'm trying to describe.
If it can be done, how can I do it?
The database's log file may have some information that is useful to your quest. AFAIK, the database itself doesn't store a "last updated" date.
Depending on the size of the database and the number of tables you could put a trigger in place that would handle updates/or inserts and log that to another table, potentially logging the table name and a timestamp, it isn't elegant but could work. and Doesn't require any modification to the rest of the db.