Resetting a Stored Procedure variable - sql

Well, apparently this does not work. I get a "incorrect syntax near '='" error.
Is it possible to change the value of a variable several times within a stored procedure?
Similar to this example :
DECLARE #columnCounter INT
SET #columnCounter = 0
DECLARE #columnName VARCHAR(255)
SET #columnName = 'A'
WHILE (#columnCounter < 4)
BEGIN
IF (#columnCounter == 1)
BEGIN
SET #columnName = 'B'
END
IF (#columnCounter == 2)
BEGIN
SET #columnName = 'C'
END
IF (#columnCounter == 3)
BEGIN
SET #columnName = 'D'
END
END
Thank you.

Is the ==. Transact-SQL uses simple = for equality comparison, like this:
DECLARE #columnCounter INT;
SET #columnCounter = 0;
DECLARE #columnName VARCHAR(255);
SET #columnName = 'Set_To_Value_ID';
WHILE (#columnCounter < 4)
BEGIN
IF (#columnCounter = 1)
BEGIN
SET #columnName = 'Set_To_Variable_ID';
END
IF (#columnCounter = 2)
BEGIN
SET #columnName = 'Changed_In_SP';
END
IF (#columnCounter = 3)
BEGIN
SET #columnName = 'Set_To_Comment_Input';
END
set #columnCounter += 1;
END

IF (#columnCounter == 1)
Comparison there should just be =, == is a common syntax in a number of languages, but not t-sql.
http://msdn.microsoft.com/en-us/library/ms175118(v=sql.100).aspx

Related

Spiting filter values into conditions sql

I have a filter and condition in a function, which works for only one condition
i:e '='
I want it to work for all condition like ' IN', ' >=', '<='
Here is the Code
declare #filter VARCHAR(1000)
DECLARE #TempFilter VARCHAR(1000)
declare #Condition VARCHAR(1000)
set #Condition='Blocked'
SET #Filter=N'Blocked=0 and TYPE = 2 and ID = 1635729'
SET #Condition=#Condition+'='
SELECT
#TempFilter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter),LEN(#Filter))
IF CHARINDEX('and',#TempFilter)=0
BEGIN
SET #Filter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter)+LEN(#Condition),
LEN(#Filter)-LEN(#Condition)-LEN(#TempFilter))
END
ELSE
BEGIN
SET #Filter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter)+LEN(#Condition),
CHARINDEX(' ',#TempFilter)-LEN(#Condition))
END
Please help or suggest.
Can you test this code
DECLARE #tempFilter VARCHAR(1000)
declare #condition VARCHAR(1000)
declare #filter VARCHAR(1000)
declare #operator VARCHAR(1000)
declare #trimmedFilter VARCHAR(1000)
set #Condition='Blocked'
SET #filter=N'Blocked IN(0) and TYPE > = 2 and ID IN (1635729,15454)'
WHILE LEN(#Filter) > 0
BEGIN
IF CHARINDEX(' and',#filter)<> 0
begin
SET #TempFilter = RIGHT ( #filter , LEN(#filter) - CHARINDEX(' and',#filter)-4)
SET #filter = LEFT ( #filter , CHARINDEX(' and',#filter))
end
SET #trimmedFilter = REPLACE(#filter,' ','')
set #operator =
case
when CHARINDEX('NOTIN(',#trimmedFilter) <> 0 then 'NOTIN'
when CHARINDEX('IN(',#trimmedFilter) <> 0 then 'IN'
when CHARINDEX('>=',#trimmedFilter) <> 0 then '>='
when CHARINDEX('<=',#trimmedFilter) <> 0 then '<='
else '='
end
IF CHARINDEX(#Condition,#filter) <> 0
BEGIN
SET #filter = REPLACE(RIGHT(#trimmedFilter,LEN(#trimmedFilter) - CHARINDEX(#operator,#trimmedFilter)+1), 'NOTIN', 'NOT IN')
BREAK
END
ELSE
BEGIN
SET #filter = #TempFilter
CONTINUE
END
END

IF ELSE Statement in SQL Server jobs

I have a SQL Server job defined as follows but it shows error while executing. Please help sort out the problem
-- First clear out the destination table fast and easy without
TRUNCATE TABLE [etimetracklite1].[dbo].[devicelogs];
-- Create table
DECLARE #tablename AS nvarchar(14);
DECLARE #yearnam AS nvarchar(4);
DECLARE #tabnam AS nvarchar(18);
IF MONTH(GETDATE()) = 1
BEGIN
SET #tablename = [devicelogs_1_]
END
ELSEIF MONTH(GETDATE()) = 2
BEGIN
SET #tablename = '[devicelogs_2_]
END
ELSEIF MONTH(GETDATE()) = 3
BEGIN
SET #tablename = [devicelogs_3_]
END
ELSEIF MONTH(GETDATE()) = 4
BEGIN
SET #tablename = [devicelogs_4_]
END
ENDIIF MONTH(GETDATE()) = 5
BEGIN
SET #tablename = [devicelogs_5_]
END
ELSEIF MONTH(GETDATE()) = 6
BEGIN
SET #tablename = [devicelogs_6_]
END
ELSEIF MONTH(GETDATE()) = 7
BEGIN
SET #tablename = [devicelogs_7_]
END
ELSEIF MONTH(GETDATE()) = 8
BEGIN
SET #tablename = [devicelogs_8_]
END
ELSEIF MONTH(GETDATE()) = 9
BEGIN
SET #tablename = [devicelogs_8_]
END
ELSEIF MONTH(GETDATE()) = 10
BEGIN
SET #tablename = [devicelogs_10_]
END
ELSEIF MONTH(GETDATE()) = 11
BEGIN
SET #tablename = [devicelogs_11_]
END
ELSEIF MONTH(GETDATE()) = 12
SET #tablename = [devicelogs_12_]
END
SET #yearnam = YEAR(GETDATE());
SET #tabnam = #tablename + #yearnam;
-- Execute a query
DECLARE #query_a AS nvarchar(500);
SET #query_a = 'INSERT INTO etimetracklite1.dbo.devicelogs SELECT *
FROM etimetracklite1.dbo.' + [#tabnam];
EXECUTE sp_executesql #query_a;
The error I am getting is SQL error 102.
remove single quote from this condition
ELSEIF MONTH(GETDATE()) = 2
BEGIN
SET #tablename = '[devicelogs_2_]
END
and ELSEIF should be ELSE IF
This is a lousy data model. You should be putting all the data into a single table.
If you printed out the SQL, you would probably spot the problem very easily. (At least) one problem is the misconstructed square braces. You have the year coming after them, for instance.
But, in any case, you can simplify your code:
TRUNCATE TABLE [etimetracklite1].[dbo].[devicelogs];
-- Create table
DECLARE #tabnam AS nvarchar(18);
SET #tabname = 'devicelogs_11_[MM][YYYY]';
SET #tabname = REPLACE(REPLACE(#tabname, '[MM]', MONTH(GETDATE())
), '[YYYY]', YEAR(GETDATE())
);
DECLARE #sql nvarchar(max);
SET #sql = 'INSERT INTO etimetracklite1.dbo.devicelogs SELECT *
FROM etimetracklite1.dbo.' + #tabnam;
EXECUTE sp_executesql #sql;

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.

Function to check the input number of words

Need help to create a function that returns TRUE or FALSE. TRUE - if type 1 or 3 words (like '__hello_', '_hello', '_hello my frend' - spaces should be cut), if the condition is not fulfilled FALSE
CREATE FUNCTION dbo.nazvFac(#f nvarchar(30))
RETURNS bit
AS
BEGIN
DECLARE #l int = 1, #s nvarchar(30), #i int = 0, #b bit
WHILE LTRIM(RTRIM(LEN(#f))) >= #l --error here, but I do not know how to fix it
BEGIN
SET #s = SUBSTRING(#f, #l, 1)
IF #s BETWEEN 'А' AND 'я'
SET #l += 1
ELSE IF #s = ' '
BEGIN
SET #l -= 1
SET #s = SUBSTRING(#f, #l, 1)
SET #s = RTRIM(#s)
SET #l += 2
SET #i += 1
END
ELSE
BREAK
END
IF #i = 0 OR #i = 2
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
GO
WHILE LTRIM(RTRIM(LEN(#f))) >= #l --error here, but I do not know how to fix it
LEN() returns an int, which you are then passing to a string function: RTRIM().
You want to return TRUE only if there are one or three words? This should do it:
CREATE FUNCTION dbo.nazvFac(#f NVARCHAR(30))
RETURNS BIT
AS
BEGIN
DECLARE #l INT, #b BIT
SET #l = LEN(#f) - LEN(REPLACE(#f, ' ', '')) + 1
IF #l == 1 OR #l == 3
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
Also, JC. is right about the len() error.
You should trim the string and then check the length.
CREATE FUNCTION dbo.nazvFac(#f NVARCHAR(30))
RETURNS BIT
AS
BEGIN
DECLARE #l INT = 1, #s NVARCHAR(30), #i INT = 0, #b BIT
WHILE LEN(LTRIM(RTRIM(#f))) >= #l --I think youn need to trim the string and then check length
BEGIN
SET #s = SUBSTRING(#f, #l, 1)
IF #s BETWEEN 'А' AND 'я'
SET #l += 1
ELSE IF #s = ' '
BEGIN
SET #l -= 1
SET #s = SUBSTRING(#f, #l, 1)
SET #s = RTRIM(#s)
SET #l += 2
SET #i += 1
END
ELSE
BREAK
END
IF #i = 0 OR #i = 2
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
GO

Invalid length parameter passed to the LEFT or SUBSTRING function

Following is my query and it works fine when I have like TRAILER_MAKE_MODEL 'testing ~ testing, test ~ testq,' ends with comma but can't handle 'testing ~ testing, test ~ testq' same as for other variable TRAILER_IDV. I tried my best but cant work it out any help would be appreciated.
My aim is to get the comma separated value for xml.
DECLARE #TRAILER_MAKE_MODEL VARCHAR(MAX)
DECLARE #TRAILER_IDV VARCHAR(MAX)
DECLARE #USER_TYPE VARCHAR(MAX)
DECLARE #START_INDEX_1 INT
DECLARE #START_INDEX_4 INT
DECLARE #END_INDEX_1 INT
DECLARE #END_INDEX_4 INT
DECLARE #VALUE VARCHAR(50)
DECLARE #QUERY VARCHAR(MAX)
set #TRAILER_MAKE_MODEL='testing ~ testing, test ~ testq,'
set #TRAILER_IDV='3500, 3400,'
set #USER_TYPE='MOBILE'
set #QUERY = ''
set #START_INDEX_1 = 1
set #START_INDEX_4 = 1
set #END_INDEX_1 = 0
if ISNULL(#TRAILER_MAKE_MODEL,'') <> ''
begin
WHILE #START_INDEX_1 > 0 and #START_INDEX_1 < len(#TRAILER_MAKE_MODEL)
BEGIN
SET #END_INDEX_1 = CHARINDEX(',',#TRAILER_MAKE_MODEL,#START_INDEX_1)
if #END_INDEX_1 = 0 and #START_INDEX_1 = 1
Begin
SET #END_INDEX_1 = len(#TRAILER_MAKE_MODEL)
END
if #USER_TYPE <> 'MOBILE'
Begin
SET #END_INDEX_1 = #END_INDEX_1 +1
End
SET #VALUE = SUBSTRING(#TRAILER_MAKE_MODEL,#START_INDEX_1,#END_INDEX_1 - #START_INDEX_1)
SET #QUERY = #QUERY + 'UNION ALL SELECT ''' + #VALUE + ''' TRAILER_MAKE_MODEL'
SET #END_INDEX_4 = CHARINDEX(',',#TRAILER_IDV,#START_INDEX_4)
if #END_INDEX_4 = 0 and #START_INDEX_4 = 1
Begin
SET #END_INDEX_4 = len(#TRAILER_IDV)
END
if #USER_TYPE <> 'MOBILE'
Begin
SET #END_INDEX_4 = #END_INDEX_4 +1
End
SET #VALUE = SUBSTRING(#TRAILER_IDV,#START_INDEX_4,#END_INDEX_4 - #START_INDEX_4)
SET #QUERY = #QUERY + ',' + #VALUE + 'TRAILER_IDV '
print #QUERY
SET #START_INDEX_1 = #END_INDEX_1 + 1
SET #START_INDEX_4 = #END_INDEX_4 + 1
END
select #QUERY=substring(#QUERY, 10, LEN(#QUERY) - 9)
EXEC (#QUERY)
END
You already have a lot of code here so two extra lines where you assign a comma at the end of each string should probably not slow things down for you or make the code less maintainable.
SET #TRAILER_MAKE_MODEL += ',';
SET #TRAILER_IDV += ',';
I don't really understand what your code does but to get the result you are getting you can use a split string function that returns the index of the item like this.
select T1.Item as TRAILER_MAKE_MODEL,
T2.Item as TRAILER_IDV
from dbo.SplitString(#TRAILER_MAKE_MODEL, ',') as T1
inner join dbo.SplitString(#TRAILER_IDV, ',') as T2
on T1.ItemNumber = T2.ItemNumber