This is running on SQL Server 2008, but the database is in SQL Server 2000 compatibility mode (this I cannot change).
A temporary table is created at the beginning of the stored procedure and then insert into via an EXEC statement from dynamically generated SQL. How is this executing successfully, even though the temporary table (should be, from my understand) is out the execution scope, or does this get bypassed temporarily when performing these statements inside a stored procedure?
Example below:
CREATE PROCEDURE myProc (Param1 int....)
AS
BEGIN
Declare #SQL varchar(max) = null
Create table #tempTable
(
ID int,
Code1 varchar(255),
...
)
SET #SQL = 'insert into #tempTable '
+ ...
EXEC(#SQL)
Select * from #tempTable
END
Any help understanding this would be greatly appreciated!
Thanks!
Shortly:
The temporary table created in the outer batch is accessible inside the dynamic SQL but not vice versa.
See doc
A local temporary table created in a stored procedure is dropped
automatically when the stored procedure is finished. The table can be
referenced by any nested stored procedures executed by the stored
procedure that created the table. The table cannot be referenced by
the process that called the stored procedure that created the table.
Related
I have inherited a database that contains a lot of stored procedures that create a local temporary table, calls a procedure that uses the temp table, and then deletes the temp table. Like this:
CREATE PROCEDURE procSelectFromTable
AS
BEGIN
SELECT *
FROM #myTable
END;
GO
CREATE PROCEDURE procMakeTable
AS
BEGIN
SELECT 1 AS [ID]
,'NestedProcedure' AS [Message]
INTO #myTable;
EXEC procSelectFromTable
DROP TABLE #myTable;
END;
GO
EXEC procMakeTable;
GO
--Clean up
IF OBJECT_ID('tempdb..#myTable') IS NOT NULL
DROP TABLE #myTable;
DROP PROCEDURE procMakeTable;
DROP PROCEDURE procSelectFromTable
I have not seen procedures written in this manner before. Is it safe for me to assume this is ok because the nested procedure will always be called in the same spid and will always be able to access the temp table?
Yes, the nested procedure will have access to the local temp table. This was common use before the introduction of table-valued parameters or when the procedures exist in different databases in the same instance. The procedures are tightly coupled and might be a problem to test the 'child' procedure, but it has the advantage that it can be called from multiple procedures.
I'm trying to run a stored procedure that creates a local table - #table1
The stored procedure is supposed to look for values and create the table and insert the values into it...
INSERT INTO #table1
I execute the stored procedure and it shows that 1 row() affected, however, I am unable to find this table in the list of my tables. Why am I not able to see it or access it?
EDIT: I'm running the stored procedure inside SQL Server against a database. At the end of the stored procedure, the last line is:
Select * from #table1
Thanks.
The #table is a local temp table. It does not exist as a permanent table that you can look for outside the scope of the stored proc. Once the stored proc is run, the temp table is dropped because it is no longer in scope. Temp tables are stored temporarily in the tempdb database but with a different name because two people running the stored procedure at the same time would each have a table that can be referenced in the proc as #table but it would be two separate tables in the tempdb.
Now if what you are doing is looking to see what is in #table at a point in the stored proc in order to troubleshoot the proc, then you need to set thing up in the proc so that you can see the results at different stages or when you hit a certain state such as an error.
This could be something like adding a #debug variable to the proc so that when you are in debug mode, you can select the results to the screen when you are running something like:
CREATE PROC test_proc (#Id INT, #debug BIT = 0)
AS
CREATE TABLE #temp(id INT)
INSERT INTO #temp
VALUES (#Id), (1), (2)
IF #debug = 1
BEGIN
SELECT * FROM #temp
END
UPDATE #temp
SET Id = id-1
IF #debug = 1
BEGIN
SELECT * FROM #temp
END
GO
You would then execute the proc without debugging as so (note that since I am not returning something or inserting to permanent tables, this proc will insert to #temp but you can't see anything. I just didn't want to get complicated here, the steps of the proc will vary depending on what you want to do, the concept I am trying to show is how to use the debug variable):
EXEC test_proc #Id= 5
and with debugging as
EXEC test_proc #Id= 5, #debug= 1
Or it might involved using a table variable instead (because they don't get rolled back on error) and then inserting the data from that table variable into a logging table after the rollback occurs in the Catch block, so that you can see the values at the time the error occurred.
Without knowing more about why you are looking for #temp and what the data means and is used for, it is hard to say what you need to do.
Did you tried refreshing the tables after exceuting Stored procedure
What are the best approaches to the below scenario?
In my C# program, I have some sql commands such as UPDATE, INSERT, DELETE. I could execute them in my C# program (which works fine) but I need to execute these sql commands when one of the stored procedure comes to the last line. So I am planning to store the sql commands in some staging table in the same database and then I would like to open this table within the stored procedure and execute one by one.
What is the best approach in terms of opening a table within stored procedure and then traversing through the table based on some condition (like select * from TempStagingTable where customerId = '1000'). If it returns 10 records, I would like to loop them and execute the sql command stored in a column named "CustomSqlScript"
PS: I am using SQL 2008 R2.
Well, you can select the data from table A initially, and instead of using cursor you can use while loop(as it will increase your performance compared to cursor) and then you can execute your predefined SQL statement from table B
Please find below sql scripts to do the same
Please note: I have not made use of any relation,This is just a plain example
CREATE TABLE test1(
customSqlScripts VARCHAR(100)
)
CREATE TABLE test2(
customer_Id INT PRIMARY KEY ,
first_Name VARCHAR(100),
last_name VARCHAR(100)
)
INSERT INTO test1 VALUES('Select first_Name from test2 where customer_Id=')
INSERT INTO test2 VALUES('1','Rohit','Tiwari')
DECLARE #Count INT
DECLARE #iCount INT=0
DECLARE #dummysql VARCHAR(100)
SELECT #Count= Count(*)
FROM test2
WHERE last_name='Tiwari'
WHILE(#icount<#count)
BEGIN
SELECT #dummysql =customSqlScripts
FROM test1
SET #dummysql=#dummysql+'1'
EXEC (#dummysql)
SET #icount=#icount+1
END
I have two stored procedures; I am calling one stored proc from another.
I return a table from the 1st stored procedure. When I execute the 1st alone, I get the table correctly.
But when I call the 1st stored procedure from another stored procedure, it always returns command completed successfully and no results.
I call it like this in stored proc 2:
set #query = 'exec servername.dbo.storedproc1 #ClassName = ''' +
#ClassName +''', #StatusName = ''' + #StatusName
exec(#query)
Inside the outer procedure, create a temporary table with a similar schema to the result set returned from the inner procedure.
When calling the inner procedure, use insert..exec, like this:
insert #tempTable exec InnerProcedure
Then select the data from the temporary table.
First create a temporary table that captures data obtained from executing first procedure . Then use Select statement to retrieve desired data from temporary table. Don't forget to use drop the temporary table table after Select statement else next time you execute the procedure error will be thrown saying table already exist . On other hand you can use table variable to avoid dropping table as scope of table variable is limited to lifetime of the containing stored procedure.
`
Insert into #temptable
Exec sprcdre1
Select * from #temptable
I have a temp table in a SP. I insert some values into it. I will need to then EXEC a second SP by sending in the values from the temp table. I would rather avoid having to use local variables.
DECLARE #tmp TABLE
(
Name VARCHAR(200).
Code INT
)
INSERT INTO #tmp
SELECT 'TEST', 100
EXEC MyProc
#Name = --Here I send the values from temp
#Code =
create an actual temp table #TempTable and not a #varibale table, and you can share it between parent and child stored procedures...
http://www.sommarskog.se/share_data.html#temptables
You can't, unless you're on SQL Server 2008 which allows table data types. Which can be used as stored proc parameters.
Otherwise frp SQL 2000/2005, for 10 rows in the temp table, you need loop through 10 inner stored proc calls.
You could wrap it all in a single SP.