Temporary table in stored procedure - sql

I have a stored procedure that executes variously dynamic sql statements.
In reality this Stored procedure will be fired from SSIS with various parameters.
So there will be a lot of parallel executions.
This stored procedure uses temp tables during execution.
I create the tables manually with a Select .. into statement and drop them at the end.
During parallel executions, the process ends up in error because of execution 2 is trying to create or use the same temp table as execution 1. This is giving errors..
I tried to resolve this using table variables. However this does not work in dynamic SQL. (How to use table variable in a dynamic sql statement?)
I tried to resolve this using local temp table. However SSIS and Stored Procedures using local temp tables is not a great marriage. I have never found a good working solution so far.. http://consultingblogs.emc.com/jamiethomson/archive/2006/12/20/SSIS_3A00_-Using-stored-procedures-inside-an-OLE-DB-Source-component.aspx
I have an idea of how to create a temp table with the name of a GUID. And then use this so that it is unique in the Stored Procedure execution. However this would really make my dynamic SQL code much more difficult to maintain.
Does anyone see other options or am I over-complicating things? Is there a more viable solution?

You can create the temp table as
Create table #tmp_execute
(
id int,
name varchar(50),
.......
)
then, execute the dynamic query
insert into #tmp_execute
select .... from tbl_Sample
If you are require to execute the dynamic columns, you can use ' alter table #tmp_execute add your_column int' with conditional statement.

Related

Executing stored procedure through SAS not working the same as it does in SQL Server

