use variable #table in select statement - sql

Can I use a variable as the name of an existing table? The first SELECT works fine, but the second generates an error suggesting I am trying to create a table variable. All I want though is to use a variable for the name of an existing table.
declare #name varchar(100)
CREATE TABLE CURVES(
ARC VARCHAR(10),
RADIUS VARCHAR (10),
CENPTid BIGINT,
StartPTid BIGINT,
EndPTid BIGINT)
INSERT INTO CURVES
VALUES ('10.23', '50.22', 5, 6, 8)
SELECT * FROM CURVES
set #name='CURVES'
SELECT * FROM #name

You cannot do what your trying to do this way.
But you can Declare a Table Variable and then populate that table variable and select from that table variable. something like this...
-- Actual Table
CREATE TABLE CURVES
(
ARC VARCHAR(10),
RADIUS VARCHAR (10),
CENPTid BIGINT,
StartPTid BIGINT,
EndPTid BIGINT
)
GO
-- Populate the table
INSERT INTO CURVES
VALUES ('10.23', '50.22', 5, 6, 8)
GO
-- Declare the table Variable
declare #name TABLE
(
ARC VARCHAR(10),
RADIUS VARCHAR (10),
CENPTid BIGINT,
StartPTid BIGINT,
EndPTid BIGINT
)
INSERT INTO #name --<-- Populate the Table Variable
SELECT * FROM CURVES
SELECT * FROM #name --<-- Now select from table Variable

This is dynamic SQL approach, so
set #name='CURVES'
exec ('SELECT * FROM '+ #name)

Related

How to insert a dynamic sql variable into a temporary table

So I want to insert the variables email, username, and age from a stored procedure into a temporary table and am running into a few issues.
Declare #email [varchar](8000)
,#user_name [varchar](8000)
, age[int]
select distinct value as value
into #temptable
from #email
,#user_name
,#age
select *
from #temptable
I am getting a syntax error. Does anybody have any advice?
Generally, I would use this syntax to insert the results of a stored procedure into a table or table variable:
INSERT #temptable EXECUTE dbo.MyStoredProcedureName
For example (table variable example):
declare #temptable table
(
name varchar(255),
field varchar(255),
filename varchar(255),
filegroup varchar(255),
size varchar(255),
maxsize varchar(255),
growth varchar(255),
usage varchar(255)
);
INSERT #temptable Exec sp_helpfile;
select * from #temptable ;
EDIT: Per your question about why can't you do this in the SP itself, the syntax would be something like:
DECLARE #Email nvarchar(4000),#UserName nvarchar(4000),#age int
declare #temptable table
(
email nvarchar(4000),
UserName nvarchar(4000),
age int
)
SELECT #Email = 'test#test.com', #UserName = 'MyName', #age = 21
INSERT INTO #temptable(Email, UserName, age) SELECT #Email, #UserName, #age
SELECT * FROM #temptable

Doing a for-each record in a user defined table type in Stored Procedure

:)
I have this defined type:
CREATE TYPE dbo.MyType
AS TABLE
(
name varchar(255),
value varchar(255)
);
Having this stored procedure:
CREATE PROCEDURE MyProcedure #docName varchar(255), #docPath varchar(255), #values AS [dbo].MyType Readonly
AS
declare #ID table (ID int)
INSERT INTO MyTable output inserted.fileID into #ID values (#docName,#docPath)
-- insert loop here
GO;
And the following "one to many" table
CREATE TABLE TableN (
fileID int PRIMARY KEY,
name varchar(255),
value varchar(255)
)
How can I, where it is noted in the above code, make a loop in order to for each record in the MyType table, to insert it into TableN, together with the fileID from the insert?
Thanks!
There's no need for a loop (you need to stop thinking programmatically in SQL and think in datasets). Just do an INSERT:
INSERT INTO TableN (FileID,[name],[value])
SELECT ID.ID,
V.[Name],
V.[value]
FROM #values v
CROSS JOIN #ID ID;

SQL - Table Type / passing a table as a paramater

I have a stored procedure that takes in a table as a parameter.
For example: I have a type PartsImport:
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
Then the stored procedure takes in this param:
#PTable PartsImport ReadOnly
The stored procedure does an insert into a table via a simple select * from #PTable, but now I need to join this table variable with other tables when creating the select statement, but I always get an error message
Must declare the scalar variable "#PPTable"
How do you select an individual column from this #PTable? I tried #PTable.LogDate, but it doesn't like the syntax. Is it possible to use the variable table in a join and select the columns or does it only work with select * ?
You can try using an Alias to refer to your table, instead of the variable name. For example:
SELECT P.LogDate FROM #PTable AS P
try with below example, when you fetch column only from table variable then works fine but when you use in join you must use alias name with table variable name.
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
create table PartsImportother (col1 varchar(10), col2 varchar(3))
insert into PartsImportother values('1','ads')
Declare #table PartsImport
insert into #table(Number_Key,LogDate,FullName,Descrip) values('1','01-01-2015','aaa','adsfadfa')
-- select [specific column] from [only table variable]
select Number_Key from #table
-- select [specific column] from [table variable with join]
select T.Number_Key from #table as T inner join PartsImportother on T.Number_Key = PartsImportother.col1

Select only few columns from procedure and insert into table

