I am trying to create a Stored Procedure that has a parameter which can take an unknown number of values. For this purpose I am using a Table-Valued Parameter that I can query. I was wondering if it is possible to have the Table-Valued Parameter be temporary and have it dropped after the Stored Procedure is executed? I tried reading up about it but from what I have found nowhere is explicitly stated whether the answer is 'Yes' or 'No'.
I'd be very grateful for any help I get. Thanks!
I am using SQL Server 2016.
I declare them as follows:
CREATE TYPE [schema].[tvp] AS Table ( value INT NULL)
GO
CREATE PROCEDURE [schema].[procedure] (
#Param [tvp] READONLY
) AS BEGIN ..
Table Valued Parameters are automatically temporary and will be dropped on the SQL Server after the stored procedure executes. On the .net side the parameter will also be dropped in normal "garbage handling".
Parameters are parameters - they only hold values temporarily. What applies to an int or a varchar parameter while calling a stored proc would apply to TVP as well.
Related
I have a stored procedure that takes one table, and doing merge to another table. I want to get a table of logs with the data of what happened to each row, without inserting the data to a table.
I understand a stored procedure cannot return a table, and therefore I thought about using a function, but as of my understanding a function can not make transformations on tables.
Is combining a stored procedure with a function the solution? Or is there any thing else that I am not aware of?
A stored procedure can certainly return a result set, which the client can consume directly just like a regular SELECT statement.
That said, there are a range of options, none of which are perfect. Each suits a different scenario, and are described at length by Erland Sommarskog in How to Share Data between Stored Procedures:
Table-valued Functions
Inline Functions
Multi-statement Functions
Using a Table
Sharing a Temp Table
Process-keyed Table
INSERT-EXEC
Using SQLCLR
OPENQUERY
XML
Cursor Variables
For example, you may not wish to use a permanent table, but a temporary table created by the client and populated by the stored procedure can work well, if directly consuming the results of a SELECT inside the procedure is not suitable.
Consider this:
CREATE PROCEDURE [dbo].[setIdentifier](#oldIdentifierName as varchar(50), #newIdentifierName as varchar(50))
AS
BEGIN
DECLARE #old_id as int;
DECLARE #new_id as int;
SET #old_id = (SELECT value FROM Configuration WHERE id = #oldIdentifierName);
SET #new_id = (SELECT value FROM Configuration WHERE id = #newIdentifierName);
IF #old_id IS NOT NULL AND #new_id IS NOT NULL
BEGIN
UPDATE Customer
SET type = #new_id
WHERE type = #old_id;
END;
END
[...]
EXECUTE dbo.setIdentifier '1', '2';
What this does is create a stored procedure that accepts two parameters which it then uses to update a Customer table.
The problem is that the entire script above runs within a schema other than "dbo". Let's just assume the schema is "company1". And when the stored procedure is called, I get an error from the SELECT statement, which says that the Configuration table cannot be found. I'm guessing this is because MS SQL by default looks for tables within the same schema as the location of the stored procedure, and not within the calling context.
My question is this:
Is there some option or parameter or switch of some kind that will
tell MS SQL to look for tables in the "caller's default schema" and
not within the schema that procedure itself is stored in?
If not,
what would you recommend? I don't really want to prefix the tables
with the schema name, because it would be kind of unflexible to do
that. So I'm thinking about using dynamic sql (and the schema_name()
function which returns the correct value even within the procedure),
but I am just not experienced enough with MS SQL to construct the
proper syntax.
It would be a tad more efficient to explicitly specify the schema name. And generally speaking, schema's are mainly used to divide a database into logical area's. I would not anticipate on tables schema-hopping often.
Regarding your question, you might want to have a look at the 'execute as' documentation on msdn, since it allows to explicitly control your execution context.
I ended up passing the schema name to my script as a property on the command line for the "sqlcmd" command. Like this:
C:/> sqlcmd -vSCHEMANAME=myschema -imysqlfile
In the SQL script I can then access this variable like this:
SELECT * from $(SCHEMANAME).myTable WHERE.... etc
Not quite as flexible as dynamic sql, but "good enough" as it were.
Thanks all for taking time to respond.
In the stored procedures of the company I work with,after the set-up commands of USE and SET, and after the CREATE commandI see
CREATE PROCEDURE [dbo].[prc_InsertRespondentSessionSurveyQuotaLifeCycle]
#DBStatus INT OUTPUT,
...etc etc
SELECT #DBStatus = ##ERROR
What is the purpose of these extra lines? All I know is that I must remove them when I will create new SSRS .rdl reports.
Thanks !
##ERROR is a system variable and contains always the latest error from the DB engine.
#DBStatus is a variable that stores that value and returns it as output parameter from the stored procedure. That way you can check the error that happened during executing the stored procedure.
I want to create a SQL Server stored procedure with a varying number of parameters. It is similar to "params" in C#.
How can I do it?
Put them in an XML and try OPENXML feature.
http://msdn.microsoft.com/en-us/library/ms186918.aspx
You cannot.
What you can do is provide a default value for some of your stored procedure parameters, so you don't have to specify them when calling your stored procedure.
If you're on SQL Server 2008 or up, you could also investigate the table-valued parameter (or here) - basically the ability to pass in a table of data to your stored procedure. Maybe that'll help.
Does anyone know of a way to append text to a stored procedure from within another stored procedure? I would like to do something like the following in SQL Server 2005:
Declare str as Nvarchar(Max) = ''
set #spStr = dbo.spTest + 'Where testCol1 = ''Test'''
exec(#spStr)
I understand this may open some discussion about SQL injection attacks. I'm simply looking to see if syntax exsists to extend a stored procedure by passing it a where clause dynamically in the above manner.
There is no syntax like this available in Sql Server any version. You've got a couple of options:
You could obviously modify the procedure to include a parameter that the procedure code itself would handle as a filter in the final statement(s) that returned the result set from the procedure call. Though I'd advise against it, you could certainly have a parameter that was just a varchar/nvarchar data type which included the actual 'where' clause you want to add and have the procedure code append it to these final select statement(s) as well
Use the insert/exec syntax to populate a temp table with the results of the stored procedure execution and then simply run a filtered select against that temp table.
There are some options.
You can alter the actual SP using the metadata in INFORMATION_SCHEMA.ROUTINES (not really what I think you are wanting to be doing)
You can parameterize the SP - this should not be vulnerable to injection if the SP uses the variable directly and not to dynamically make SQL.
You might consider using a view or an inline or multi-step table-valued function instead, which can be used like a parameterized view (inline being more efficient) - SELECT * FROM udf_Test WHERE TestCol1 = 'Test'.
You can take the results of the SP and put them in a temporary table or table variable and query against that.