I have a stored procedure that I often execute within SQL Server. Without copying hundreds of lines of code into here, it basically does the following:
You enter a database and table name as parameters.
The procedure then calculates summary statistics on all fields in the table (average, sum etc.) and inserts them into a temporary table.
The summary statistics are then inserted into an existing meta table.
The temporary table of stats is then dropped.
The procedure itself works perfectly when executing through SQL Server.
However, executing the same procedure with the same parameters through SAS code (via WPS) does not return the same results. It kicks off the procedure and calculates the statistics, but then fails to insert the statistics into the existing table and fails to drop the temporary table. Despite this, no errors are returned in the SAS log. The SAS code to execute the procedure is here:
proc sql;
connect to odbcold(required="dsn=&SQLServer; database=_Repository;");
execute (SP_Meta_Stats
#DATABASE = &vintage.,
#TABLE_NAME = &table_name.) by odbcold;
disconnect from odbcold;
quit;
I can assure you the macro variables have been setup correctly because the procedure is kicking off correctly with the correct parameters. It's just not completing the procedure as it does directly in SQL.
Are there are any known limitations to executing SQL stored procedures through a proc sql statement in SAS? Any known reasons why this not be computing the same as it does in SQL, despite just executing the same procedure?
EDIT:
This seems to be some sort of connection issue. As if after a certain time lapses, WPS disconnects from the SQL connection. Because sometimes the temporary table has only computed stats for a handful of variables.

Manipulating data from a stored procedure by saving data into a table

Problem: I have a stored procedure in SQL Server 2012 and I want to put constraints to the output so I only get relevant information.
I am using Execute. The way I see it I have two options:
save the result of the execution into a table, so I can use it for different purposes
put constraints to the variables in Execute so I only get the results I want
The first method is discussed here:
Insert results of a stored procedure into a temporary table .
My code is (due to company information I can't share the whole thing):
create table #mtable ( .... )
Insert into #mtable
Execute [myProcedure]
The error:
An INSERT EXEC statement cannot be nested.
I assume the error is because of the code in the stored procedure. How can I fix that problem without looking into the code for the stored procedure. Is there another way where I can save the content in a table?
My problem can also be solved by proposal #2. Is it possible for me to manipulate the output from the stored procedure with something like:
Execute [myProcedure] where variable1 > 100

How to call a stored procedure within a SELECT query?

I have a store procedure that takes in a uniqueidentifier and returns a table. What I am trying to do is to use these results like a regular table, but I realize SQL is still limited and doesn't allow it (yet!)
Example:
SELECT *
FROM MyTable MT
WHERE NOT EXISTS
(SELECT *
FROM MyStoredProc(MT.ID) MSP
WHERE MT.SomeData = MSP.SomeData)
Is there an alternative solution to this problem? And please don't suggest using a function or a view as they are not exchangeable with a stored procedure. I'm actually quite surprised that the developers haven't implemented this yet considering the age of SQL.
Any help would be really appreciated!
That syntax won't work. You'd have to dump the results of the stored proc into a temp table and the reference the temp table.
Because Of the parameter, I'd suggest either making a new version of the proc that can execute for all IDs at once or drop the proc code into a table valued function (which can be executed using the syntax you're trying to use).

SQL: Using Stored Procedure within a Stored Procedure

I have a few stored procedures that return the same set of data (same columns) to a user. The stored procedure called depends on certain conditions. These stored procedures are fairly intensive and are being run by every user of the system. I would like to create stored procedure that calls each of these procedures and stores the data on a separate table. I will then run this new stored procedure every 5 minutes or so and let the users pull from the new table.
T_OutboundCallList is a permanent table with the same columns as returned by the two stored procedures.
I would like something like the following but when I try to run this it just runs continuously and I have to stop the procedure.
BEGIN
TRUNCATE TABLE T_OutboundCallList
INSERT T_OutboundCallList EXECUTE p_LeadVendor_GetCallsForCallList
INSERT T_OutboundCallList EXECUTE p_CallLog_GetAbandonedCallsCallList
END
Each of the procedures (*CallList) return a list of calls to be made and I do want them entered into the new table in this order (LeadVendor calls before AbandonedCalls). I also need to clear the table before adding the calls as there may be new calls that need to be higher in the list.
Is there some problem with this procedure that I am not seeing?
Thanks,
Brian
Without seeing the code in your *CallList procs it is hard to say what issue you are having. You should have the insert commands inside of your nested procedure. You can use the results of a procedure to insert data, but not like you are above. It is using OPENROWSET, and I think you will be better off the way I suggested.

Access to Result sets from within Stored procedures Transact-SQL SQL Server

I'm using SQL Server 2005, and I would like to know how to access different result sets from within transact-sql. The following stored procedure returns two result sets, how do I access them from, for example, another stored procedure?
CREATE PROCEDURE getOrder (#orderId as numeric) AS
BEGIN
select order_address, order_number from order_table where order_id = #orderId
select item, number_of_items, cost from order_line where order_id = #orderId
END
I need to be able to iterate through both result sets individually.
EDIT: Just to clarify the question, I want to test the stored procedures. I have a set of stored procedures which are used from a VB.NET client, which return multiple result sets. These are not going to be changed to a table valued function, I can't in fact change the procedures at all. Changing the procedure is not an option.
The result sets returned by the procedures are not the same data types or number of columns.
The short answer is: you can't do it.
From T-SQL there is no way to access multiple results of a nested stored procedure call, without changing the stored procedure as others have suggested.
To be complete, if the procedure were returning a single result, you could insert it into a temp table or table variable with the following syntax:
INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...
You can use the same syntax for a procedure that returns multiple results, but it will only process the first result, the rest will be discarded.
I was easily able to do this by creating a SQL2005 CLR stored procedure which contained an internal dataset.
You see, a new SqlDataAdapter will .Fill a multiple-result-set sproc into a multiple-table dataset by default. The data in these tables can in turn be inserted into #Temp tables in the calling sproc you wish to write. dataset.ReadXmlSchema will show you the schema of each result set.
Step 1: Begin writing the sproc which will read the data from the multi-result-set sproc
a. Create a separate table for each result set according to the schema.
CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
, Document_status_definition_uid INT
, Document_status_Code VARCHAR(100)
, Attachment_count INT
, PRIMARY KEY (Document_ID));
b. At this point you may need to declare a cursor to repetitively call the CLR sproc you will create here:
Step 2: Make the CLR Sproc
Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub usp_SF_ReadSFIntoTables()
End Sub
End Class
a. Connect using New SqlConnection("context connection=true").
b. Set up a command object (cmd) to contain the multiple-result-set sproc.
c. Get all the data using the following:
Dim dataset As DataSet = New DataSet
With New SqlDataAdapter(cmd)
.Fill(dataset) ' get all the data.
End With
'you can use dataset.ReadXmlSchema at this point...
d. Iterate over each table and insert every row into the appropriate temp table (which you created in step one above).
Final note:
In my experience, you may wish to enforce some relationships between your tables so you know which batch each record came from.
That's all there was to it!
~ Shaun, Near Seattle
There is a kludge that you can do as well. Add an optional parameter N int to your sproc. Default the value of N to -1. If the value of N is -1, then do every one of your selects. Otherwise, do the Nth select and only the Nth select.
For example,
if (N = -1 or N = 0)
select ...
if (N = -1 or N = 1)
select ...
The callers of your sproc who do not specify N will get a result set with more than one tables. If you need to extract one or more of these tables from another sproc, simply call your sproc specifying a value for N. You'll have to call the sproc one time for each table you wish to extract. Inefficient if you need more than one table from the result set, but it does work in pure TSQL.
Note that there's an extra, undocumented limitation to the INSERT INTO ... EXEC statement: it cannot be nested. That is, the stored proc that the EXEC calls (or any that it calls in turn) cannot itself do an INSERT INTO ... EXEC. It appears that there's a single scratchpad per process that accumulates the result, and if they're nested you'll get an error when the caller opens this up, and then the callee tries to open it again.
Matthieu, you'd need to maintain separate temp tables for each "type" of result. Also, if you're executing the same one multiple times, you might need to add an extra column to that result to indicate which call it resulted from.
Sadly it is impossible to do this. The problem is, of course, that there is no SQL Syntax to allow it. It happens 'beneath the hood' of course, but you can't get at these other results in TSQL, only from the application via ODBC or whatever.
There is a way round it, as with most things. The trick is to use ole automation in TSQL to create an ADODB object which opens each resultset in turn and write the results to the tables you nominate (or do whatever you want with the resultsets). you can also do it in DMO if you enjoy pain.
There are two ways to do this easily. Either stick the results in a temp table and then reference the temp table from your sproc. The other alternative is to put the results into an XML variable that is used as an OUTPUT variable.
There are, however, pros and cons to both of these options. With a temporary table, you'll need to add code to the script that creates the calling procedure to create the temporary table before modifying the procedure. Also, you should clean up the temp table at the end of the procedure.
With the XML, it can be memory intensive and slow.
You could select them into temp tables or write table valued functions to return result sets. Are asking how to iterate through the result sets?