I created a SQL Server procedure where I am passing table names as parameters.
#Input_Table_Name nvarchar(200),
#Output_Table_Name nvarchar(200)
This is working fine when I use select * from #Input_Table_Name, however it's not working when I use select * into #Output_Table_Name or Update #Output_Table_Name or Alter table #Output_Table_Name.
I understand creating a dynamic query instead of passing table name as parameter is a good practice, however in this case, I just want to work with passing table name as parameter.
Please let me know how we can make this work with Select * into, Alter Table, or Update SQL statements.
As mentioned in comments the only way to make it pure T-SQL is to use dynamic SQL. But if you enable SQLCMD mode in SSMS you could write something like:
:setvar TableName "myTableName"
GO
SELECT * FROM $(TableName);
--it will be executed as: SELECT * FROM myTableName
Related
If I run this dynamic query:
declare #test nvarchar(1000) = 'select * into #tmp7 from bauser'
execute(#test)
and then try to query #tmp7 with:
select * from #tmp7
error is thrown:
Invalid object name '#tmp7'.
However if I run the same query manually:
select * into #tmp7 from bauser
Everything is OK. Temporary table is created and filled with results.
Why is it not working with dynamic query execution?
SCOPE!
The temporary table exists only in the scope of the dynamic executed query
If you do want to make the select put it inside the dynamic query
declare #test nvarchar(1000) = 'select * into #tmp7 from bauser
select * from #tmp7'
execute(#test)
Also you can check if a such object exists by using this
select * from sys.sysobjects so where so.name like '%tmp7%'
See this similar question
SQL Server 2005 and temporary table scope
Edit
A temp table IS A TABLE so yes you can add columns, indexes, etc. Those tables resides in fact in the TempDB database and you can even "find" them (they can be seen with strange long names) but they are destroyed after the execution of your EXEC.
Maybe your problem is to try the dynamic approach or is not related to your question at all. Try to post a new question what you got and what you need to do to get further assistance.
If you create temp table using dynamic SQL, it will not be available out of dynamic SQL scope.
You need to create it out of dynamic SQL and then use INSERT INTO to populate the table.
-- use this trick to create the temp table easily.
SELECT * INTO #tmp7
FROM bauser
WHERE 1=2
declare #test nvarchar(1000) = 'insert into #tmp7 select * from bauser'
execute(#test)
Is it possible to do something like this in sql server 2005?
WITH tmpTable AS (EXEC spWhatever)
Or any other way I can query the data returned from the sp? Thanks!!!
Temp table:
CREATE TABLE #foo (col1 int, col2 char(10), ...)
INSERT #foo
EXEC myproc
Or loopback (not sure if this still works). Edit: Could be OPENROWSET as per SQLMenace's answer
SELECT * FROM OPENQUERY (MyServername, 'USE MyDB EXEC myproc')
only with a loopback query if you don't first want to create the table, see here: Store The Output Of A Stored Procedure In A Table Without Creating A Table
example
SELECT * INTO #TempSpWho
FROM OPENROWSET ('SQLOLEDB','Server=(local);TRUSTED_CONNECTION=YES;',
'set fmtonly off exec master.dbo.sp_who')
SELECT * FROM #TempSpWho
as far as i know you can not. But you can try using User Defined Functions (UDF) instead of SP, if you do that you can you use it like a table.
I had the same question. I solved my situation by changing the SP to a VIEW. Now it acts just like a table. That's fine if you don't need to pass any parameters to the SP.
If you do need to pass parameters, make it a table-valued function.
I wish to do the following:
select * into tmptbl from sometable
EXCEPT 'sometable' is a stored procedure that returns a result set AND editing the stored procedure to suit my goal is not an option. ALSO i may or may not know the columns and types of what the procedure returns.
Basically i am looking for a proper way of doing this:
select * into tmptbl from exec someSP
Is this even possible, if so, how?
yes it is possible with a loopback query like this
SELECT * INTO #tmptbl
FROM OPENROWSET ('SQLOLEDB','Server=(local);TRUSTED_CONNECTION=YES;'
,'set fmtonly off exec DatabaseName.dbo.someSP')
More example here: Store The Output Of A Stored Procedure In A Table Without Creating A Table
Be aware that this has to be turned on first, see here: How to enable xp_cmdshell and Ad Hoc Distributed Queries on SQL Server 2005
in my SQL Server 2008 database I have a number of different tables with the same structure. I query them in different stored procedures. My first try was to pass the table name to the stored procedure, like:
CREATE PROCEDURE MyTest
#tableName nvarchar(255)
AS
BEGIN
SELECT * FROM #tableName
END
But we can't use parameters for table names in SQL. So I asked you and tried the solution with using Synonyms instead of a parameter for the table name:
CREATE PROCEDURE MyTest
#tableName nvarchar(255)
AS
BEGIN
EXEC SetSimilarityTableNameSynonym #tbl = #tableName;
SELECT * FROM dbo.CurrentSimilarityTable
END
SetSimilarityTableNameSynonym is a SP to set the Synonym dbo.CurrentSimilarityTable to the passed value (the specific table name). It looks like:
CREATE PROCEDURE [dbo].[SetSimilarityTableNameSynonym]
#tbl nvarchar(255)
AS
BEGIN
IF object_id('dbo.CurrentSimilarityTable', 'SN') IS NOT NULL
DROP SYNONYM CurrentSimilarityTable;
-- Set the synonym for each existing table
IF #tbl = 'byArticle'
CREATE SYNONYM dbo.CurrentSimilarityTable FOR dbo.similarity_byArticle;
...
END
Now, as you probably see, the problem is with concurrent access to the SPs which will "destroy" each others assigned synonym. So I tried to create dynamic synonyms for each single SP-call with a GUID via NewID()
DECLARE #theGUID uniqueidentifier;
SET #theGUID=NEWID()
SET #theSynonym = 'dbo.SimTabSyn_' + CONVERT(nvarchar(255), #theGUID);
BUT ... I can't use the dynamical created name to create a synonym:
CREATE SYNONYM #theSynonym FOR dbo.similarity_byArticle;
doesn't work.
Has anybody an idea, how to get dynamical synonyms running? Is this even possible?
Thanks in advance,
Frank
All I can suggest is to run the CREATE SYNONYM in dynamic SQL. And this also means your code is running at quite high rights (db_owner or ddl_admin). You may need EXECUTE AS OWNER to allow it when you secure the code.
And how many synonyms will you end up with for the same table? If you have to do it this way, I'd use OBJECT_ID not NEWID and test first so you have one synonym per table.
But if you have one synonym per table then why not use the table name...?
What is the point is there creating 1 or more synonyms for the same table, given the table names are already unique...
I'd fix the database design.
Why would you want multiple concurrent users to overwrite the single resource (synonym)?
If your MyTest procedure is taking a the table name as a parameter, why not simply do dynamic SQL? You can validate the #tableName against against a hardcoded list of tables that this procedure is allowed to select from, or against sys.tables
Is there a way when executing a stored procedure in Management Studio to get the data types of the result sets coming back? I'm looking for something like functionality of when you pass a table name to sp_help
You do get to look at the types though, if you call the stored procedure via ADO, ADO.NET, ODBC or the likes: The resulting recordsets have the type information you are looking for. Are you really restricted to Management Studio?
Your best bet would be to change the stored procedure to a function. But that only works if your environment allows it.
No easy way comes to mind without parsing syscomments to see what it's querying from where. If you can edit the SP to select XML, you can append XML_INFO to the query to get the schema back.
Actually, you can do it from within an SP:
EXEC ('if exists (select * from sys.tables where name = ''tmp_TableName'') drop table tmp_TableName')
EXEC ('select * into tmp_TableName from MyTable')
-- Grab the column types from INFORMATION_SCHEMA here
EXEC ('if exists (select * from sys.tables where name = ''tmp_TableName'') drop table tmp_TableName')
Although, I think there must be a better way.
It's not the most elegant solution, but you could use OPENROWSET to put the stored proc results into a table, then use sp_help to get a description of it.
eg
select * into tmp_Results
from openrowset( 'SQLOLEDB.1'
, 'Server=your_server_name;Trusted_Connection=yes;'
, 'exec your_stored_proc')
exec sp_help 'tmp_Results'
drop table tmp_Results
You could always use an actual table that is garrenteed to be unique. It's a kludge, but it's an option. This will not work inside a stored proc though.
if exists (select * from sys.tables where name = 'tmp_TableName')
drop table tmp_TableName
go
select * into tmp_TableName from MyTable
--do some stuff
go
if exists (select * from sys.tables where name = 'tmp_TableName')
drop table tmp_TableName
go