relatively new to this.
I have a stored procedure that should run when a job is triggered. It all worked fine with the files containing test data that I used for import and testing (excel sheets). I got a new file to test with my solution before deploying, but after having executed the job given the new file the stored procedure just keeps loading without having anything done.
I tried to delete the (excel)file and start again, but it says it's open in another program (it isn't). I then noticed that anytime I try to perform a simple select on one of the tables that are used in the stored procedure, it just keeps loading and never finishes. None of the simple commands work.
I've tried this:
SELECT * FROM Cleaned_Rebate
SELECT TOP 1 * FROM Cleaned_Rebate
TRUNCATE TABLE Cleaned_Rebate
DELETE FROM Cleaned_Rebate
SELECT COUNT(*) FROM Cleaned_Rebate
I also tried to create a new stored procedure identical to the original one, but it just never executes the create query. it keeps on loading. It only creates the new one if I remove 90% of the code.
I can't even execute the stored procedure for the sake of saving it (f5) with just an added comment...
I don't know what is wrong, why, or what I should do to fix this. Does anyone have an idea of what could be wrong? any advice is appreciated!
I want to add that these aren't any big tables - some of them should be empty even. the data sets aren't large either (about 100-300 rows?)
Related
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
My first post here, so please be gentle with me :)
I have a stored procedure with which I take some source data, do some manipulation, run some update statements on it and then put the data into our main data table (I guess you could say its an ETL). The problem I have is some of the update statements I've written don't seem to have worked when the procedure has run, however, if I run them manually in a seperate query window they work perfectly.There are technically two parts to the update statement and one part updates and the other fails, which adds further complication to my trouble.
The snippet of code for the update is as follows:
UPDATE Prod_DDb.dbo.DataLoadTeleconnect
SET pCommissionValue = (SELECT Commission
FROM dbo.MappingiPhoneCommission
WHERE Prod_DDb.dbo.DataLoadTeleconnect.pMRC BETWEEN BaseMRC AND HighMRC),
pMRCBand = (SELECT MRCBand
FROM dbo.MappingiPhoneCommission
WHERE Prod_DDb.dbo.DataLoadTeleconnect.pMRC BETWEEN BaseMRC AND HighMRC)
WHERE pMapID = 'iPhone'
The code updates 2 columns in my source table where the MRC of the record falls between the base and high mrc. Commission is the value which is not updating, however MRCBand updates correctly.
The MappingiPhoneCommission table has the following columns:
BaseMRC
HighMRC
Commission
MRCBand
If anyone could shed any light onto why this would fail in the stored procedure but run fine in a new query window I would be most appreciative.
If you require any further information please let me know and i will try to supply what is needed.
Kind Regards
Tony
I see no reason for this code to act differently in a stored procedure, so I would assume the stored procedure makes a change in the data before the update. I would advise adding some checks to your stored procedure to see what the actual data at runtime is. You might start adding the following just before the update:
SELECT * FROM Prod_DDb.dbo.DataLoadTeleconnect WHERE pMapID = 'iPhone'
SELECT Commission FROM dbo.MappingiPhoneCommission, Prod_DDb.dbo.DataLoadTeleconnect
WHERE Prod_DDb.dbo.DataLoadTeleconnect.pMRC BETWEEN dbo.MappingiPhoneCommission.BaseMRC AND dbo.MappingiPhoneCommission.HighMRC
SELECT MRCBand FROM dbo.MappingiPhoneCommission, Prod_DDb.dbo.DataLoadTeleconnect
WHERE Prod_DDb.dbo.DataLoadTeleconnect.pMRC BETWEEN dbo.MappingiPhoneCommission.BaseMRC AND dbo.MappingiPhoneCommission.HighMRC
If the stored proc does not have a try catch block, then put one in. Likely the SP is failing just above this update which is why it doesn;t happen, without a trycatch block, you are probably not rolling back the whole transaction or bubbling up the actual error.
you can use FOR loop calling the columns in select statement and then updating the columns. this will help you out.
I have a stored procedure that is updating a very large table (with over 100 million records). The stored procedure is updating records in this table.
The steps are as follows:
Store record IDs to be updated in a recordset (not all records will be updated - only about 20000)
Loop through the recordset and call the stored procedure for each record ID in the recordset
Each time the stored procedure has finished (for each record in the recordset mentioned in part 1), update a flag in a table to say that the update completed.
I am finding some strange behaviour. It appears that the stored procedure is passing control back to VB6 before it has completed its updates and is continuing processing the next record. The stored procedure is then timing out later on (on another record ID). Therefore there are flags that say updated (step 3), even though the stored procedure has not run (because it timed out). Is this normal behaviour i.e. for the stored procedure to pass control back to VB6 before it has finished the work?
I have Googled this and I have discovered that it could be because of the way the stored procedure is optimised by SQL Server. I would expect control only to be passed back to VB6 after the updates have completed. Is this not the case?
Please note that I realise there may be better ways of approaching this. My question specifically relates to SQL Server passing control back to VB6 before it has finished the work (update).
The following article proved to be the solution to this problem: http://weblogs.sqlteam.com/dang/archive/2007/10/20/Use-Caution-with-Explicit-Transactions-in-Stored-Procedures.aspx. It appears that the following behaviour was happening:
1) Record 1. Run stored procedure and create transaction. Timeout on SQL Command object occurrs.
2) Record 2. Run stored procedure successfully. Return constrol to VB6 to update flag in database.
3) Record 3. Run stored procedure successfully. Return constrol to VB6 to update flag in database.
4) Record 4. Run stored procedure successfully. Return constrol to VB6 to update flag in database.
5) Program ends. Stored procedure rolls back transaction (transaction now encompasses records 1-4). Therefore records 1-4 are not deleted.
Can you...
run the code in sql management studio and see what happens and report back? if so i will update this answer as that will help us understand if its the code / connection or sql.
other things to investigate, given we dont not what cases you have tested for...
use the same code path in ur vb application and change only the sql in the stored procedure to something very simple but has the same signature as far as what its doing (ie/ basica reading if there is reading, basic deleting if there is deleting, and same for updating and adding) to see what happens.
Also, some other thoughts...
if you are using MSSQL, it's as simple as someone leaving a query window open and it ties up the database. This is easily tested. I've had the same trouble before. I've run stored procedures before that had no timeout, that normally would run immediately but would sit overnight and not run. Only to realize another person left their query window open. Close their window and poof it finally runs. Check this out, it could be a table lock. Whether it be the application doing it, or it is being done by another user making queries to the DB. Check to make sure your application is closing connections to the DB each time their being used.
what is the best way of troubleshoot a stored procedure in SQL Server, i mean from where do you start etc..?
Test each SELECT statements (if any) outside of your stored procedure to see whether it returns the expected results;
Make INSERT and UPDATE statements as simple as possible;
Try to test Inserts and Updates outside of your SP so that you can check it gives the expected results;
Use the debugger provided with SSMS Express 2008.
Visual Studio 2008 / 2010 has a debug facility. Simply connect to to your SQL Server instance in 'Server Explorer' and browse to your stored procedure.
Visual Studio 'Test Edition' also can generate Unit Tests around your stored procedures.
Troubleshooting a complex stored proc is far more than just determining if you can get it to run or not and finding the step which won't run. What is most critical is whether it actually returns the corect results or performs the correct actions.
There are two kinds of stored procs that need extensive abilites to troublshoot. First the the proc which creates dynamic SQL. I never create one of these without an input parameter of #debug. When this parameter is set, I have the proc print the SQl statment as it would have run and not run it. Almost everytime, this leads you right away to the problem as you can then see the syntax error in the generated SQL code. You also can run this sql code to see if it is returning the records you expect.
Now with complex procs that have many steps that affect data, I always use an #test input parameter. There are two things I do with the #test parameter, first I make it rollback the actions so that a mistake in development won't mess up the data. Second, I have it display the data before it rollsback to see what the results would have been. (These actually appear in the reverse order in the proc; I just think of them in this order.)
Now I can see what would have gone into the table or been deleted from the tables without affecting the data permananently. Sometimes, I might start with a select of the data as it was before any actions and then compare it to a select run afterwards.
Finally, I often want to log actions of a complex proc and see exactly what steps happened. I don't want those logs to get rolled back if the proc hits an error, so I set up a table variable for the logging information I want at the start of the proc. After each step (or after an error depending on what I want to log), I insert to this table variable. After the rollback or commit statement, I select the results of the table variable or use those results to log to a permanent logging table. This can be especially nice if you are using dynamic SQL because you can log the SQL that was run and then when something strange fails on prod, you have a record of which statement was run when it failed. You do this in a table variable because those do not go out of scope in a rollback.
In SSMS, you can simply start by opening the proc., and clicking on the check mark button (Parse) next to the Execute button on the menu bar. It reports any errors it finds.
If there are no errors there and you're stored procedure is harmless to run (you're not inserting into tables, just creating a temp table for example), then comment out the CREATE PROCEDURE x (or ALTER PROCEDURE x) and declare all the parameters by copying that part, then define them with valid values. Then run it to see what happens.
Maybe this is simple, but it's a place to start.
I have a script in T-SQL that goes like this:
create table TableName (...)
SET IDENTITY INSERT TableName ON
And on second line I get error:
Cannot find the object "TableName" because it does not exist or you do not have permissions.
I execute it from Management Studio 2005. When I put "GO" between these two lines, it's working. But what I would like to acomplish is not to use "GO" because I would like to place this code in my application when it will be finished.
So my question is how to make this work without using "GO" so that I can run it programmatically from my C# application.
Without using GO, programmatically, you would need to make 2 separate database calls.
Run the two scripts one after the other - using two calls from your application.
You should only run the second once the first has successfully run anyway, so you could run the first script and on success run the second script. The table has to have been created before you can use it, which is why you need the GO in management studio.
From the BOL: "SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to SQL Server". Therefore, as Jose Basilio already pointed out, you have to make separate database calls.
If this can help, I was faced with the same problem and I had to write a little (very basic) parser to split every single script in a bunch of mini-script which are sent - one at a time - to the database.
something even better than tpdi's temp table is a variable table. they run lightning fast and are dropped automatically once out of scope.
this is how you make one
declare #TableName table (ColumnName int, ColumnName2 nvarchar(50))
then to insert you just do this
insert into #TableName (ColumnName, ColumnName2)
select 1, 'A'
Consider writing a stored proc that creates a temporary table and does whatever it needs to with that. If you create a real table, your app won't be able to run the script more than once, unless it also drops the table -- in which case, you have exactly the functionality of a temp table.