I have several views in Database 1 and I wrote a stored procedure in database 2. The stored procedure in database 2 references several tables in database 1.
For some reason when I have:
USE Database1
GO
while testing, it works completely fine. But when I use
USE Database2
GO
the stored procedure doesn't compile. No warnings, just continues to spin. The first case only takes about 1 second to run.
Anyone know what could possibly be the issue? When I attempt to run similar stored procedures in database2 that use the same references to database1 it works fine. Also, they are on the same server in SQL Server.
Sorry I am unable to post the code.
SQL Server has to take out locks on the objects so it can create a query plan. It either cannot connect to the database or cannot take the locks it needs.
Related
I am frequently testing certain areas on a development server and so running a pre-defined SQL statement to truncate the tables in question before testing again. It would only be a slip of a key to switch to the live server.
I'm looking for an IF statement or similar to prevent that.
Either to check the server name, database name, or even that a certain record in a different table exists before running the query.
Any help appreciated
For such cases I use stored procedures. I'd call them TestTruncateTables, etc.
Then instead of calling TRUNCATE TABLE you should CALL TestTruncateTables.
Just make sure that the procedures are not created on the live server. If by any chance you happen to run CALL TestTruncateTables on the live server you only get an error about non-existing proc.
Using Microsoft SQL Server 2012
I have a graphical query plan for a stored procedure. In one part of the procedure the plan makes reference to a table (not a view or function) that doesn't exist within the stored procedure. I've gone through the stored procedure line by line, checked tables to see if triggers had been defined on them and still I can't find the table name the query plan is making a reference to.
Has anyone ever come across this? Is this a bug or am I missing something obvious.
Thanks!
I'm running a stored procedure on server1 from my application. The stored procedure does a bunch of stuff and populate a table on server2 with the result from the procedure.
I'm using linked server to accomplish this.
When the stored procedure is done running the application continues and tries to do some manipulation of the result from the stored procedure.
My problem is that the results from the stored procedure has not been completely inserted into the tables yet, so the manipulation of the tables fails.
So my question is. Is it possible to ensure the insert into on the linked server is done synchronous? I would like to have the stored procedure not return until the tables on the linked server actually is done.
You can use an output parameter of the first procedure. When the table is create on the second server the output parameter value will be return to your application and indicates the operation is ready.
If the things are difficult then this you can try setting a different isolation level of your store procedure:
http://msdn.microsoft.com/en-us/library/ms173763.aspx
I found the reason for this strange behavior. There was a line of code in my stored procedure added during debug that did a select on a temporary mem table before the data in the same table was written to the linked server.
When the select statement was run, the control was given back to my application and at the same time the stored procedure continued running. I guess the stored procedure was running synchronously from the start.
i have this stored procedure, doing a select query with couple of inner joins (one of the tables is in another db). Now, i had to write this query as dynamic cause first i had to find which db the select query should run. Anyway, none of the tables have permissions on them, just giving permission to the stored procedure for the database role "personel" (which includes everyone).
But now, someone with a personel role runs this stored proc, they are getting the error "The SELECT permission was denied on the object 'tbl_table', database 'Db', schema 'dbo'." no difference in the schema, and there are other procs using the same table that are running normally.
Can using a dynamic query (exec (Use DB; select ...) ) be the reason for this? Like cause it is dynamic, i should give permissions to the tables also ?
Thanks
The short answer is yes.
When you compile a stored procedure, permissions of the user/login creating the stored procedure are checked. When someone else executes it, their ability to read those tables is no longer relevant (in most cases), but rather just their ability to execute the SP.
When executing the dynamic code, however, the permissions regarding the tables have to be checked there and then. This means that the executing user's permissions are being checked.
Yes, this can be the reason. Read this to get an explanation and a possible solution.
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.