Find the last time table was updated - sql-server-2008-r2

I want to retrieve the last time table was updated(insert,delete,update).
I tried this query.
SELECT last_user_update
FROM sys.dm_db_index_usage_stats
WHERE object_id=object_id('T')
but the data there is not persisted across service restarts.
I want to preserve the stats even if the service restarts. How can I achieve it?

If you're talking about last time the table was updated in terms of its structured has changed (new column added, column changed etc.) - use this query:
SELECT name, [modify_date] FROM sys.tables
If you're talking about DML operations (insert, update, delete), then you either need to persist what that DMV gives you on a regular basis, or you need to create triggers on all tables to record that "last modified" date - or check out features like Change Data Capture in SQL Server 2008 and newer.

If you want to see data updates you could use this technique with required permissions:
SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'DATABASE')
AND OBJECT_ID=OBJECT_ID('TABLE')

Find last time of update on a table
SELECT
tbl.name
,ius.last_user_update
,ius.user_updates
,ius.last_user_seek
,ius.last_user_scan
,ius.last_user_lookup
,ius.user_seeks
,ius.user_scans
,ius.user_lookups
FROM
sys.dm_db_index_usage_stats ius INNER JOIN
sys.tables tbl ON (tbl.OBJECT_ID = ius.OBJECT_ID)
WHERE ius.database_id = DB_ID()
http://www.sqlserver-dba.com/2012/10/sql-server-find-last-time-of-update-on-a-table.html

To persist audit data regarding data modifications, you will need to implement a DML Trigger on each table that you are interested in. You will need to create an Audit table, and add code to your triggers to write to this table.
For more details on how to implement DML triggers, refer to this MDSN article http://msdn.microsoft.com/en-us/library/ms191524%28v=sql.105%29.aspx

SELECT so.name,so.modify_date
FROM sys.objects as so
INNER JOIN INFORMATION_SCHEMA.TABLES as ist
ON ist.TABLE_NAME=so.name where ist.TABLE_TYPE='BASE TABLE' AND
TABLE_CATALOG='DbName' order by so.modify_date desc;
this is help to get table modify with table name

SELECT UPDATE_TIME
FROM information_schema.tables WHERE TABLE_SCHEMA = 'your_dbname' AND TABLE_NAME = 'your_tablename'

Why not just run this: No need for special permissions
SELECT
name,
object_id,
create_date,
modify_date
FROM
sys.tables
WHERE
name like '%yourTablePattern%'
ORDER BY
modify_date

Related

Select on delete actions for foreign keys [duplicate]

Almost all the information I had needed about a database, I could find in information_schema
This time I needed to read details of all foreign keys in a database through single query I found every thing in information_schema.key_Column_usage but could not find the constraints like on delete, on update
I could do show create table for all individual tables. But is there any way to get these details through some select query like this?
SELECT CONSTRAINT_NAME, TABLE_NAME,COLUMN_NAME, REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME FROM information_schema.`KEY_COLUMN_USAGE` WHERE
table_schema = 'mydbname' AND referenced_column_name IS NOT NULL
It is doing the job well but just missing constraints like on delete, on update How can I get those values as well so that I can get all info about foreign keys in a single query?
UPDATE_RULE and DELETE_RULE is the thing you asked for
it's a little bit too late but it could help someone else, here the solution :
SELECT tb1.CONSTRAINT_NAME, tb1.TABLE_NAME, tb1.COLUMN_NAME,
tb1.REFERENCED_TABLE_NAME, tb1.REFERENCED_COLUMN_NAME, tb2.MATCH_OPTION,
tb2.UPDATE_RULE, tb2.DELETE_RULE
FROM information_schema.`KEY_COLUMN_USAGE` AS tb1
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS AS tb2 ON
tb1.CONSTRAINT_NAME = tb2.CONSTRAINT_NAME
WHERE table_schema = 'sfa' AND referenced_column_name IS NOT NULL
Update From information_schema.REFERENTIAL_CONSTRAINTS table add in mysql 5.1 mysql-5.1 we can get information about all constraints**. Accepted answer gives the solution as query.
Earlier
Before mysql 5.1 like mysql-5.0, we could not get this information, we could only use show create table for individual table.
If you are looking for (primary|foreign|unique) keys :
http://dev.mysql.com/doc/refman/5.5/en/table-constraints-table.html
Now, you can find foreign key constraint details in table INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
http://dev.mysql.com/doc/refman/5.5/en/referential-constraints-table.html

Postgres - UNION ALL vs INSERT INTO which is better?

