Tips for tracking down mystery update SQL? - sql

I just started a new job and was given a bug to track down and fix. The basic issues it that a field in a DB record is being cleared out and no one knows why. So far I have tried:
Checking the table for triggers,
there are none.
Monitoring the table using SQL
Server profiler for the last couple
of days in the hopes that the error
would happen again but unfortunately
it hasn't.
Reviewing all the code that does
inserts/updates and I didn't see
anything that would cause this
problem.
Does anyone have any other suggests for finding what could have updated this record? Am I not checking something that I should be? Are there any other sources of information that I should look at?

Create a trigger that will write to a history table. Include columns for the date of the write as well as the user.

::fn_dblog() will show you at the very least when the update occurred (as sequence, not as time) and what other operations were done by that transaction. From the information on what other operations this transaction did, along with what other transactions were doing at that moment, you should be able to narrow down at least the context under which the update occurred, from which point code inspection is a viable option to continue.
Reading the log requires ... the log so your database should be in full recovery mode.

select
schema_name = s.name,
object_name = o.name
from sys.sql_modules m join sys.objects o on m.object_id = o.object_id
join sys.schemas s on o.schema_id = s.schema_id
where definition like '%FieldName%'
This query looks through all the objects in the database (stored procedures, functions, views) and looks for any place where 'FieldName' is being refered. I would go through all the objects returned by this query to see if anything unusual is being done with the Field. This might be extremely tedious as it might return more results than you care about, but its a sure shot way of catching all the references to the field

If you are on SQL Server 2008 you can use extended events to get the full stack trace for the offending statement. Example code here Create Trigger to log SQL that affected table?

Related

What DML operations a table is performing inside Stored Procedure or SQL Functions

I am using SQL Server 2014. I have some user defined tables like Customer, PurchaseOrder, User, and so on. I am using those tables inside many stored procedures. In some cases, those stored procedures are almost 1000/1500 lines long.
Now I want to find out what operation(s) (insert/update/delete) those tables are doing inside every stored procedures.
I am doing it manually. But it is hell lot of effort. Besides, in manual effort, I might miss anything.
Can we write a SQL query by which without opening a stored procedure I can know what operation (insert/update/delete) a certain table is performing inside it.
Thanks in advance.
Based on your requirements you may find the following useful. You can search the complete text of all procedures / functions / triggers / views etc and look for matching key words.
select Schema_Name(o.schema_id)[schema], o.[name], o.type_desc
from sys.sql_modules m
join sys.objects o on o.object_id=m.object_id
where
m.definition like '%insert%customers%' or
m.definition like '%update%customers%' or
m.definition like '%delete%customers%'
order by type_desc, name
This can help you narrow down and identify potential objects. This in itself is not precise since it may find a procedure where you update orders and then use customers in a from or join subsequently.
If you have conventions you can rely on such as a delete will always be delete from customers and not delete customers or delete from c from... then you can of course improve the matching to increase the relevance of what you find.
A tool such as Redgate's SQLPrompt is invaluable here as you can script out all your procedure names prefixed with exec , paste it into SSMS and immediately preview the entire procedure code of each in a pop-up window.

Any non-SELECT queries don't run in Oracle

So, I can successfully run any SELECT statement, but doing any UPDATE statements just hang until they eventually time out. This occurs with trying to execute any stored procedures as well. Other users that connect to the database can run anything without running into this problem.
Is there a cache per user that I can dump or something along those lines? I usually get sick of waiting and cancel the operation, so I don't know if that has contributed to the problem or not.
Just for reference, it's things as simple as these:
UPDATE SOME_TABLE
SET SOME_COLUMN = 'TEST';
EXECUTE SOME_PROCEDURE(1234);
But this works:
SELECT * FROM SOME_TABLE; -- various WHERE clauses don't cause any problems.
UPDATE:
Probably a little disappointing for anyone who came here looking for an answer to a similar problem, but the issue ended up being twofold: The DBA didn't think it was important to give me many details, but there were limitations on the Oracle server that were intentionally set for procedures in general (temp space issues, and things of that ilk). And second, there was an update to the procedure that I wasn't aware of that'd run a sub-query for every record that's pulled in the query (thousands of records). That was removed and now it's running as expected.
In my experience this happens most often because there is another uncommitted operation on the table. For example: User 1 successfully issues an update but does not commit it or roll it back. User 2 (or even another session of User 1) issues another update which just hangs until the other pending update is committed or rolled back. You say that "other users" don't have the same problem, which makes me wonder if they are committing their changes. And if so, if they are updating the same table or a different one.

Pre-execute a query when any Stored Procedure is called