I have a stored procedure that returns 6 columns. But I want to take only 2 columns and insert them into my table variable.
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable EXEC [GetAllTenantCategories] #TenantId
When I run this
Column name or number of supplied values does not match table
definition
How to insert only specified columns from a stored procedure?
I do not want to use SELECT INTO as it is not supported by SQL Azure
Tried below and got Invalid object name '#Temp'
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #Temp EXEC [GetAllTenantCategories] 1
INSERT INTO #CategoryTable (CategoryId, Name)
SELECT CategoryId, Name from #Temp
DROP TABLE #Temp
You can create a temp table first and the INSERT the required columns in your table variable.
CREATE TABLE #temp
(
your columns and datatype
)
INSERT INTO #temp
EXEC [GetAllTenantCategories] #TenantId
Then you can,
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable (CategoryId, Name)
select CategoryId, Name from #temp
Also drop the #temp table,
DROP TABLE #temp
Refer the points taken from https://www.simple-talk.com/sql/performance/execution-plan-basics/
When the Estimated Plan is Invalid
In some instances, the estimated plan won't work at all. For example, try generating an estimated plan for this simple bit of code:
CREATE TABLE TempTable
(
Id INT IDENTITY (1 , 1 )
,Dsc NVARCHAR (50 )
);
INSERT INTO TempTable ( Dsc )
SELECT [Name]
FROM [Sales] .[Store] ;
SELECT *
FROM TempTable ;
DROP TABLE TempTable ;
You will get this error:
Invalid object name 'TempTable'.
The optimizer, which is what is used to generate Estimated Execution plans, doesn't execute T-SQL.
It does run the stateĀ­ments through the algebrizer , the process outlined earlier that is responsible for verifying the names of database objects. Since the query has not yet been executed, the temporary table does not yet exist. This is the cause of the error.
Running this same bit of code through the Actual execution plan will work perfectly fine.
Hope you got why your temp table approach not worked :) Because you might tried as T-SQL
We can use OPENQUERY
SELECT EmployeeID,CurrentSalary INTO #tempEmp
FROM OPENQUERY(LOCALSERVER,'Exec TestDB.dbo.spEmployee')

SQL Server: Stored Proc input table variable workaround

I'm trying to find a good work around to not being able to use a table variable as an input to a stored procedure. I want to insert a single record into a base table and multiple records into a pivot table. My initial thought process led me to wanting a stored proc with separate inputs for the base table, and a single list input for the pivot table records, i.e.:
create proc insertNewTask (#taskDesc varchar(100), #sTime datetime, #eTime datetime, #items table(itemID int))
as
begin
declare #newTask table(newID int)
insert into tasks(description, sTimeUTC, eTimeUTC)
output inserted.ID into #newTask
values(#taskDesc, #sTime, #eTime)
insert into taskItems(taskID, itemID)
select newID, itemID
from #newTask cross join #items
end
As already stated, the above code won't work because of the table variable input, #items (I believe primarily due to variable scope issues). So, are there any good workarounds to this?
Original Question
I have three tables:
CREATE TABLE items
(
ID int PRIMARY KEY,
name varchar(20),
description varchar(100)
)
CREATE TABLE tasks
(
ID int identity(1,1) PRIMARY KEY,
description varchar(100),
sTimeUTC datetime,
eTimeUTC datetime
)
CREATE TABLE taskItems
(
taskID int,
itemID int,
CONSTRAINT fk_taskItems_taskID FOREIGN KEY (taskID) on tasks(ID),
CONSTRAINT fk_taskItems_itemID FOREIGN KEY (itemID) on items(ID)
)
With some initial item data:
insert into items (ID, name, description)
select 1, 'nails', 'Short piece of metal, with one flat side and one pointed side' union
select 2, 'hammer', 'Can be used to hit things, like nails' union
select 3, 'screws', 'I''m already tired of writing descriptions for simple tools' union
select 4, 'screwdriver', 'If you can''t tell already, this is all fake data' union
select 5, 'AHHHHHH', 'just for good measure'
And I have some code for creating a new task:
declare #taskDes varchar(100), #sTime datetime, #eTime datetime
select #taskDes = 'Assemble a bird house',
#sTime = '2011-01-05 12:00', #eTime = '2011-01-05 14:00'
declare #usedItems table(itemID int)
insert into #usedItems(itemID)
select 1 union
select 2
declare #newTask table(taskID int)
insert into tasks(description, sTimeUTC, eTimeUTC)
output inserted.ID into #newTask
values(#taskDes, #sTime, #eTime)
insert into taskItems(taskID, itemID)
select taskID, itemID
from #newTask
cross join #usedItems
Now, I want a way of simplifying/streamlining the creation of new tasks. My first thought was to use a stored proc, but table variables can't be used as inputs, so it won't work. I think I can do this with a view with an insert trigger, but I'm not sure... Is that my best (or only) option?
I have had great luck using XML to pass data to procedures. You can use OPENXML (Transact-SQL) to parse the XML.
-- You already had an example of #usedItems
-- declared and populated in the question
declare #usedItems table(itemID int)
insert into #usedItems(itemID)
select 1 union
select 2
-- Build some XML, either directly or from a query
-- Here I demonstrate using a query
declare #itemsXML nvarchar(max);
select #itemsXML =
'<Items>'
+ (select itemID from #usedItems as Item for xml auto)
+ '</Items>'
print #itemsXML
-- Pass #itemsXML to the stored procedure as nvarchar(max)
-- Inside the procedure, use OPENXML to turn the XML
-- back into a rows you can work with easily
DECLARE #idoc int
EXEC sp_xml_preparedocument #idoc OUTPUT, #itemsXML
SELECT *
FROM OPENXML (#idoc, '/Items/Item',1)
WITH (itemID int)
EXEC sp_xml_removedocument #idoc
Results
<Items><Item itemID="1"/><Item itemID="2"/></Items>
itemID
-----------
1
2