Getting multi-part identifier "column name" could not be bound error in SQL Server of newer version - sql

I have this code for my stored procedure:
create or alter procedure udpReservationFilter
#FName nvarchar(160),
#LName nvarchar(160),
#Category nvarchar(160),
#Number int,
#TotalCount int OUT,
#ColumnName nvarchar(100) = 'M.Id',
#SortDesc bit = 0,
#Page int = 1,
#PageSize int = 2
as
begin
declare #sqlWhere nvarchar(max) = ''
declare #whereParams nvarchar(1000) = N' #FName nvarchar(160),
#LName nvarchar(160),
#Category nvarchar(160),
#Number int, #OffsetRows int, #PageSize int'
declare #countParams nvarchar(1000) = N' #FName nvarchar(160),
#LName nvarchar(160),
#Category nvarchar(160),
#Number int,
#TotalCount int OUT'
if len(trim(#FName)) > 0
set #sqlWhere += ' AND c.FName like ''%'' + #FName + ''%'' '
if len(trim(#LName)) > 0
set #sqlWhere += ' AND c.LName like #LName '
if len(trim(#Category))> 0
set #sqlWhere += ' AND r.Category like #Category '
if (#Number > 0)
set #sqlWhere += ' AND r.Number = #Number '
---------------- counting total results -------------------
declare #sqlCount nvarchar(1000) = N' select #TotalCount = count(*) from Reservations M '
if len(#sqlWhere) > 0
set #sqlCount = #sqlCount + ' where ' + (SUBSTRING(#sqlWhere, 5 , 60))
exec sp_executesql #sqlCount,
#countParams,
#FName = #FName,
#LName = #LName,
#Category = #Category,
#Number = #Number,
#TotalCount = #TotalCount OUT
declare #sql nvarchar(max) = N' select M.*, c.*, r.Category, r.Number, r.Price, r.Status
from Reservations M, Client c, Rooms r
where M.ClientId=c.ID and M.RoomId=r.Id'
+ #sqlWhere
+ ' order by ' + #ColumnName
+ ' offset #OffsetRows rows fetch next #PageSize rows only'
--M.*, c.*, r.Number, r.category, r.Price, r.status
declare #Offset int = (#Page-1)*#PageSize
if #Offset < 0
set #Offset = 0
exec sp_executesql #sql,
#whereParams,
#FName = #FName,
#LName =#LName,
#Category = #Category,
#Number = #Number,
#OffsetRows = #Offset,
#PageSize = #PageSize
end
I'm getting this error:
The multi-part identifier "column_name" could not be bound.
when executing the query.
declare #cnt int
exec udpReservationFilter
#FName = null,
#LName = null,
#Category = null,
#Number = null,
#TotalCount = #cnt OUT,
#PageSize = 3
When I provide parameters it is above error and gives the matched result this error stops my asp.net core app and if there is no parameters provided its compiling without error
Here is more detailed error :
Msg 4104, Level 16, State 1, Line 5
The multi-part identifier "c.FName" could not be bound.
(1 row affected)

Related

Dynamic SQL - parametrized query

I use dynamic sql with parameters and have problem :)
In block of code it works, but when I call procedure I have error that I need to declare scalar variable #name_dummy
So:
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT
o.SCHEMA_N
,o.TABLE_N
,o.Condition
,o.TargetDB
,o.SourceDB
,STUFF((SELECT
', ' + c.name
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH (''))
, 1, 1, '')
FROM Table_A o
ORDER BY 1,
2
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = ( SELECT CAST(Wartosc AS VARCHAR) FROM Table_B WHERE Id = 3 )
IF #TOP < 40000
SET #TOP = 40000
WHILE ( 1 = 1 )
BEGIN
DECLARE #CHECK BIT = 0
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM '
+ #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
SELECT #sqlCMD , #CHECK
END
END
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
CLOSE KUR;
DEALLOCATE KUR
And when I execute this it's compiling and works ( returns values ) for example sql which I want to execute.
SELECT TOP 1 #check_exists = 1 FROM MSSF15_WarstwaPosrednia.KatalogZdarzen.MSSF_RaportZdarzenPLKB2CS2K WHERE StatusPrzetwarzania = 4 AND DataWpisu < DATEADD(MONTH, -3, #START_TIME)
Parameters work here ( #check_exists which is output and #START_TIME condition param ) , but when I execute this in procedure I'm getting error
Must declare the scalar variable "#START_TIME". 137
SP definition:
USE xxxx
/****** Object: StoredProcedure dbo.dummy Script Date: 06/09/2018 13:40:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE dbo.dummy
AS
BEGIN
/*
PRZENIESIENIE DANYCH
*/
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT o.SCHEMA_N,
o.TABLE_N,
o.Condition,
o.TargetDB,
o.SourceDB,
STUFF((
SELECT ', ' + c.NAME
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH('')
), 1, 1, '')
FROM dbo.Table_A o
ORDER BY 1,
2
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = (
SELECT CAST(Wartosc AS VARCHAR)
FROM dbo.Table_B
WHERE Id = 3
)
IF #TOP < 40000
SET #TOP = 40000
WHILE (1 = 1)
BEGIN
BEGIN TRY
BEGIN TRANSACTION T_TEST
DECLARE #CHECK BIT = 0
DECLARE #START_TIME_P DATE = GETDATE()
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
SELECT #CHECK,
#START_TIME_P,
#sqlCMD
EXEC sp_executesql #sqlCMD,
N'#check_exists bit OUTPUT, #START_TIME DATE',
#check_exists = #CHECK OUTPUT,
#START_TIME = #START_TIME_P;
IF OBJECT_ID('tempdb..#TMP_ID') IS NOT NULL
DROP TABLE #TMP_ID
CREATE TABLE #TMP_ID (Id INT)
EXEC (
'INSERT INTO #TMP_ID
SELECT TOP ' + #TOP + ' Id
FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
)
DECLARE #sqlCMD_Ins NVARCHAR(MAX)
SET #sqlCMD_Ins = 'INSERT INTO ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' '
SET #sqlCMD_Ins = #sqlCMD_Ins + 'SELECT ' + #COLUMN_LIST + ' FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Ins IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Ins)
DECLARE #sqlCMD_Del NVARCHAR(MAX)
SET #sqlCMD_Del = 'DELETE FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Del IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Del)
DROP TABLE #TMP_ID
COMMIT TRANSACTION T_TEST
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION T_TEST
PRINT 'Wycofanie zmian'
PRINT ERROR_MESSAGE() + ' ' + CAST(ERROR_NUMBER() AS VARCHAR(256))
END
END CATCH
IF #CHECK = 0
BREAK
END
EXEC ('SELECT ''' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' UNION ALL ' + 'SELECT ''' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N)
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
END
CLOSE KUR;
DEALLOCATE KUR;
DECLARE #END_TIME DATETIME = GETDATE()
SELECT 'Daty przetworzenia',
#START_TIME_P AS 'START',
#END_TIME AS 'END'
SELECT 'Czas (min)',
DATEDIFF(MINUTE, #START_TIME_P, #END_TIME)
END
Guys, maybe u have similar situation and can help.
Error msg
Wycofanie zmian
Must declare the scalar variable "#START_TIME". 137
Thanks
Instead of
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
try
declare #date_in DATE = GETDATE()
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #date_in;

Error Pass from nested MSSQL procedure to parent procedure

I have one parent stored procedure and one nested stored procedure. Parent Stored procedure calls the nested stored procedure on loop. Now when there is certain condition matches I have raised the error. When this error is raised I want to stop all the process and return the error.
CREATE Proc [dbo].[Usp_GenSalarySheet](#SalData [HRM].UTDT_SalaryData ReadOnly)
AS
set nocount on
DECLARE #SMT NVARCHAR(MAX)
SET #SMT = 'Create Table ##SalarySheet (StaffID INT,FullName NVARCHAR(1024),PresentDays NVARCHAR(1024),Absent NVARCHAR(1024),Department NVARCHAR(1024),Designation NVARCHAR(1024),'
DECLARE #HopName nvarchar(max)
Declare HOPCursor cursor for select ID from HRM.tbl_HOP
OPEN HOPCursor
FETCH NEXT FROM HOPCursor INTO #HopName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SMT = #SMT + ' [' + #HopName + '] DECIMAL(19,7),'
FETCH NEXT FROM HOPCursor into #HopName
END
SET #SMT = #SMT + '[Total] DECIMAL(19,7))'
CLOSE HOPCursor
DEALLOCATE HOPCursor
print (#smt)
exec (#SMT)
select * into #temp from #SalData
Declare #TopID INT
While (Select Count(*) From #Temp) > 0
Begin
Select Top 1 #TopID = StaffID From #temp
Declare #StaffID INT =(select top 1 StaffID from #temp)
Declare #StaffName NVARCHAR(1024) = (SELECT TOP 1 FullName FROM #temp)
Declare #WorkingDays Int = (SELECT top 1 WorkingDays from #temp)
Declare #Leave INT = (SELECT top 1 [Absent] from #temp)
INSERT INTO ##SalarySheet(StaffID,FullName,[Absent]) values(#StaffID,#StaffName,#Leave)
DECLARE #HOPType INT
DECLARE #Value Decimal(19,7)
DECLARE #CalcVal DECIMAL(19,7) = 0
DECLARE #Formula NVARCHAR(MAX)
DECLARE #Total DECIMAL(19,7)
DECLARE #PayEvery INT
DECLARE #Round Int
Declare HOPList Cursor for SELECT ID,HOPType,Value,Formula,RoundOff,PayEvery FROM HRM.Tbl_HOP order by Schedule
open HOPList
FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery
WHILE ##FETCH_STATUS = 0
BEGIN
if exists(select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = #StaffID and HOPID = #HopName)
print('select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = ' + convert(varchar(max), #StaffID) + ' and HOPID =' + convert(varchar(max),#HopName))
begin
if(#HOPType=51)
begin
exec HRM.Usp_GetSalaryValueFromFormula #StaffID,#Formula,#HOPType,#Leave,#WorkingDays,#Value output
set #HOPType= 50
end
if(#HOPType=50)
begin
set #CalcVal = #value
END
IF(#HOPType=38)
BEGIN
SET #CalcVal = #Value - ((#Value/#WorkingDays) * #Leave)
END
if(#PayEvery= 40)
begin
set #CalcVal = ((#CalcVal * #WorkingDays) - (#CalcVal * #Leave))
end
if(#Round = 45)
begin
set #CalcVal = round(#CalcVal,2)
end
else if(#Round = 46)
begin
set #CalcVal = CEILING(#CalcVal)
end
else if(#Round = 47)
begin
set #CalcVal = FLOOR(#CalcVal)
end
set #SMT ='UPDATE ##SalarySheet SET [' + #HopName + '] = ' + cast(#CalcVal as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max))
exec (#smt)
end
SET #CalcVal = 0
FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery
END
close HOPList
DEALLOCATE HOPList
set #SMT ='UPDATE ##SalarySheet SET [Total] = ' + cast(#Total as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max))
exec (#smt)
Delete #temp Where StaffID = #TopID
end
select * from ##SalarySheet
drop table ##SalarySheet
This is my parent Stored Procudere and nested procedure is as follow:
CREATE proc [HRM].[Usp_GetSalaryValueFromFormula](#StaffID INT,#val nvarchar(max),#HOPType INT,#Leave INT,#WorkingDays INT, #GetResult Decimal(19,7) output)
as
set nocount on
Declare #Formula Varchar(max)
declare #initial INT =0
declare #final INT =0
Declare #DataVal NVARCHAR(MAX) -- set the value from HOP table
declare #FieldVal nvarchar(max)
declare #cnt int = 0
Declare #Complete Int =CHARINDEX ('[',#val,0)
while (#Complete <> 0)
begin
set #initial = CHARINDEX ('[',#val,0)
set #final = CHARINDEX(']',#val,0)
set #FieldVal = SUBSTRING(#val,#initial,(#final-#initial) + 1)
if len(#FieldVal)<>0
begin
select #HOPType = HOPType, #DataVal= ( case when HOPType = 51 then [Formula] else cast([Value] as nvarchar(max)) end) from HRM.Tbl_ContractHOPDetails where PersonalDetailsID = #StaffID and HOPID in(select ID from HRM.tbl_HOP where HOPName = replace(replace(#fieldVal,'[',''),']',''))
if (#DataVal is null or #DataVal ='')
begin
RAISERROR ('Nested HOP is not defined.',11,1)
RETURN
end
print(#DataVal)
if ISNUMERIC(#DataVal)=1
begin
if(#HOPType = 38)
begin
SET #DataVal = cast(#DataVal as decimal(19,7)) - ((cast(#DataVal as decimal(19,7))/#WorkingDays) * #Leave)
end
end
set #val = replace(#val,#fieldVal,#DataVal)
set #fieldVal= ''
set #DataVal = ''
end
set #Complete = CHARINDEX ('[',#val,0)
set #fieldVal =''
set #final =0
set #initial = 0
end
SET #Complete =CHARINDEX ('{',#val,0)
while (#Complete <> 0)
BEGIN
set #initial = CHARINDEX ('{',#val,0)
set #final = CHARINDEX('}',#val,0)
set #FieldVal = SUBSTRING(#val,#initial+1,(#final-#initial)-1)
if len(#FieldVal)<>0
begin
set #DataVal = isnumeric((SELECT 0 FROM [HRM].Tbl_StaffTag where CValue = #FieldVal and StaffID = #StaffID))
set #FieldVal = '{' + #FieldVal + '}'
set #val = replace(#val,#fieldVal,#DataVal)
set #fieldVal= ''
set #DataVal = ''
end
set #Complete = CHARINDEX ('{',#val,0)
set #final =0
set #initial = 0
END
DECLARE #RetrunVal DECIMAL(19,7)
declare #ParmDefinition Nvarchar(512) = '#GetVal decimal(19,7) OUTPUT'
Declare #SMT NVARCHAR(MAX) = ' SET #GetVal = ' + #val
EXECUTE sp_executeSQL #Smt, #ParmDefinition, #GetVal =#RetrunVal OUTPUT
set #GetResult = #RetrunVal
But in current situation it raises error and again from the main procedure it runs next step of loop. But I want to terminate the complete process after this raiserror
Kindly help me
My guess is that RaiseError throws the control back to the caller, which might make the Return statement unreachable. The caller (loop) continues with next iteration.

How to split and replace with stored procedure?

I want to replace all e_Mail column where in #tablename with my users table (my main table).
For example:
#tablename
[name] [eMail] // columns
------------------------------------------------------
name surname blahblah#gmail.com
My users table
[name] [eMail]
----------------------------------------
name surname blahblah#hotmail.com
I want to update this row's eMail column as 'blahblah#hotmail.com' in #tablename.
What will procedure do?
1- Get first value of eMail column from #tablename
2- Split value (split char: #) and get first value (for example, if value blahblah#gmail.com, get gmail.com)
3- Search first value in users table
4- When the find value in users table, (Code must find blahblah#hotmail.com) Update eMail as blahblah#hotmail.com in #tablename
5- Get second value of eMail column from #tablename
.
.
.
So, I write a stored procedure. But this procedure is not working. Where is the problem?
Create Proc update_eMail
(#tablename nvarchar(50),
#columnname nvarchar(50))
AS
Begin
Declare #get_oldeMail nvarchar(100)
Declare #get_eMail nvarchar(100)
Declare #get_SplitValue nvarchar(100)
Declare #get_oldSplitValue nvarchar(100)
Declare #rowNumber int
Declare #users_rowNumber int
Declare #i int
Declare #j int
Declare #q_getRowNumber NVARCHAR(MAX)
Declare #q_getoldeMail NVARCHAR(MAX)
Declare #q_UpdateQuery NVARCHAR(MAX)
SET #q_getRowNumber = N'SELECT Count(ID)
FROM ' + QUOTENAME(#tablename)
EXECUTE #rowNumber = sp_executesql #q_getRowNumber
/*Set #rowNumber = (Select Count(ID) from #tablename)*/
Set #users_rowNumber = (Select Count(ID) from tblusers)
Set #i = 1
Set #j = 1
While(#i <= #rowNumber)
BEGIN
Set #q_getoldeMail = '(SELECT Lower(#columnname) FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,ID
,[Name]
,[Description]
,[Status]
,[AssignedTo]
,[AssignedToMail]
,[CC]
FROM' + #tablename + '
) AS ar
WHERE rownumber = #i)'
EXECUTE #get_oldeMail = sp_executesql #q_getoldeMail
Set #get_oldeMail = REPLACE(#get_oldeMail,'ı','i')
WHILE LEN(#get_oldeMail) > 0
BEGIN
IF CHARINDEX('#',#get_oldeMail) > 0
SET #get_oldSplitValue = SUBSTRING(#get_oldeMail,0,CHARINDEX('#',#get_oldeMail))
ELSE
BEGIN
SET #get_oldSplitValue = #get_oldeMail
SET #get_oldeMail = ''
END
SET #get_oldeMail = REPLACE(#get_oldeMail,#get_oldSplitValue + '#' , '')
END
While(#j <= #users_rowNumber)
BEGIN
Set #get_eMail = (SELECT Replace(Lower(eMail),'ı','i') FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,eMail
FROM tblusers) AS ar
WHERE rownumber = #j)
WHILE LEN(#get_eMail) > 0
BEGIN
IF CHARINDEX('#',#get_eMail) > 0
SET #get_SplitValue = SUBSTRING(#get_eMail,0,CHARINDEX('#',#get_eMail))
ELSE
BEGIN
SET #get_SplitValue = #get_eMail
SET #get_eMail = ''
END
SET #get_eMail = REPLACE(#get_eMail,#get_SplitValue + '#' , '')
END
if(#get_splitValue = #get_oldSplitValue)
begin
Set #q_UpdateQuery = 'Update ar Set ' + #columnname + ' = ' + #get_email + ' Where rownumber = ' +#i
EXECUTE sp_executesql #q_UpdateQuery
break
end
SET #j = #j+1
END
SET #i = #i+1
END
End
Thanks in advance.

Why do I get this error in SQL Server? How to fix it?

I am creating a stored procedure to insert to a table. Following would provide my table columns are
Create Table Item
(
ID char(20),
Name varchar(max) NOT NULL,
Brand char(10) NOT NULL,
Category char(10) NOT NULL,
Unit_Of_Measure char(5) NOT NULL,
Price decimal(18,2) NOT NULL,
[Image] image NOT NULL,
Active bit NOT NULL Default('True')
Constraint PK_Item Primary Key (ID),
Constraint FK_Item_Brands Foreign Key (Brand) References Brands(ID),
Constraint FK_Item_Item_Category Foreign Key (Category) References Item_Category(ID),
Constraint FK_Item_Unit_Of_Measure Foreign Key (Unit_Of_Measure) References Unit_Of_Measure(ID)
);
go
Table insert is working fine. Before we go further I need to show the error that I am getting.
Msg 50000, Level 16, State 2, Procedure stpItem, Line 66
Operand type clash: image is incompatible with nvarchar
The above error occurs when I'm executing the command below and after that you would see the stored procedure
exec stpItem '','GG','2','2','2',123.12, null, 'true', 'false'
Stored procedure code:
Create Proc stpItem
#ID varchar(max),
#Name varchar(max),
#Brand varchar(max),
#Category varchar(max),
#UOM varchar(max),
#Price decimal,
#Image Image,
#Active bit,
#Update bit
As
Set Transaction Isolation Level Serializable
Begin Transaction
Begin Try
-- If it is an insertion
IF #Update = 'False'
Begin
Declare #Pre char(1),
#Len int,
#Next int,
#Start int,
#SetKey varchar(max);
Set #SetKey = '';
Select #Pre = Prefix, #Len = [Length], #Next = [Next] From Key_Generation Where Table_Name = 'Item';
Set #Start = 1;
Set #Len = #Len - 1;
While #Start < #Len
Begin
set #SetKey = #SetKey + '0'
set #Start = #Start + 1;
End
Exec('Declare #LID char(20); Set #LID = (select ''' + #Pre + ''' + right(''' + #SetKey + ''' + cast(' + #Next + ' as varchar(' + #Len + ')), ' + #Len + '));' +
'Insert into Item Values (#LID,''' + #Name + ''',''' + #Brand + ''',''' + #Category + ''',''' + #UOM + ''',' + #Price + ',' + #Image + ' ,' + #Active + ');' +
'Update Key_Generation Set [Next] = [Next] + 1 Where Table_Name = ''Item'';');
End
Else
Begin
Update Item
Set Name = #Name,
[Brand] = #Brand,
[Category] = #Category,
[Unit_Of_Measure] = #UOM,
Price = #Price,
[Image] = #Image,
Active = #Active
Where ID = #ID;
End
Commit Transaction;
End Try
Begin Catch
Rollback Transaction;
DECLARE #ErrorMessage NVARCHAR(4000);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SELECT
#ErrorMessage = ERROR_MESSAGE(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (#ErrorMessage, -- Message text.
#ErrorSeverity, -- Severity.
#ErrorState -- State.
);
End Catch
Could anyone tell me why I am getting this error, and how to fix this issue?
You are not casting non varchar variables to varchar here:
#Price + ',' + #Image + ' ,' + #Active + ');'
Try:
cast(#price as varchar(max)) + ',' + cast(#image as varchar(max)) + ...
cast(cast(#Image as binary) as nvarchar(max));
I used a nvarchar variable to convert it from outside then use it inside og execution command
Declare #txtImage nvarchar(max);
if #Image IS NULL
Begin Set #txtImage = 'NULL'; END
Else
Begin Set #txtImage = cast(cast(#Image as binary) as nvarchar(max)); END

Incorrect syntax near '=' while trying to call a stored procedure in T-sql

I am calling a stored procedure called Searchprocedure. I get an error at line where I am calling it. I have not made any changes to the parameters passed in the procedure and it was called just fine with same calling statement earlier.
Exec SearchProcedure #firstname = 'Simran', #middlename = 'kaur', #lastname = 'Khurana', #City = 'Delhi'
What's wrong with the syntax that is gives the error that says:
Incorrect syntax near '='
Edit:
Statement where I did :
set #sql = 'declare ' + '#Temp'+ #colVar + ' int'
exec(#sql)
select #sql as 'SQLFORDECLARATIONS
outputs
declare #TempMiddleName int
yet when I try to set value in the variable gives error that it should be declared first.
The set statement results in :
select #TempMiddleName=dbo.[MatchMiddleName](MiddleNameFromUser,MiddleNameFromTable,0)
which is what is should be yet it not able to see the declared variable
The stored procedure is as follows:
create procedure SearchProcedure
(
#firstname nvarchar(20),
#middlename nvarchar(20) = null,
#lastname nvarchar(20),
#DOB Date = null,
#SSN nvarchar(30)= null,
#ZIP nvarchar(10)= null,
#StateOfResidence nvarchar(2)= null,
#City nvarchar(20)= null,
#StreetName nvarchar(20)= null,
#StreetType nvarchar(20)= null,
#BuildingNumber int= null,
#Aptnumber nvarchar(10)= null
)
As
DECLARE #sSQL NVARCHAR(2000), #Where NVARCHAR(1000) = ' '
declare #Percent int,
#FN nvarchar(20),
#MN nvarchar(20) = null,
#LN nvarchar(20),
#DateOfB Date = null,
#SSNumber nvarchar(30)= null,
#ZIPCode nvarchar(10)= null,
#StateOfRes nvarchar(2)= null,
#CityOfRes nvarchar(20)= null,
#StreetNameRes nvarchar(20)= null,
#StreetTypeRes nvarchar(20)= null,
#BuildingNumberRes int= null,
#AptnumberRes nvarchar(10)= null
set #Percent = 0
create table #results
(
firstname nvarchar(20) not null,
middlename nvarchar(20),
lastname nvarchar(20)not null,
PercentageMatch int not null,
DOB Date,
SSN nvarchar(30),
ZIP nvarchar(10),
[State] nvarchar(2),
City nvarchar(20),
StreetName nvarchar(20),
StreetType nvarchar(20),
BuildingNumber int,
Aptnumber nvarchar(10)
)
declare c Cursor local static Read_only
for
SELECT * from dbo.Patients where firstname = #firstname
open c
fetch next from c into #FN,
#MN,
#LN,
#DateOfB,
#SSNumber,
#ZIPCode,
#StateOfRes,
#CityOfRes,
#StreetNameRes,
#StreetTypeRes,
#BuildingNumberRes,
#AptnumberRes
while ##FETCH_STATUS = 0 BEGIN
/*set #Percent = dbo.[MatchLastName](#lastname, #LN, #Percent)
set #Percent = dbo.[MatchMiddleName](#middlename, #MN, #Percent)
set #Percent = dbo.[MatchCity](#City, #CityOfRes, #Percent)*/
Exec [dbo].[OutputProcedure] #lastname, #LN, #middlename, #MN,#City, #CityOfRes, #Percent output
Insert into #results values
(#FN,#MN,#LN,#Percent, #DateOfB,#SSNumber, #ZIPCode,#StateOfRes,#CityOfRes,#StreetNameRes,#StreetTypeRes,#BuildingNumberRes,#AptnumberRes)
fetch next from c into #FN,
#MN,
#LN,
#DateOfB,
#SSNumber,
#ZIPCode,
#StateOfRes,
#CityOfRes,
#StreetNameRes,
#StreetTypeRes,
#BuildingNumberRes,
#AptnumberRes
end
select * from #results order by PercentageMatch desc
IF OBJECT_ID('tempdb..#results') IS NOT NULL DROP TABLE #results
go
OutputProcedure code is as follows:
CREATE Procedure OutputProcedure
(
#LastNameFromUser nvarchar(20) = null,
#LastNameFromTable nvarchar(20),
#MiddleNameFromUser nvarchar(20) = null,
#MiddleNameFromTable nvarchar(20) = null,
#CityFromUser nvarchar(20) = null,
#CityFromTable nvarchar(20) = null,
#Percentage int out
)
AS
BEGIN
select 'OUTPUTPROCEDURECALLED'
declare #maxvalue int
DECLARE #variableTable TABLE (
idx int identity(1,1),
matchvalue nvarchar(15))
INSERT INTO #variableTable(matchvalue) values ('MiddleName')
INSERT INTO #variableTable(matchvalue) values ('LastName')
INSERT INTO #variableTable(matchvalue) values ('City')
SELECT * FROM #variableTable
DECLARE #counter int
declare #sql nvarchar(100)
declare #sql2 nvarchar(25), #finalResult nvarchar(100)
declare #sql3 nvarchar(300), #sql4 nvarchar(15), #tempresultStore nvarchar(20), #temp int, #temp2 int, #average int
SET #counter = 1
SELECT #maxvalue = (SELECT MAX(idx) FROM #variableTable)
select #maxvalue as 'MAXVALUE'
WHILE(#counter <= #maxvalue)
BEGIN
DECLARE #colVar nvarchar(15)
SELECT #colVar = matchvalue FROM #variableTable WHERE idx = #counter
set #sql = 'declare ' + '#Temp'+ #colVar + ' int'
exec(#sql)
select #sql as 'SQLFORDECLARATIONS'
/*set #temp = CHARINDEX(' ',#sql)
select #temp as 'resultofcharindex'
set #temp2 = LEN(#sql) - (#temp)
SELECT #temp2 AS 'AFTERADDING1'
set #tempresultStore = right(#sql, #temp2)*/
set #tempresultStore = 'Temp'+#colVar
SELECT #tempresultStore AS 'FINALCUTPART'
set #sql3 = 'set ' + ' ' + #tempresultStore + '=' + 'dbo.[Match' + #colVar + '](' + #colVar + 'FromUser' + ',' + #colVar + 'FromTable' + ',' + '0)'
EXEC(#sql3)
select #sql3 as 'check sql query formed'
set #finalResult = #finalResult + #tempresultStore
select #finalResult as 'SUM'
SET #counter = #counter + 1
select #counter as 'COUNTERVALUE'
END
set #Percentage = #finalResult/#maxvalue
SELECT #Percentage AS 'FINALRESULT'
RETURN
END
--Setting variable in Dynamic SQL
DECLARE
#sql NVARCHAR(MAX),
#Name NVARCHAR(100)
SET #Name = '#B2E0EB1A'
SET #sql =
'
DECLARE #MyVar NVARCHAR(100)
SELECT TOP 1 #MyVar = name FROM sys.objects WHERE name LIKE ''%a''--Escaping single quote with double quote
PRINT #MyVar
'
EXEC(#sql)
SET #sql =
'
DECLARE #MyVar NVARCHAR(100)
SET #MyVar = '''+(SELECT TOP 1 name FROM sys.objects WHERE name LIKE '%a')+'''--Escaping single quote with double quote
PRINT #MyVar
'
EXEC(#sql)
SET #sql =
'
DECLARE #MyVar NVARCHAR(100)
SET #MyVar = '''+#Name+'''--Escaping single quote with double quote
PRINT #MyVar
'
EXEC(#sql)
SET #sql =
'
DECLARE #MyVar NVARCHAR(100)
SET #MyVar = ''#B2E0EB1A''--Escaping single quote with double quote
PRINT #MyVar
'
EXEC(#sql)
If you want to get output variable from your dynamic query you have to use sp_executesql procedure instead of EXEC()
Study this code
DECLARE #DynamicSQLOutput NVARCHAR(100)
DECLARE #SQL nvarchar(500);
DECLARE #ParmeterDefinition nvarchar(500);
--in this variabe you write the variables which you want to be declared in the dynamic sql without using the declare
SET #ParmeterDefinition = N'#FinalOutputResultInDynamicSQL NVARCHAR(100) OUTPUT';
--here you write your dynamic code
SELECT #SQL = N'SET #FinalOutputResultInDynamicSQL = ''test'' '
EXEC sp_executesql
#SQL, --Execute code
#ParmeterDefinition, -- Define Parameters
#FinalOutputResultInDynamicSQL = #DynamicSQLOutput OUTPUT --Get output
--Note that #FinalOutputResultInDynamicSQL is only defined in #ParmeterDefinition but not outside of the dynamic sql
PRINT #DynamicSQLOutput;
I think too many things wrong in your Dynamic sql. I found one
SET #sql3 = 'set ' + ' ' + #tempresultStore + ' = ' + 'dbo.[Match'
+ #colVar + '](' + #colVar + 'FromUser' + ',' + #colVar
+ 'FromTable' + ',' + '0)'
In the above code instead of Set use Select. Looks like you are selecting from a UDF. Try this
SET #sql3 = 'Select ' + ' ' + #tempresultStore + ' = ' + 'dbo.[Match'
+ #colVar + '](' + #colVar + 'FromUser' + ',' + #colVar
+ 'FromTable' + ',' + '0)'
Note : To debug Dynamic Sql before Exec #sql just use print #sql to check the syntax and other stuff in generated sql
I can't find any error and can run the exec without anerror message.
Edit: After I created the (now avialbe) output procedure and uncomment its call, I'm getting the error too...
Still investigating
Edit2:
In the Output procedure you have to use
set #sql = 'declare ' + '#Temp'+ #colVar + ' int' (# before Temp) and
set #sql3 = 'set ' + ' #' + #tempresultStore" (additional # after the 'set'.
Btw: you can exec more than one statement in Dynamic SQL so you could use f.e. exec (#sql + '; ' + #sql3);