Our enterprise's database is 20+ years old, and it's filled with junk, so we're planning to start deleting tables and Stored Procedures. The problem is that we don't exactly know which of those are unused, so we thought on doing a research to spot them.
I tried this answer's solution, but I think the number of queries returned are the ones in the system cache.
I have an idea of how to do it, but I don't know if it's possible:
- Create a system table with 3 columns: Stored Procedure name, number of executions, and date of last call
- The tricky part: everytime a Stored Procedure is executed, perform a query to insert/update that table.
To avoid having to modify ALL our Stored Procedures (those are easily 600+), I thought of adding a Database Trigger, but turns out it's only possible to link them to tables, not Stored Procedures.
My question is, is there any way to pre-execute a query when ANY Stored Procedure is called?
EDIT: Our Database is a SQL Server
I'm aware that I asked this question a while ago, but I'll post what I've found, so anyone who stumbles with it can use it.
When the question was asked, my goal was to retrieve the number of times all Stored Procedures were executed, to try to get rid of the unused ones.
While this is not perfect, as it doesn't show the date of last execution, I found this query, which retrieves all Stored Procedures on all databases, and displays the number of times it's been executed since it's creation:
SELECT
Db_name(st.dbid) [Base de Datos],
Object_schema_name(st.objectid, dbid) [Schema],
Object_name(st.objectid, dbid) [USP],
Max(cp.usecounts) [Total Ejecuciones]
FROM
sys.dm_exec_cached_plans cp
CROSS apply sys.Dm_exec_sql_text(cp.plan_handle) st
WHERE
Db_name(st.dbid) IS NOT NULL
AND cp.objtype = 'proc'
GROUP BY
cp.plan_handle,
Db_name(st.dbid),
Object_schema_name(objectid, st.dbid),
Object_name(objectid, st.dbid)
ORDER BY
Max(cp.usecounts)
I found this script on this webpage (it's on spanish). It also has 2 more useful scripts about similar topics.
I used this script (subsequently improved)
https://chocosmith.wordpress.com/2012/12/07/tsql-recompile-all-views-and-stored-proceedures-and-check-for-error/#more-571
To run through all of your objects and find the ones that are no longer valid.
If you want I will post my enhanced version which fixes a few things.
Then create a new schema (I call mine recycle) and move those invalid objects in there.
Now run it again.
You may end up moving a whole bunch on non functional objects out

Table is automatically truncated on SQL Server

I have a really strange problem on my SQL Server.
Every night 2 tables, that I have recently created, are being automatically truncated...
I am quite sure, that it is truncate, as my ON DELETE Trigger does not log any delete transactions.
Additionally, using some logging procedures, I found out, that this happens between 01:50 and 01:52 at night. So I checked the scheduled Jobs on the server and did not find anything.
I have this problem only on our production server. That is why it is very critical. On the cloned test server everything works fine.
I have checked transaction log entries (fn_dblog), but didnt find any truncate logs there.
I would appreciate any help or hints that will help me to find out process/job/user who truncates the table.
Thanks
From personal experience of this, as a first step I would look to determine whether this is occurring due to a DROP statement or a TRUNCATE statement.
To provide a possible answer, using SSMS, right click the DB name in Object Explorer, mouse over Reports >> Standard Reports and click Schema Changes History.
This will open up a simple report with the object name and type columns. Find the name of the table(s), click the + sign to expand, and it will provide you history of what has happened at the object level for that table.
If you find the DROP statement in there, then at least you know what you are hunting for, likewise if there is no DROP statement, you are likely looking for a TRUNCATE.
Check with below query,
declare #var as varchar(max)='tblname'
EXEC sp_depends #objname =#var;
it will return number of stored procedure name which are using your table and try search for any truncate query if you have wrote by mistake.
Thanks a lot to everyone who has helped!
I've found out the reason of truncating. It was an external application.
So if you experience the same problem, my hint is to check your applications that could access the data.
I don't know if can help you to resolve the question.
I often encounter the following situations.
Look at this example:
declare #t varchar(5)
set #t='123456'
select #t as output
output:12345

SQL Server 2005: Why would a delete from a temp table hang forever?

DELETE FROM #tItem_ID
WHERE #tItem_ID.Item_ID NOT IN (SELECT DISTINCT Item_ID
FROM Item_Keyword
JOIN Keyword ON Item_Keyword.Keyword_ID = Keyword.Record_ID
WHERE Keyword LIKE #tmpKW)
The Keyword is %macaroni%. Both temp tables are 3300 items long. The inner select executes in under a second. All strings are nvarchar(249). All IDs are int.
Any ideas? I executed it (it's in a stored proc) for over 12 minutes without it finishing.
Anything that has a lock on the table could prevent the query from proceeding. Do you have any other sessions open in SSMS where you have done something to one of the tables?
You can also use the system sproc sp_who2 to see if there are any locks open. look in the column BlkBy and see if anything is hanging on a lock held by another process.
The classic case where SQL Server "hangs" is when you open a transaction but don't commit or rollback. Don't get so wrapped up in your actual delete (unless you are working with a truly huge dataset) that you fail to consider this possibility.
When i run into issues like this i fire up SQL Heartbeat and it can show me what is causing the conflict. This also shows deadlocks related to transactions that were not closed correctly as Mark states above.
Sounds like you might want to read up on deadlocking...
** Ignore my answer - I'm leaving it up so that Dr. Zim's comment is preserved, but it is incorrect **