I have two query by union all and insert into temp table.
Query 1
select *
from (
select a.id as id, a.name as name from a
union all
select b.id as id, b.name as name from b
)
Query 2
drop table if exists temporary;
create temp table temporary as
select id as id, name as name
from a;
insert into temporary
select id as id, name as name
from b;
select * from temp;
Please tell me which one is better for performance?
I would expect the second option to have better performance, at least at the the database level. Both versions require doing a full table scan of both the a and b tables. But the first version would create an unnecessary intermediate table, used only for the purpose of the insert.
The only potential issue with doing two separate inserts is latency, i.e. the time it might take some process to get to and from the database. If you are worried about this, then you can limit to one insert statement:
INSERT INTO temporary (id, name)
SELECT id, name FROM a
UNION ALL
SELECT id, name FROM b;
This would just require one trip to the database.
I think use union all is the better performance way, not sure, you can try it your self. In tab run of SQL application alway show time to run. I take a snapshot in oracle; mysql and sql sv have the same tool to see it
click here to see image

Amazon Redshift how to get the last date a table inserted data

I am trying to get the last date an insert was performed in a table (on Amazon Redshift), is there any way to do this using the metadata? The tables do not store any timestamp column, and even if they had it, we need to find out for 3k tables so it would be impractical so a metadata approach is our strategy. Any tips?
All insert execution steps for queries are logged in STL_INSERT. This query should give you the information you're looking for:
SELECT sti.schema, sti.table, sq.endtime, sq.querytxt
FROM
(SELECT MAX(query) as query, tbl, MAX(i.endtime) as last_insert
FROM stl_insert i
GROUP BY tbl
ORDER BY tbl) inserts
JOIN stl_query sq ON sq.query = inserts.query
JOIN svv_table_info sti ON sti.table_id = inserts.tbl
ORDER BY inserts.last_insert DESC;
Note: The STL tables only retain approximately two to five days of log history.

Postgres subquery has access to column in a higher level table. Is this a bug? or a feature I don't understand?

I don't understand why the following doesn't fail. How does the subquery have access to a column from a different table at the higher level?
drop table if exists temp_a;
create temp table temp_a as
(
select 1 as col_a
);
drop table if exists temp_b;
create temp table temp_b as
(
select 2 as col_b
);
select col_a from temp_a where col_a in (select col_a from temp_b);
/*why doesn't this fail?*/
The following fail, as I would expect them to.
select col_a from temp_b;
/*ERROR: column "col_a" does not exist*/
select * from temp_a cross join (select col_a from temp_b) as sq;
/*ERROR: column "col_a" does not exist
*HINT: There is a column named "col_a" in table "temp_a", but it cannot be referenced from this part of the query.*/
I know about the LATERAL keyword (link, link) but I'm not using LATERAL here. Also, this query succeeds even in pre-9.3 versions of Postgres (when the LATERAL keyword was introduced.)
Here's a sqlfiddle: http://sqlfiddle.com/#!10/09f62/5/0
Thank you for any insights.
Although this feature might be confusing, without it, several types of queries would be more difficult, slower, or impossible to write in sql. This feature is called a "correlated subquery" and the correlation can serve a similar function as a join.
For example: Consider this statement
select first_name, last_name from users u
where exists (select * from orders o where o.user_id=u.user_id)
Now this query will get the names of all the users who have ever placed an order. Now, I know, you can get that info using a join to the orders table, but you'd also have to use a "distinct", which would internally require a sort and would likely perform a tad worse than this query. You could also produce a similar query with a group by.
Here's a better example that's pretty practical, and not just for performance reasons. Suppose you want to delete all users who have no orders and no tickets.
delete from users u where
not exists (select * from orders o where o.user_d = u.user_id)
and not exists (select * from tickets t where t.user_id=u.ticket_id)
One very important thing to note is that you should fully qualify or alias your table names when doing this or you might wind up with a typo that completely messes up the query and silently "just works" while returning bad data.
The following is an example of what NOT to do.
select * from users
where exists (select * from product where last_updated_by=user_id)
This looks just fine until you look at the tables and realize that the table "product" has no "last_updated_by" field and the user table does, which returns the wrong data. Add the alias and the query will fail because no "last_updated_by" column exists in product.
I hope this has given you some examples that show you how to use this feature. I use them all the time in update and delete statements (as well as in selects-- but I find an absolute need for them in updates and deletes often)

interrogating table lock schemes in T-SQL

Is there some means of querying the system tables to establish which tables are using what locking schemes? I took a look at the columns in sysobjects but nothing jumped out.
aargh, just being an idiot:
SELECT name, lockscheme(name)
FROM sysobjects
WHERE type="U"
ORDER BY name
take a look at the syslockinfo and syslocks system tables
you can also run the sp_lock proc