Must declare the scalar variable "#tabvar" - sql

declare #departmentid int;
set #departmentid = 1;
declare #tabvar table (id int, name nvarchar(100))
begin
insert into #tabvar
select DepartmentID, Name
from HumanResources.Department where DepartmentID = #departmentid;
print #tabvar
end
It shows
Must declare the scalar variable "#tabvar".

The problem is
print #tabvar.id
Remove this and the code will work.
The following is equivalent functionality:
print #departmentid;

Related

Why am I getting a syntax error in this procedure

CREATE PROCEDURE AssignRegular
#department AS INT,
#project AS VARCHAR(100),
#Employee AS VARCHAR(100)
AS
BEGIN
DECLARE #result AS INT
SELECT #result = COUNT(*)
FROM Managers_assign_Regular_Emplyee_Projects
WHERE regular_employee = #Employee
I am getting a syntax error near employee and don't know why
You're missing the END to match the BEGIN:
create proc AssignRegular
#department as int
,#project as varchar(100)
,#Employee as varchar(100)
as
BEGIN
Declare #result as int
select #result = count(*) from Managers_assign_Regular_Emplyee_Projects where regular_employee=#Employee
END
What is your error? I think this is the corrected:
create procedure AssignRegular
(
#department int
,#project varchar(100)
,#Employee varchar(100)
)
as
BEGIN
Declare #result int
select #result = count(*) from Managers_assign_Regular_Emplyee_Projects where regular_employee=#Employee
END
There could be a number of things wrong, spelling of the table name, etc. We don't have your schema to view or your table layout, etc.
But my guess would be that you forgot the END statement to match your BEGIN statement.

SQL Server: How to achieve re-usability yet flexibility in TSQL

