When I execute one of my stored procedures manually, I have to populate several variables.
Most of the variables don't change each time it is run; is it possible to pre-populate the "Value" box so that it only needs to be changed when necessary?
I am reluctant to hard code in the script as there was a series of interlinked procedures which I need to keep dynamic
I'm going to go out on a limb here and guess that you're talking about SQL Server, and that you're executing your procedure through SSMS, because of your description of the graphical interface. In the future, please tag your question with the specific database platform that the question pertains to, and try to be responsive to early comments. You'll get answers much, much faster. (If I'm wrong, just undo the tagging I added to your question.)
Although stored procedures can contain variables, what you're talking about here are parameters; values that are passed into the procedure from the calling code or application.
Parameters can be defined with default values in their declarations.
CREATE OR ALTER PROCEDURE dbo.SomeProc (
#SomeBigIntegerValue bigint = 42
)
AS...
When default values exist, the parameter becomes optional for the caller. The procedure can now be called with or without explicit parameters. Either of these will run.
EXECUTE dbo.SomeProc;
EXECUTE dbo.SomeProc
#SomeBigIntegerValue = 37;
In the first instance, the procedure will use the default value, 42. In the second instance, it will use the parameter value, 37.
You'll note that I named the parameter in the call. That's a best practice, generally, to avoid confusion, but it also allows you to send the parameters in any order. If you don't name them, they will be interpreted in the order they're declared, so you run all manner of risks there.
If you choose to execute the procedure through the GUI, the default values won't be pre-populated, but you can see which parameters have defaults and which don't by expanding the Parameters tab under the procedure name in SSMS. I couldn't find an example with defaults, but it'll looks something like this:
If you want the procedure to use the default value, just tick the Pass Null Value check box.
(In case you're wondering, we have a truncate proc so that our ETL service accounts can have scaled back permissions without having to do fully-logged, row-by-row deletions...)
Related
Is it possible (using only T-SQL no C# code) to write a stored procedure to execute a series of other stored procedures without passing them any parameters?
What I mean is that, for example, when I want to update a row in a table and that table has a lot of columns which are all required, I want to run the first stored procedure to check if the ID exists or not, if yes then I want to call the update stored procedure, pass the ID but (using the window that SQL Server manager shows after executing each stored procedure) get the rest of the values from the user.
When I'm using the EXEC command, I need to pass all the parameters, but is there any other way to call the stored procedure without passing those parameter? (easy to do in C# or VB, I mean just using SQL syntax)
I think you are asking "can you prompt for user input in a sql script?". No not really.
You could actually do it with seriously hack-laden calls to the Windows API. And it would almost certainly have serious security problems.
But just don't do this. Write a program in C#, VB, Access, Powerscript, Python or whatever makes you happy. Use an tool appropriate to the task.
-- ADDED
Just so you know how ugly this would be. Imagine using the Flash component as an ActiveX object and using Flash to collect input from the user -- now you are talking about the kind of hacking it would be. Writing CLR procs, etc. would be just as big of a hack.
You should be cringing right now. But it gets worse, if the TSQL is running on the sql server, it would likely prompt or crash on the the server console instead of running on your workstation. You should definitely be cringing buy now.
If you are coming from Oracle Accept, the equivalent in just not available in TSQL -- nor should it be, and may it never be.
Right after reading your comment now I can understand what you are trying to do. You want to make a call to procedure and then ask End User to pass values for Parameters.
This is a very very badddddddddddddddddddd approach, specially since you have mentioned you will be making changes to database with this SP.
You should get all the values from your End Users before you make a call to your database(execute procedure), Only then make a call to database you Open a transaction and Commit it or RollBack as soon as possible and get out of there. as it will be holding locks on your resources.
Imagine you make a call to database (execute sp) , sp goes ahead and opens a transaction and now wait for End user to pass values, and your end user decides to go away for a cig, this will leave your resources locked and you will have to go in and kill the process yourself in order to let other user to go and use database/rows.
Solution
At application level (C#,VB) get all the values from End users and only when you have all the required information, only then pass these values to sp , execute it and get out of there asap.
You can specify the parameters by prefixing the name of the parameter with the # sign. For example, you can call an SP like this:
EXEC MyProc #Param1='This is a test'
But, if you are asking if you can get away with NOT providing required parameters, the answer is NO. Required is required. You can make them optional by providing a default value in the declaration of the SP. Then you can either not pass the value or call it like this:
EXEC MyProc #Param1=DEFAULT
--OR
EXEC MyProc DEFAULT
I have a stored procedure sp_1 that calls another stored procedure sp_1_1.
I know how to suppress the results from sp_1_1 using this trick.
The real problem is that sp_1_1 itself also call another stored procedure sp_1_1_1 which ALSO returns it's results to sp_1_1!!
I may not change either sp_1_1 or sp_1_1_1, and can only change sp_1.
The results returned to sp_1 are 2 recordsets, with the first from sp_1_1 and the second from sp_1_1_1.
SUMMARY:
sp_1 (Needs to suppress two recordsets returned from below)
+---- sp_1_1 (returns its own results, then results from below)
+----------sp_1_1_1 (returns results)
Firstly, an aside, SQL Server "Denali" gives you new options for handling resultsets.
In this case, because you're nesting you obviously can't use the insert/exec trick.
One kludgy workaround, if you don't want to refactor too much, is to add a parameter to the proc with a default, something like #SuppressResults bit = false.
Then, in the routines that need to be nested, call it explicitly with #SuppressResult=True, and then alter the code in the routines to not select results if #SuppressResults=True.
The important thing is to provide a default and put the parameter at the end. That will prevent existing calls to the routine from elsewhere in the code base needing to be altered.
I have a stored procedure that causes blocking on my SQL server database. Whenever it does block for more than X amount of seconds we get notified with what query is being run, and it looks similar to below.
CREATE PROC [dbo].[sp_problemprocedure] (
#orderid INT
--procedure code
How can I tell what the value is for #orderid? I'd like to know the value because this procedure will run 100+ times a day but only cause blocking a handful of times, and if we can find some sort of pattern between the order id's maybe I'd be able to track down the problem.
The procedure is being called from a .NET application if that helps.
Have you tried printing it from inside the procedure?
http://msdn.microsoft.com/en-us/library/ms176047.aspx
If it's being called from a .NET application you could easily log out the parameter being passed from the .net app, but if you don't have access, also you can use SQL Server profiling. Filters can be set on the command type i.e. proc only as well as the database that is being hit otherwise you will be overwhelmed with all the information a profile can produce.
Link: Using Sql server profiler
rename the procedure
create a logging table
create a new one (same signature/params) which calls the original but first logs the params and starting timestamp and logs after the call finishes the end timestamp
create a synonym for this new proc with the name of the original
Now you have a log for all calls made by whatever app...
You can disbale/enable the logging anytime by simply redefining the synonym to point to the logging wrapper or to the original...
The easiest way would be to run a profiler trace. You'll want to capture calls to the stored procedure.
Really though, that is only going to tell you part of the story. Personally I would start with the code. Try and batch big updates into smaller batches. Try and avoid long-running explicit transactions if they're not necessary. Look at your triggers (if any) and cascading Foreign keys and make sure those are efficient.
easiest way is to do the following:
1) in .NET, grab the date-time just before running the procedure
2) in .Net, after the procedure is complete grab the date-time
3) in .NET, do some date-time math, and if it is "slow", write to a file (log) those start and end date-times, user info, all the the parameters, etc.
I have a stored procedure (sproc A) which is syntactically correct. So when I hit "run" on its create or alter statement, it is saved into the database.
However, sproc A has a call to another stored procedure (sproc B). It does not provide enough parameters for sproc B, so I don't see how it's a valid stored procedure.
I want to detect any stored procedures in my database which aren't passing enough parameters to their own stored procedures.
Thankyou,
Fidel
Unfortunately, there is no mechanism in SQL Server to test dependencies, parameters etc
You have to search+check, or provide defaults for parameters. You'll only pick it up by testing otherwise.
A good auto complete tool like Red Gate SQL prompt can list parameters + types for you
Note:
It's a long standing problem and there is even a request to MS including this.
SP parameter checking is one of the OPTION STRICT suggestions
I have several stored procedures that all use the same set of parameters. Is there a way to define and save the parameter list as a reusable block of code? Something like this:
CREATE PROCEDURE test
Using StoredParameterList
AS
BEGIN
SQL Statement
END
Is this possible? It would make code maintenance easier if a parameter needed to be changed.
Well, sort of. I've never used them, but Sql Server supports something called User Defined Types. I suspect you can create a user-defined type that represents your parameter list and then just have one parameter on each procedure with UDT.