Table variable error: Must declare the scalar variable "#temp" - sql-server

I am trying to achieve:
declare #TEMP table (ID int, Name varchar(max))
insert into #temp SELECT ID, Name FROM Table
SELECT * FROM #TEMP
WHERE #TEMP.ID = 1 <--- ERROR AT #TEMP.ID
But I'm getting the following error:
Must declare the scalar variable "#temp".
What am I doing wrong?

A table alias cannot start with a #. So, give #Temp another alias (or leave out the two-part naming altogether):
SELECT *
FROM #TEMP t
WHERE t.ID = 1;
Also, a single equals sign is traditionally used in SQL for a comparison.

Either use an Allias in the table like T and use T.ID, or use just the column name.
declare #TEMP table (ID int, Name varchar(max))
insert into #temp SELECT ID, Name FROM Table
SELECT * FROM #TEMP
WHERE ID = 1

There is one another method of temp table
create table #TempTable (
ID int,
name varchar(max)
)
insert into #TempTable (ID,name)
Select ID,Name
from Table
SELECT *
FROM #TempTable
WHERE ID = 1
Make Sure You are selecting the right database.

If you bracket the # you can use it directly
declare #TEMP table (ID int, Name varchar(max))
insert into #temp values (1,'one'), (2,'two')
SELECT * FROM #TEMP
WHERE [#TEMP].[ID] = 1

You should use hash (#) tables, That you actually looking for because variables value will remain till that execution only.
e.g. -
declare #TEMP table (ID int, Name varchar(max))
insert into #temp SELECT ID, Name FROM Table
When above two and below two statements execute separately.
SELECT * FROM #TEMP
WHERE #TEMP.ID = 1
The error will show because the value of variable lost when you execute the batch of query second time.
It definitely gives o/p when you run an entire block of code.
The hash table is the best possible option for storing and retrieving the temporary value. It last long till the parent session is alive.

try the following query:
SELECT ID,
Name
INTO #tempTable
FROM Table
SELECT *
FROM #tempTable
WHERE ID = 1
It doesn't need to declare table.

You could stil use #TEMP if you quote the identifier "#TEMP":
declare #TEMP table (ID int, Name varchar(max));
insert into #temp SELECT 1 AS ID, 'a' Name;
SELECT * FROM #TEMP WHERE "#TEMP".ID = 1 ;
db<>fiddle demo

You've declared #TEMP but in your insert statement used #temp. Case sensitive variable names.
Change #temp to #TEMP

Related

Adding constraints to list items in SQL Server database

I have table holding items for a given list id in my Ms Sql server database (2008R2).
I would like to add constraints so that no two list ids have same item list. Below illustrate my schema.
ListID , ItemID
1 a
1 b
2 a
3 a
3 b
In above example ListID 3 should fail. I guess you can't put constarint/check within the database itself (Triggers,check) and the logic constaint can only be done from the frontend?
Thanks in advance for any help.
Create a function that performs the logic you want and then create a check constraint or index that leverages that function.
Here is a functional example, the final insert fails. The function is evaluated row by row, so if you need to insert as a set and evaluate after, you'd need to do an "instead of" trigger:
CREATE TABLE dbo.Test(ListID INT, ItemID CHAR(1))
GO
CREATE FUNCTION dbo.TestConstraintPassed(#ListID INT, #ItemID CHAR(1))
RETURNS TINYINT
AS
BEGIN
DECLARE #retVal TINYINT = 0;
DECLARE #data TABLE (ListID INT, ItemID CHAR(1),[Match] INT)
INSERT INTO #data(ListID,ItemID,[Match]) SELECT ListID,ItemID,-1 AS [Match] FROM dbo.Test
UPDATE #data
SET [Match]=1
WHERE ItemID IN (SELECT ItemID FROM #data WHERE ListID=#ListID)
DECLARE #MatchCount INT
SELECT #MatchCount=SUM([Match]) FROM #data WHERE ListID=#ListID
IF NOT EXISTS(
SELECT *
FROM (
SELECT ListID,SUM([Match]) AS [MatchCount]
FROM #data
WHERE ListID<>#ListID
GROUP BY ListID
) dat
WHERE #MatchCount=[MatchCount]
)
BEGIN
SET #retVal=1;
END
RETURN #retVal;
END
GO
ALTER TABLE dbo.Test
ADD CONSTRAINT chkTest
CHECK (dbo.TestConstraintPassed(ListID, ItemID) = 1);
GO
INSERT INTO dbo.Test(ListID,ItemID) SELECT 1,'a'
INSERT INTO dbo.Test(ListID,ItemID) SELECT 1,'b'
INSERT INTO dbo.Test(ListID,ItemID) SELECT 2,'a'
INSERT INTO dbo.Test(ListID,ItemID) SELECT 2,'b'
Related

How to store the result of an select statement into a variable in sql server stored procedure

I have a condition like this:
IF #aaa = 'high'
set #bbb = select * from table1
else
set #bbb = select * from table2
I am going to use this variable (#bbb) throughout my stored procedure
is this possible to save a table into a variable?
I tried using temporary table but i am not able to assign it twice.
IF #aaa = 'high'
set #bbb = select * into #temp from table1
else
set #bbb = select * into #temp from table2
it shows #temp is already declared.
No, It is not work like that. You can declare a table variable and insert into inside it.
DECLARE #bbbTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
insert into #bbbTable (Id,SampleColumn)
select Id,SampleColumn from table1
If the table1 and table2 are completely different tables, you should declare two different table variable;
DECLARE #bbbTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
DECLARE #aaaTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
IF #aaa = 'high'
insert into #bbbTable (Id,SampleColumn)
select Id,SampleColumn from table1
else
insert into #aaaTable (Id,SampleColumn)
select Id,SampleColumn from table2
You cant insert into a variable more than 1 value.
you can use Table Variable to reach your answer like this:
DELCARE #TableResult AS TABLE (Column1 INT, Column2 INT)
IF #aaa = 'high'
BEGIN
INSERT INTO #TableResult (Column1,Column2)
SELECT Column1FromTable, Column2FromTable
FROM table1
END
ELSE
BEGIN
INSERT INTO #TableResult (Column1,Column2)
SELECT Column1FromTable, Column2FromTable
FROM table2
END
Of course you can declare more than 2 columns.
You can store only 1 Column/Row to a variable.So you can't say *.
Suppose I want to store the value of Column1 from TableA to a variable, I can use this
SELECT #MyVariable = Column1 FROM TableA
But I Can't Say
SELECT #MyVariable = * FROM TableA
Even if there is only 1 column in the Table TableA.
Also If there is more than 1 record returned by the Select condition, then it will assign the First value to the Variable.
Or What you need is to store the entire Rows, you can Either use a Temporary table or a table variable.
Temporary Table
SELECT * INTO #Temp FROM TableA
Table Variable
DECLARE #MyVarTable TABLE
(
Column1 VARCHAR(50),
Column2 VARCHAR(50)
)
INSERT INTO #MyVarTable
(
Column1 ,
Column2
)
SELECT
Column1 ,
Column2
From MyTable
This Temporary Table and Table variable can be accessed in the same way you access the normal table using SELECT/UPDATE/DELETE Queries. Except :
Temporary tables are created for each session and automatically dropped when the session ends or the Query window is Closed
Table Variables exists only when you execute the Query. So before using the table variable in a query you need to declare the same

Creating a temporary table within a TRIGGER with GROUP BY

I need to create and use a temporary table with GROUP BY clause within a trigger, but I'm having difficulties doing so.
My attempt:
Here I'm trying to use two temporary tables which are dropped after the trigger reach an end.
First I create a #Temptable and the trigger.
CREATE TABLE #TempTable (admID smallint, diagID smallint);
CREATE TRIGGER tr_newTest
ON Adm_Diag
FOR INSERT
AS
BEGIN
...
END
Since the table inserted only contains rows for a current INSERT and UPDATE statements I'm passing several INSERT and UPDATE statements to #TempTable.
DECLARE #admID smallint
SELECT #admID = Adm_ID
FROM inserted
DECLARE #diagID smallint
SELECT #diagID=Diag_ID
FROM inserted
INSERT INTO #TempTable VALUES (#admID, #diagID)
Now with this data I want to create a temporary table that groups the rows of #TempTable:
SELECT *
INTO #TempGroupTable
FROM
(
SELECT admID, COUNT(*) as Diag
FROM #TempTable
GROUP BY admID
) t1
WHERE Diag > 2
The whole script
CREATE TABLE #TempTable (admID smallint, diagID smallint);
CREATE TRIGGER tr_newTest
ON Adm_Diag
FOR INSERT
AS
BEGIN
DECLARE #admID smallint
SELECT #admID = Adm_ID
FROM inserted
DECLARE #diagID smallint
SELECT #diagID=Diag_ID
FROM inserted
INSERT INTO #TempTable VALUES (#admID, #diagID)
-- Below I'm tring to create #TempGroupTable
SELECT *
INTO #TempGroupTable
FROM
(
SELECT admID, COUNT(*) as Diag
FROM #TempTable
GROUP BY admID
) t1
WHERE Diag > 2
END
After executing the trigger I get an error:
Msg 208, Level 16, State 0, Line 41 Invalid object name
'#TempGroupTable'.
How can I create #TempGroupTable?
Not quote sure what you are trying to do but would a global temporary tables which starts with ## work for you? So make the #TempGroupTable into ##TempGroupTable?
Why not dispense with all the overhead of temp tables and variables? Try:
CREATE TRIGGER tr_newTest
ON Adm_Diag
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO Adm_Diag (adminID, Diag)
SELECT admID, COUNT(*) as Diag
FROM inserted
GROUP BY admID
END

Converting arithmetic formula in a string into a values

I have a table in which all entries are in form of arithmetic formulas (i.e. 1+2+3 etc).
In this table all columns are of type varchar. The table has many columns like this.
I want to calculate formula and insert the values into another. Any suggestions on how to achieve this?
You can try this. I hope this can assist you. It takes expression from t1 and put the result in t2. You won't want to make t1 the actual table as it deletes from the table, so you can copy the actual table value to a temp table
declare #t as table(val varchar(20))
declare #t2 as table(val varchar(20))
insert into #t values
('1+3'),
('2*3'),
('9+3*2')
declare #exp varchar(20)
while(exists(select 1 from #t))
begin
select top(1) #exp = val from #t
insert into #t2
exec ('select '+#exp)
delete top (1) from #t
end
select * from #t2
Result
val
------
4
6
15
You can check these links Similar question here and Convert string with expression to decimal
Follow the link -
Convert string with expression to decimal
After you create function DBO.EVAL , just Run :-
select dbo.eval(column_name) from table_name;
You can declare two table variables:
#tabformula in which will be stored the formulas
#tabresult in which will stored the results
There is an ID column that will be used for joining the two tables.
After filling the first table with the required formulas, you declare a cursor, and then you execute the formula and store the result into the #tabresult table.
declare #tabformula as table (id int identity(1,1), formula
varchar(200)) declare #tabresult as table (id int, result int)
insert into #tabformula(formula) values('1+4+6+7') ;
insert into #tabformula(formula) values('10+4+60+7');
insert into #tabformula(formula) values('1+4+6+70') ;
insert into #tabformula(formula) values('1+44+65+7');
declare c cursor for select ID,formula from #tabformula declare #id as
int declare #formula as varchar(200)
open c fetch c into #id,#formula while ##fetch_status=0 begin print
#formula insert into #tabresult (id,result) exec( 'select '+ #id +
','+#formula ) fetch c into #id,#formula end close c deallocate c
select T1.id,t1.formula,T2.result from #tabformula t1 inner join
#tabresult t2 on t1.id=t2.id

contains search over a table variable or a temp table

i'm trying to concatenate several columns from a persistent table into one column of a table variable, so that i can run a contains("foo" and "bar") and get a result even if foo is not in the same column as bar.
however, it isn't possible to create a unique index on a table variable, hence no fulltext index to run a contains.
is there a way to, dynamically, concatenate several columns and run a contains on them? here's an example:
declare #t0 table
(
id uniqueidentifier not null,
search_text varchar(max)
)
declare #t1 table ( id uniqueidentifier )
insert into
#t0 (id, search_text)
select
id,
foo + bar
from
description_table
insert into
#t1
select
id
from
#t0
where
contains( search_text, '"c++*" AND "programming*"' )
You cannot use CONTAINS on a table that has not been configured to use Full Text Indexing, and that cannot be applied to table variables.
If you want to use CONTAINS (as opposed to the less flexible PATINDEX) you will need to base the whole query on a table with a FT index.
You can't use full text indexing on a table variable but you can apply the full text parser. Would something like this do what you need?
declare #d table
(
id int identity(1,1),
testing varchar(1000)
)
INSERT INTO #D VALUES ('c++ programming')
INSERT INTO #D VALUES ('c# programming')
INSERT INTO #D VALUES ('c++ books')
SELECT id
FROM #D
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(testing,'"','""') + '"', 1033, 0,0)
where display_term in ('c++','programming')
GROUP BY id
HAVING COUNT(DISTINCT display_term)=2
NB: There might well be a better way of using the parser but I couldn't quite figure it out. Details of it are at this link
declare #table table
(
id int,
fname varchar(50)
)
insert into #table select 1, 'Adam James Will'
insert into #table select 1, 'Jain William'
insert into #table select 1, 'Bob Rob James'
select * from #table where fname like '%ja%' and fname like '%wi%'
Is it something like this.

Resources