SQL Server stored procedure statements using table clause - sql-server-2005

I am new to SQL Server and just joined a company where somebody had created the following stored procedure which I cannot understand.
I would like all of you to help me to understand what is going on in this procedure and what can be the alternate way of doing it.
Procedure [dbo].[SP_GetUserIncompleteCheckList]
(
#GroupID as int,
#BranchID as numeric)
As
Begin
Declare #DateStart as datetime
if #GroupID = 1
begin
set #DateStart = '08/31/2010' --'09/01/2010' 'Getdate()-30
end
else
begin
set #DateStart = Getdate()-30
end
--Select ResponseDate,isNull(Submit,'Incomplete') as Status from CheckList_Response Where BranchID=#BranchID and isNull(Submit,'y') <> 'Complete' and Month(ResponseDate) = Month(GetDate()) and Year(ResponseDate) = Year(GetDate()) order by ResponseDate
declare
#T table (ResponseDate Datetime,UserResponse int,DailyCount int,WeeklyCount int,MonthlyCount int,QuaterlyCount int,HalfYearlyCount int)
insert into #T (ResponseDate,UserResponse,DailyCount,WeeklyCount,MonthlyCount,QuaterlyCount,HalfYearlyCount)
Select ResDate,
isNull((Select UserResponse from VUserResponseBranchGroupwise Where ResponseDate=A.ResDate AND CLGroup = #GroupID and BranchID = B.BranchID),0) as UserResponse,
(Select Count(CLID) From CheckList where Frequency = 'Daily' and CLGroup=#GroupID) as DailyCount,
Case Weekly
When 1 Then (Select Count(CLID) From CheckList where Frequency = 'Weekly' and CLGroup=#GroupID) Else 0
End as WeeklyCount,
Case Monthly
When 1 Then (Select Count(CLID) From CheckList where Frequency = 'Monthly' and CLGroup=#GroupID) Else 0
End as MonthlyCount,
Case Quaterly
When 1 Then (Select Count(CLID) From CheckList where Frequency = 'Quarterly' and CLGroup=#GroupID) Else 0
End as QuaterlyCount,
Case HalfYearly
When 1 Then (Select Count(CLID) From CheckList where Frequency = 'Half Yearly' and CLGroup=#GroupID) Else 0
End as HalfYearlyCount
--isNull(Submit,'Incomplete') as Status
--,RoleStatus1,RoleStatus2,RoleStatus3,RoleStatus4,RoleStatus5 */
from dbo.CheckList_DateType A
,dbo.CheckList_Response B
Where A.ResDate=B.ResponseDate
AND B.ResponseDate > #DateStart
AND isNull(B.Submit,'Incomplete') <> 'Complete'
AND B.BranchID = #BranchID
Select ResponseDate,
case UserResponse
when 0 Then 'Incomplete'
else 'Partial'
end as Status
from #T
Where UserResponse < (DailyCount+WeeklyCount+MonthlyCount+QuaterlyCount+HalfYearlyCount)
order by ResponseDate
As far as I understand its a temporary table or something...

It's a variable of type TABLE
Same as:
DECLARE #COUNTER INT // variable of type INT
DECLARE #STR VARCHAR(5) // variable of type STRING
DECLARE #TAB TABLE(COLUMN1 INT) // variable of type TABLE
You can assign values to variables using SET statements.
Example:
SET #COUNTER = 1;
But for tables, INSERT statement will do
INSERT INTO #TAB(COLUMN1) VALUES(123)

It is a table variable.
Have a look at
Table Variables In T-SQL
DECLARE #local_variable
(Transact-SQL)

Related

Add column name to a variable and use it in later calculation in WHERE clause

I have a problem. I need to determine the name of the column under which the calculations will continue. So I wrote a select:
DECLARE #column VARCHAR(MAX)
DECLARE #ColumnA VARCHAR(MAX)
DECLARE #ColumnB VARCHAR(MAX)
SET #ColumnA = 'RegistrationDate'
SET #ColumnB = 'EntryDate'
SET #column = CASE
WHEN CONVERT(DATE,GETDATE()) NOT IN (
'2021-08-04','2021-08-05','2021-08-06','2021-08-07','2021-08-08','2021-08-09','2021-08-10','2021-09-07','2021-09-08','2021-09-09','2021-09-10','2021-09-11',
'2021-09-12','2021-09-13','2021-10-05','2021-10-06','2021-10-07','2021-10-08','2021-10-09','2021-10-10','2021-10-11','2021-11-09','2021-11-10','2021-11-11','2021-11-12','2021-11-13','2021-11-14','2021-11-15','2021-12-07',
'2021-12-08','2021-12-09','2021-12-10','2021-12-11','2021-12-12','2021-12-13'
) THEN
QUOTENAME(#Column)
ELSE
QUOTENAME(#ColumnB)
END
SELECT #column
which returns me [RegistrationDate] or [EntryDate] and stores this in variable #column. Now, when I know under which column should I calculate, I want to insert this variable #column in to my main select one of the WHERE clause:
DECLARE #column VARCHAR(MAX)
DECLARE #ColumnA VARCHAR(MAX)
DECLARE #ColumnB VARCHAR(MAX)
SET #ColumnA = 'RegistrationDate'
SET #ColumnB = 'EntryDate'
SET #column = CASE
WHEN CONVERT(DATE,GETDATE()) NOT IN (
'2021-08-04','2021-08-05','2021-08-06','2021-08-07','2021-08-08','2021-08-09','2021-08-10','2021-09-07','2021-09-08','2021-09-09','2021-09-10','2021-09-11',
'2021-09-12','2021-09-13','2021-10-05','2021-10-06','2021-10-07','2021-10-08','2021-10-09','2021-10-10','2021-10-11','2021-11-09','2021-11-10','2021-11-11','2021-11-12','2021-11-13','2021-11-14','2021-11-15','2021-12-07',
'2021-12-08','2021-12-09','2021-12-10','2021-12-11','2021-12-12','2021-12-13'
) THEN
QUOTENAME(#Column)
ELSE
QUOTENAME(#ColumnB)
END
SELECT
CASE WHEN final.Branch IS NULL THEN 'Total'
ELSE final.Branch
END AS 'Branch',
final.TR
FROM
(
SELECT
CASE
WHEN main.BRANCHNO = 1 THEN 'One'
WHEN main.BRANCHNO = 2 THEN 'Two'
WHEN main.BRANCHNO = 3 THEN 'Three'
WHEN main.BRANCHNO = 4 THEN 'Four'
WHEN main.BRANCHNO = 5 THEN 'Five'
WHEN main.BRANCHNO = 6 THEN 'Six'
END AS 'Branch',
COUNT(*) AS 'TR'
FROM
(
SELECT
*
FROM
[TABLE]
WHERE
Status = 100
AND
BRANCHNO IN (1,2,3,4,5,6)
AND
Type = 'TR'
AND
**#column** = CONVERT(DATE, CASE WHEN DATENAME(dw, getdate()) = 'Monday' THEN getdate()-3 ELSE getdate()-1 END
)
) AS main
GROUP BY
main.BRANCHNO WITH ROLLUP
) AS final
But when I execute query it returns me an error:
Msg 241, Level 16, State 1, Line 11 Conversion failed when converting
date and/or time from character string.
I imagined everything very simple: I put a column name into a variable, and then, that name placed at the beginning of the WHERE clause will be recognized as the column name and then *= CONVERT(DATE, CASE WHEN DATENAME(dw, getdate()) etc will do all work.
But that did not happen. Maybe someone knows why and maybe they know how to solve this task?
You can't use a variable to reference a column name. #column is just a piece of data, which just so happens to contain a column name as a string, but it's still just a string, not actually a reference to a column in a table.
Some options you have seem to be...
AND CASE #column WHEN 'RegistrationDate' THEN RegistrationDate
WHEN 'EntryDate' THEN EntryDate
END
=
CONVERT(DATE, CASE WHEN DATENAME(dw, getdate()) = 'Monday' THEN getdate()-3 ELSE getdate()-1 END)
Or, have two queries which only differ in the column being referenced...
IF (#column = 'RegistrationDate')
<query1>
ELSE IF (#column = 'EntryDate')
<query2>
Or "Dynamic SQL" where you build up a new string with your SQL code and execute that by call sp_executesql (assuming this is SQL Server, which it appears to be).
I recommend reading this : https://www.sommarskog.se/dyn-search.html
EDIT: A pure SQL alternative, assuming SQL Server
DECLARE #mode INT = CASE
WHEN CONVERT(DATE,GETDATE()) NOT IN (
'2021-08-04','2021-08-05','2021-08-06','2021-08-07','2021-08-08','2021-08-09','2021-08-10','2021-09-07','2021-09-08','2021-09-09','2021-09-10','2021-09-11',
'2021-09-12','2021-09-13','2021-10-05','2021-10-06','2021-10-07','2021-10-08','2021-10-09','2021-10-10','2021-10-11','2021-11-09','2021-11-10','2021-11-11','2021-11-12','2021-11-13','2021-11-14','2021-11-15','2021-12-07',
'2021-12-08','2021-12-09','2021-12-10','2021-12-11','2021-12-12','2021-12-13'
) THEN
0
ELSE
1
END;
DECLARE #filter_date DATE = CONVERT(DATE, CASE WHEN DATENAME(dw, getdate()) = 'Monday' THEN getdate()-3 ELSE getdate()-1 END;
WITH
source AS
(
SELECT
*
FROM
[TABLE]
WHERE
Status = 100
AND BRANCHNO IN (1,2,3,4,5,6)
AND Type = 'TR'
),
filtered_source AS
(
SELECT 0 AS mode, * FROM source WHERE RegistrationDate = #filter_date
UNION ALL
SELECT 1 AS mode, * FROM source WHERE EntryDate = #filter_date
)
SELECT
COALESCE(
CASE
WHEN BRANCHNO = 1 THEN 'One'
WHEN BRANCHNO = 2 THEN 'Two'
WHEN BRANCHNO = 3 THEN 'Three'
WHEN BRANCHNO = 4 THEN 'Four'
WHEN BRANCHNO = 5 THEN 'Five'
WHEN BRANCHNO = 6 THEN 'Six'
END,
'Total'
)
AS 'Branch',
COUNT(*) AS 'TR'
FROM
filtered_source
WHERE
mode = #mode
GROUP BY
GROUPING SETS (
(mode),
(mode, BRANCHNO)
);
By always including mode in the GROUPING SETS, the optimiser might be able to yield a better execution plan for the two scenarios.
Still read the link given above though, at the very least to understand why this is necessary, or perhaps why it doesn't quite manage to yield the best execution plan.

How to find out sum of a column with respect to another columns maximum and minimum

I have worked with DB2, and I just moved to the SQL Server. I'm a bit confused by a query.
Lets suppose I have table data like
StoreID | Sales
A | 23
B | 50
B | 50
In this data with the stored procedure parameter, I wanted to roll up the sum of Sales. I will get a parameter of StoreID, but in this parameter I can get 'ALL' too.
In DB2 I can get all data using a stored procedure (which has StoreID in a parameter named ParameterStore) with a query like
if(ParameterStore= 'ALL') Then
Set Loc_min = X'00';
Set Loc_max = X'FF';
ELSE
Set Loc_min = ParameterStore;
Set Loc_max = ParameterStore;
END if;
Select Sum(Sales) From Store_data where StoreID between Loc_min and Loc_max;
How can I do this in SQL Server to get the same result?
You could check the value if it's ALL or some other value in OR:
DECLARE #store_id VARCHAR(20) -- or whatever length you have
SET #store_id = 'XYZ'
select sum(sales)
from store_data
where #store_id = 'ALL' or store_id = #store_id;
T-SQL syntax for IF is slightly different. You can use it like this:
/*
DECLARE #ParameterStore VARCHAR(10);
DECLARE #Loc_min INT;
DECLARE #Loc_max INT;
*/
IF #ParameterStore = 'ALL'
BEGIN
Set #Loc_min = 0x00;
Set #Loc_max = 0xFF;
END
ELSE
BEGIN
Set #Loc_min = #ParameterStore;
Set #Loc_max = #ParameterStore;
END;
Having said that, what you are trying to achieve could be done as follows:
-- DECLARE #ParameterStore VARCHAR(10);
SELECT SUM(Sales)
FROM Store_data
WHERE CASE
WHEN #ParameterStore = 'ALL' THEN -1
WHEN #ParameterStore = StoreID THEN -1
END = -1
Try this if you need hexadecimal comparison.
DECLARE
#ParameterStore VARCHAR(10)
SET #ParameterStore = 'ALL'
SELECT SUM(Sales)
FROM Store_data
WHERE StoreID BETWEEN (
CASE
WHEN #ParameterStore = 'ALL'
THEN 0x00
ELSE #ParameterStore
END)
AND (
CASE
WHEN #ParameterStore = 'ALL'
THEN 0xFF
ELSE #ParameterStore
END ) ;
DEMO

I want to add multiple select queries in stored procedure by using flag - how will I do this?

ALTER PROCEDURE [dbo].[UserManagement]
#flag int
AS
BEGIN
IF #flag = 1
BEGIN
SELECT
Formatid, Formatdetail, dispformat
FROM
loy_Formatdetail with (nolock)
WHERE
isactive = '1'
AND memberstatus = 'Member'
ORDER BY
FormatDetail
END
END

While Loop SAP B1 SQL stored procedure for blocking

I have an issue with my stored procedure SAP B1.
What I'm trying to do here is storing the sum of the quantity, group by the manufacturing order and insert it into the temp table. Then use a while loop to go thru each ID to compare with the user table [#FGTRACKING] and block if
temp.quantity > sum(quantity) in [#FGTracking].
However this is not working, the transaction still passed the stored procedure block. I suspect there is something wrong with my syntax.
IF #transaction_type IN ('A') AND #object_type = '67'
BEGIN
declare #top as int
declare #temp table (id int,quantity int NOT NULL, monum int NOT NULL)
insert into #temp (id, quantity,monum)
select row_number() over (order by (select NULL)), sum(quantity) as quantity, u_shipment_line as monum
from wtr1 t1
where t1.docentry = #list_of_cols_val_tab_del
group by u_shipment_line
set #top = 1
WHILE #top <= (select count(monum) from #temp)
BEGIN
IF EXISTS (select t100.monum from #temp t100
where t100.quantity > (select sum(t111.u_transfer)
from [#FGTRACKING] t111 where t111.u_mo_num = t100.monum
group by t111.u_mo_num) and t100.id = #top)
BEGIN
SELECT #Error = 666, #error_message = 'Over-transfer'
END
ELSE
set #top = #top + 1
END
END
It looks like you're only incrementing your iterator (#top) when you don't encounter your error condition, so if your error condition triggers, you're stuck in an infinite loop.
Get rid of your "else" and always increment #top, or alternatively break out of your while loop when you hit your error condition.
...
ELSE -- Get rid of this else
set #top = #top + 1
...

How to assign a variable different values based on a column cell values

I need to loop through all rows and do the following:
If the Date_Deleted is null then SET #Form = '01' else #Form = '02'
Currently is returning Form = 01 only.
Thank you!
SELECT #CHECKDATE = [DATE_DELETED]
FROM Executive__Vehicles
WHERE (STATE = 'NC')
IF ( #CHECKDATE is null )
BEGIN
SET #FORM = '01'
END
ELSE
BEGIN
SET #FORM = '02'
END
You need to load all the results from Executive_vehicles into a temp table and then loop through them one by one to do the set.
CREATE TABLE #tempTable1(iID int identity(1,1),date_deleted datetime)
INSERT INTO #tempTable1
select [DATE_DELETED]
FROM Executive__Vehicles WHERE (STATE = 'NC')
DECLARE #countROws int
DECLARE #CHECKDATE datetime
DECLARE #topRow INT
SET #countRows =(SELECT COUNT(*) FROM #tempTable1)
WHILE #countRows>0
BEGIN
SET #topRow = (SELECT TOP 1 iID from #tempTable1)
SET #CHECKDATE = (SELECT TOP 1 date_deleted from #tempTable1)
IF ( #CHECKDATE is null )
BEGIN SET #FORM = '01'
END
ELSE
BEGIN
SET #FORM = '02'
END
DELETE FROM #tempTable1 where iID=#topRow
set #countRows = (SELECT count(*) FROM #tempTable1)
set #CHECKDATE = NULL
END
editted to add identity column as date_deleted could be same for multiple rows and delete would delete all of them.