I am using SQL Server 2008 R2. I am having some problems finding an effective coding pattern for SQL which supports code re-usability as well as flexibility. By re-usability, what I mean is keeping SQL queries in Stored Procedures and User Defined Functions.
Now, if I choose Stored Procedures, I will be sacrificing its usability in a query directly. If I choose User Defined Functions, I won't be able to use DML statements.
For example, suppose I created a Stored Procedures which inserts one contact record. Now, if I am having a table which can act as a source of multiple contact records, all I am left with are either WHILE loops or CURSORs, which is clearly not a recommended option, due to its performance drawbacks. And due to the fact that DML statements are not allowed in User Defined Functions, I simply cannot use them for this purpose.
Although, If I am not concerned with code re-usability, then instead of using Stored Procedures I can surely use same set of queries again and again to avoid while loops.
What pattern should I follow?
Here is a similar Stored Procedures:-
ALTER Proc [dbo].[InsertTranslationForCategory]
(
#str nvarchar(max),
#EventId int,
#CategoryName NVarchar(500),
#LanguageId int,
#DBCmdResponseCode Int Output,
#KeyIds nvarchar(max) Output
)as
BEGIN
DECLARE #XmlData XML
DECLARE #SystemCategoryId Int
DECLARE #CategoryId Int
Declare #Counter int=1
Declare #tempCount Int
Declare #IsExists int
Declare #TranslationToUpdate NVarchar(500)
Declare #EventName Varchar(200)
declare #Locale nvarchar(10)
declare #Code nvarchar(50)
declare #KeyName nvarchar(200)
declare #KeyValue nvarchar(500)
select #Locale=locale from languages where languageid = #LanguageId
SET #DBCmdResponseCode = 0
SET #KeyIds = ''
select #EventName = eventName from eventLanguages
where eventID = #EventId
--BEGIN TRY
Select #SystemCategoryId=CategoryId from SystemCategories where Name=rtrim(ltrim(#CategoryName))
Select #CategoryId=CategoryId from Categories where Name=rtrim(ltrim(#CategoryName)) and EventId=#EventId
if (#str='deactivate')
Begin
Delete from Codetranslation where CategoryId=#CategoryId
Update Categories set [Status]=0, Isfilter=0 where CategoryId=#CategoryId and Eventid=#EventId
Set #DBCmdResponseCode=2
return
End
set #XmlData=cast(#str as xml)
DECLARE #temp TABLE
(
Id int IDENTITY(1,1),
Code varchar(100),
Translation varchar(500),
CategoryId int
)
Insert into #temp (Code,Translation,CategoryId)
SELECT
tab.col.value('#Code', 'varchar(200)'),
tab.col.value('#Translation', 'varchar(500)'),#SystemCategoryId
FROM #XmlData.nodes('/Data') AS tab (col)
select #tempCount=Count(*) from #temp
if(IsNull(#CategoryId,0)>0)
Begin
While (#Counter <= #tempCount)
Begin
Select #IsExists= count(sc.categoryid) from #temp t Inner Join SystemCodetranslation sc
On sc.categoryid=t.CategoryId
where ltrim(rtrim(sc.code))=ltrim(rtrim(t.code)) and ltrim(rtrim(sc.ShortTranslation))=ltrim(rtrim(t.Translation))
and t.Id= #Counter
print #IsExists
Select #Code = Code , #KeyValue = Translation from #temp where id=#counter
set #KeyName = ltrim(rtrim(#EventName)) + '_' + ltrim(rtrim(#CategoryName)) + '_' + ltrim(rtrim(#Code)) + '_LT'
exec dbo.AddUpdateKeyValue #EventId,#Locale, #KeyName,#KeyValue,NULL,12
select #KeyIds = #KeyIds + convert(varchar(50),keyvalueId) + ',' from dbo.KeyValues
where eventid = #EventId and keyname = #KeyName and locale = #Locale
set #KeyName = ''
set #KeyValue = ''
Set #Counter= #Counter + 1
Set #IsExists=0
End
End
--- Inser data in Codetranslation table
if(isnull(#CategoryId,0)>0)
Begin
print #CategoryId
Delete from codetranslation where categoryid=#CategoryId
Insert into codetranslation (CategoryId,Code,LanguageId,ShortTranslation,LongTranslation,SortOrder)
SELECT
#CategoryId,
tab.col.value('#Code', 'varchar(200)'), #LanguageId,
tab.col.value('#Translation', 'varchar(500)'),
tab.col.value('#Translation', 'varchar(500)'),0
FROM #XmlData.nodes('/Data') AS tab (col)
Update Categories set [Status]=1 where CategoryId=#CategoryId and Eventid=#EventId
End
Set #DBCmdResponseCode=1
set #KeyIds = left(#KeyIds,len(#KeyIds)-1)
END
You can use table variable parameter for your user defined functions.
following code is an example of using table variable parameter in stored procedure.
CREATE TYPE IdList AS TABLE (Id INT)
CREATE PROCEDURE test
#Ids dbo.IdList READONLY
AS
Select *
From YourTable
Where YourTable.Id in (Select Id From #Ids)
End
GO
In order to execute your stored procedure use following format:
Declare #Ids dbo.IdList
Insert into #Ids(Id) values(1),(2),(3)
Execute dbo.test #Ids
Edit
In order to return Inserted Id, I don't use from Table Variable Parameter. I use following query sample for this purpose.
--CREATE TYPE NameList AS TABLE (Name NVarChar(100))
CREATE PROCEDURE test
#Names dbo.NameList READONLY
AS
Declare #T Table(Id Int)
Insert Into YourTable (Name)
OUTPUT Inserted.Id Into #T
Select Name
From #Names
Select * From #T
End
GO

How to use SQL Variables inside a query ( SQL Server )?

I have written the following SQL Stored Procedure, and it keeps giving me the error at
#pid = SELECT MAX(... The whole procedure is:
Alter PROCEDURE insert_partyco
#pname varchar(200)
AS
BEGIN
DECLARE #pid varchar(200);
#pid = SELECT MAX(party_id)+1 FROM PARTY;
INSERT INTO party(party_id, name) VALUES(#pid, #pname)
SELECT SCOPE_IDENTITY() as PARTY_ID
END
GO
Can anyone please tell me what I'm doing wrong here?
Alter PROCEDURE insert_partyco
#pname varchar(200)
AS
BEGIN
DECLARE #pid varchar(200);
SELECT #pid = MAX(party_id)+1 FROM PARTY;
INSERT INTO party(party_id, name) VALUES(#pid, #pname)
SELECT SCOPE_IDENTITY() as PARTY_ID
END
This has an advantage over SET with SELECT in that you can select expressions in multiple variables in one statement:
SELECT #var1 = exp1, #var2 = expr2 ... etc
declare #total int
select #total = count(*) from news;
select * from news where newsid = #total+2
//**news** table name and **newsid** column name
You need to use SET.
Alter PROCEDURE insert_partyco
#pname varchar(200)
AS
BEGIN
DECLARE #pid varchar(200);
SET #pid = (SELECT MAX(party_id)+1 FROM PARTY);
INSERT INTO party(party_id, name) VALUES(#pid, #pname)
SELECT SCOPE_IDENTITY() as PARTY_ID
END
GO
Alternatively, in your case you could make party_id an autoincremented value, so you wouldn't need to query the table.

How to return the output of stored procedure into a variable in sql server

I want to execute a stored procedure in SQL Server and assign the output to a variable (it returns a single value) ?
That depends on the nature of the information you want to return.
If it is a single integer value, you can use the return statement
create proc myproc
as
begin
return 1
end
go
declare #i int
exec #i = myproc
If you have a non integer value, or a number of scalar values, you can use output parameters
create proc myproc
#a int output,
#b varchar(50) output
as
begin
select #a = 1, #b='hello'
end
go
declare #i int, #j varchar(50)
exec myproc #i output, #j output
If you want to return a dataset, you can use insert exec
create proc myproc
as
begin
select name from sysobjects
end
go
declare #t table (name varchar(100))
insert #t (name)
exec myproc
You can even return a cursor but that's just horrid so I shan't give an example :)
You can use the return statement inside a stored procedure to return an integer status code (and only of integer type). By convention a return value of zero is used for success.
If no return is explicitly set, then the stored procedure returns zero.
CREATE PROCEDURE GetImmediateManager
#employeeID INT,
#managerID INT OUTPUT
AS
BEGIN
SELECT #managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = #employeeID
if ##rowcount = 0 -- manager not found?
return 1;
END
And you call it this way:
DECLARE #return_status int;
DECLARE #managerID int;
EXEC #return_status = GetImmediateManager 2, #managerID output;
if #return_status = 1
print N'Immediate manager not found!';
else
print N'ManagerID is ' + #managerID;
go
You should use the return value for status codes only. To return data, you should use output parameters.
If you want to return a dataset, then use an output parameter of type cursor.
more on RETURN statement
Use this code, Working properly
CREATE PROCEDURE [dbo].[sp_delete_item]
#ItemId int = 0
#status bit OUT
AS
Begin
DECLARE #cnt int;
DECLARE #status int =0;
SET NOCOUNT OFF
SELECT #cnt =COUNT(Id) from ItemTransaction where ItemId = #ItemId
if(#cnt = 1)
Begin
return #status;
End
else
Begin
SET #status =1;
return #status;
End
END
Execute SP
DECLARE #statuss bit;
EXECUTE [dbo].[sp_delete_item] 6, #statuss output;
PRINT #statuss;
With the Return statement from the proc, I needed to assign the temp variable and pass it to another stored procedure. The value was getting assigned fine but when passing it as a parameter, it lost the value. I had to create a temp table and set the variable from the table (SQL 2008)
From this:
declare #anID int
exec #anID = dbo.StoredProc_Fetch #ID, #anotherID, #finalID
exec dbo.ADifferentStoredProc #anID (no value here)
To this:
declare #t table(id int)
declare #anID int
insert into #t exec dbo.StoredProc_Fetch #ID, #anotherID, #finalID
set #anID= (select Top 1 * from #t)

How to assign an exec result to a sql variable?

How do you assign the result of an exec call to a variable in SQL? I have a stored proc called up_GetBusinessDay, which returns a single date.
Can you do something like this:
exec #PreviousBusinessDay = dbo.up_GetBusinessDay #Date, -1
I always use the return value to pass back error status. If you need to pass back one value I'd use an output parameter.
sample stored procedure, with an OUTPUT parameter:
CREATE PROCEDURE YourStoredProcedure
(
#Param1 int
,#Param2 varchar(5)
,#Param3 datetime OUTPUT
)
AS
IF ISNULL(#Param1,0)>5
BEGIN
SET #Param3=GETDATE()
END
ELSE
BEGIN
SET #Param3='1/1/2010'
END
RETURN 0
GO
call to the stored procedure, with an OUTPUT parameter:
DECLARE #OutputParameter datetime
,#ReturnValue int
EXEC #ReturnValue=YourStoredProcedure 1,null, #OutputParameter OUTPUT
PRINT #ReturnValue
PRINT CONVERT(char(23),#OutputParameter ,121)
OUTPUT:
0
2010-01-01 00:00:00.000
This will work if you wish to simply return an integer:
DECLARE #ResultForPos INT
EXEC #ResultForPos = storedprocedureName 'InputParameter'
SELECT #ResultForPos
declare #EventId int
CREATE TABLE #EventId (EventId int)
insert into #EventId exec rptInputEventId
set #EventId = (select * from #EventId)
drop table #EventId
From the documentation (assuming that you use SQL-Server):
USE AdventureWorks;
GO
DECLARE #returnstatus nvarchar(15);
SET #returnstatus = NULL;
EXEC #returnstatus = dbo.ufnGetSalesOrderStatusText #Status = 2;
PRINT #returnstatus;
GO
So yes, it should work that way.
I had the same question. While there are good answers here I decided to create a table-valued function. With a table (or scalar) valued function you don't have to change your stored proc. I simply did a select from the table-valued function. Note that the parameter (MyParameter is optional).
CREATE FUNCTION [dbo].[MyDateFunction]
(#MyParameter varchar(max))
RETURNS TABLE
AS
RETURN
(
--- Query your table or view or whatever and select the results.
SELECT DateValue FROM MyTable WHERE ID = #MyParameter;
)
To assign to your variable you simply can do something like:
Declare #MyDate datetime;
SET #MyDate = (SELECT DateValue FROM MyDateFunction(#MyParameter));
You can also use a scalar valued function:
CREATE FUNCTION TestDateFunction()
RETURNS datetime
BEGIN
RETURN (SELECT GetDate());
END
Then you can simply do
Declare #MyDate datetime;
SET #MyDate = (Select dbo.TestDateFunction());
SELECT #MyDate;
Here is solution for dynamic queries.
For example if you have more tables with different suffix:
dbo.SOMETHINGTABLE_ONE, dbo.SOMETHINGTABLE_TWO
Code:
DECLARE #INDEX AS NVARCHAR(20)
DECLARE #CheckVALUE AS NVARCHAR(max) = 'SELECT COUNT(SOMETHING) FROM
dbo.SOMETHINGTABLE_'+#INDEX+''
DECLARE #tempTable Table (TempVALUE int)
DECLARE #RESULTVAL INT
INSERT INTO #tempTable
EXEC sp_executesql #CheckVALUE
SET #RESULTVAL = (SELECT * FROM #tempTable)
DELETE #tempTable
SELECT #RESULTVAL
You can use a Table Variable for that
Code:
DECLARE #PreviousBusinessDay DATETIME
DECLARE #Temp TABLE(BusinessDay DATETIME)
INSERT INTO #Temp EXEC dbo.up_GetBusinessDay #Date, -1
SET #PreviousBusinessDay = (SELECT * FROM #Temp)
SELECT #PreviousBusinessDay
https://www.sqlservertutorial.net/sql-server-user-defined-functions/sql-server-table-variables/