Converting While Loop in SP to Set based - sql-server

I am trying to convert a while loop stored procedure to a set-based code .Someone can enlighten me how to do this ? I separate the source data to 2 #temp table based on the #AlertType (email or sms), and inner join the #temptable to based table (itemheader and itemdetail) to replace the code below :
**Old code :**
Where IMD.CustomerAccountNo= #CustAccountNo
AND IMD.StatusCode=#ItemStatus
AND (#Reasoncode = '%' OR IMD.Reasoncode = #Reasoncode)
AND IH.TrackingNo=#TrackingNo
AND IH.ServiceTypeId = #ServiceType
**New code:**
inner join #tempresult_SMS SMS on
IMD.CustomerAccountNo= SMS.CustAccountNo
AND IMD.StatusCode= SMS.ItemStatus
AND (IMD.Reasoncode = SMS.ReasonCode 0R SMS.ReasonCode = '%')
AND IH.TrackingNo=SMS.TrackingNo
AND IH.ServiceTypeId = SMS.ServiceType
But I am struck at the part to generate the #EmailREQNumber in the while loop , how do I generate this number and insert into the table without the while loop ?
#EmailREQNumber + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
This is the full SP:
Alter PROCEDURE [dbo].[ezy_UpdateItemHeader](
#SMSNotificationItemDetails ezy_SMSNotificationItemDetailsType READONLY)
AS
BEGIN
SET NOCOUNT ON;
--Declare temp table
DECLARE #SMSDetailTable TABLE
(
[ROWID] INT NOT NULL PRIMARY KEY IDENTITY(1,1),
[CustAccountNo] [NVARCHAR](MAX) NULL,
[ServiceType] [NVARCHAR](MAX) NULL,
[AlertType] [NVARCHAR](MAX) NULL,
[ItemStatus] [NVARCHAR](MAX) NULL,
[TrackingNo] [VARCHAR](MAX) NULL,
[ReasonCode] [VARCHAR](MAX) NULL,
)
--Insert into temp table
INSERT INTO #SMSDetailTable( [CustAccountNo] , [ServiceType] ,[AlertType] ,[ItemStatus] ,[TrackingNo, [ReasonCode] )
SELECT [CustAccountNo] ,[ServiceType] ,[AlertType] ,[ItemStatus] ,[TrackingNo], [ReasonCode] FROM #SMSNotificationItemDetails
DECLARE #TotalRows INT , #CurrentRow INT
SELECT #TotalRows = COUNT(*) FROM #SMSDetailTable
SET #CurrentRow = 0
--Looping start in the first rows
WHILE(#CurrentRow < #TotalRows)
BEGIN
SET #CurrentRow = #CurrentRow + 1
DECLARE #CustAccountNo VARCHAR(50) ,#ServiceType VARCHAR(50) ,#ItemStatus VARCHAR(50) ,
#AlertType VARCHAR(50) , #TrackingNo VARCHAR(50) , #ReasonCode VARCHAR(50)
--Fetch the data into variable
SELECT #CustAccountNo = CustAccountNo , #ServiceType = ServiceType , #ItemStatus = ItemStatus
, #AlertType = AlertType , #TrackingNo = TrackingNo , #ReasonCode = ReasonCode
FROM #SMSDetailTable WHERE ROWID = #CurrentRow
DECLARE #REQNumber VARCHAR(100) , #EmailREQNumber VARCHAR (100)
---Build the transactionID
SET #REQNumber= 'TESTID'+replace(replace(replace(replace(CONVERT(VARCHAR(40),GETDATE(),121),'-',''),':',''),' ',''),'.','')
SET #EmailREQNumber= 'TESTEMAILID'+replace(replace(replace(replace(CONVERT(VARCHAR(40),GETDATE(),121),'-',''),':',''),' ',''),'.','')
--NOtification Item for SMS
IF (#AlertType = 'SMS' OR #AlertType = 'SMS/Email')
BEGIN
declare #NotificationItemDetail table(
[ID] [int],
[TransactionID] VARCHAR(max),
[ItemNumber] VARCHAR(max),
[AlertType] VARCHAR(max)
)
INSERT INTO #NotificationItemDetail (
[ID],
[TransactionID],
[ItemNumber],
[AlertType]
)
Select
IMD.AutoID
,#REQNumber + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
,#TrackingNo
,#AlertType
from ItemDetail IMD
INNER JOIN itemheader IH on
IH.TrackingNo = IMD.TrackingNo
WHERE
IMD.CustomerAccountNo= #CustAccountNo
AND IMD.StatusCode=#ItemStatus
AND (#Reasoncode = '%' OR IMD.Reasoncode = #Reasoncode)
AND IH.TrackingNo=#TrackingNo
AND IH.ServiceTypeId = #ServiceType
AND IMD.LastUpdatedDate = CAST(GETDATE() as DATE)
END
--NOtification Item for Email
IF (#AlertType = 'Email')
BEGIN
declare #NotificationItemSMSEMAILDetail table(
[ID] [int],
[ETransactionID] VARCHAR(max),
[EItemNumber] VARCHAR(max),
[EAlertType] VARCHAR(max))
INSERT INTO #NotificationItemSMSEMAILDetail (
[ID],
[ETransactionID],
[EItemNumber],
[EAlertType]
)
Select
IMD.AutoID
,#EmailREQNumber + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
,IMD.TrackingNo
,'Email'
from ItemDetail IMD
INNER JOIN Itemheader IH on
IH.TrackingNo = IMD.TrackingNo
where
IMD.CustomerAccountNo= #CustAccountNo
AND IMD.StatusCode=#ItemStatus
AND IH.ServiceTypeId = #ServiceType
AND IMD.LastUpdatedDate = CAST(GETDATE() as DATE)
END
END
END

Related

How To Populate A Local Table?

I have a stored-procedure that (tries) to assign a table (derived from a query) into a variable called #relation. Here's my current futile attempt:
ALTER PROCEDURE [dbo].[getAllBookings]
#mode INT
AS
BEGIN
SET NOCOUNT ON;
--==========
DECLARE #relation AS TABLE(
id INT PRIMARY KEY, code VARCHAR(10), [description] VARCHAR(255),
environment VARCHAR(10), systems VARCHAR(50), [start] SMALLDATETIME,
[end] SMALLDATETIME, [user] VARCHAR(50), approved BIT, rejected BIT
);
SELECT * INTO [#relation] FROM
SELECT
B_ID AS 'id',
B_Change_ID AS 'code',
B_Description AS 'description',
E_Name AS 'environment',
S_System_Name AS 'systems',
dbo.fromDateTime(B_Start_Date) AS 'start',
dbo.fromDateTime(B_End_Date) AS 'end',
U_Name AS 'user',
dbo.isAppr(B_Reviewed, B_Confirmed) AS 'approved',
dbo.isRej(B_Reviewed, B_Confirmed) AS 'rejected'
FROM ((((dbo.Bookings INNER JOIN dbo.Users ON B_User_ID = U_ID)
INNER JOIN dbo.Environment ON B_Environment_ID = E_ID)
INNER JOIN dbo.BookingApps ON B_ID = BA_bookingID)
INNER JOIN dbo.EnvironmentSystems ON BA_bookingSystemID = ES_ID)
INNER JOIN dbo.System_List ON ES_SystemID = S_ID;
--==========
IF (#mode = 0)
DELETE FROM #relation WHERE (approved = 0);
SELECT * FROM #relation;
END
What am I doing wrong here?
I haven't tried building data and running it, but I had to make the following mods to get it to compile. Perhaps this will help get you started.
CREATE PROCEDURE [dbo].[getAllBookings] #mode INT
AS
BEGIN
SET NOCOUNT ON;
--==========
DECLARE #relation AS TABLE
(
[id] INT PRIMARY KEY
, [code] VARCHAR(10)
, [description] VARCHAR(255)
, [environment] VARCHAR(10)
, [systems] VARCHAR(50)
, [start] SMALLDATETIME
, [end] SMALLDATETIME
, [user] VARCHAR(50)
, [approved] BIT
, [rejected] BIT
);
INSERT INTO #relation
([id]
, [code]
, [description]
, [environment]
, [systems]
, [start]
, [end]
, [user]
, [approved]
, [rejected])
SELECT [B_ID] AS 'id'
, [B_Change_ID] AS 'code'
, [B_Description] AS 'description'
, [E_Name] AS 'environment'
, [S_System_Name] AS 'systems'
, dbo.fromDateTime([B_Start_Date]) AS 'start'
, dbo.fromDateTime([B_End_Date]) AS 'end'
, [U_Name] AS 'user'
, dbo.isAppr([B_Reviewed], [B_Confirmed]) AS 'approved'
, dbo.isRej([B_Reviewed], [B_Confirmed]) AS 'rejected'
FROM dbo.[Bookings]
INNER JOIN dbo.[Users]
ON [B_User_ID] = [U_ID]
INNER JOIN dbo.[Environment]
ON [B_Environment_ID] = [E_ID]
INNER JOIN dbo.[BookingApps]
ON [B_ID] = [BA_bookingID]
INNER JOIN dbo.[EnvironmentSystems]
ON [BA_bookingSystemID] = [ES_ID]
INNER JOIN dbo.[System_List]
ON [ES_SystemID] = [S_ID];
--==========
IF ( #mode = 0 )
DELETE FROM #relation
WHERE ( [approved] = 0 );
SELECT *
FROM #relation;
END

How to convert YES/NO to BIT automatically in SQL Server?

I want to override system defined conversion in SQL Server. is that possible.
Problem Statement
I have a large csv file to upload data in database. There is a column with BIT type contains True/False, Yes/No, 1/0
When I used bulk insertion True/False and '1/0' will be consider as right value but Yes/No (as expected) will throw an conversion error.
Is there any way to convert Yes/No without any looping or one by one value?
Edit
Custom data type PanelMemberType
CREATE TYPE [dbo].[PanelMemberType] AS TABLE(
[Email] [nvarchar](255) NOT NULL,
[LocationName] [nvarchar](255) NOT NULL,
[OptInPermission] [nvarchar](255) NOT NULL
)
GO
Stored procedure code:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
#tblPanelMember PanelMemberType READONLY,
#PanelID int,
#UserID nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING #tblPanelMember p2 ON p1.Email= p2.Email
WHEN MATCHED THEN
UPDATE SET
p1.PanelID = #PanelID,
p1.LocationID = (SELECT TOP(1) [LocationID]
FROM [dbo].[Location]
WHERE [LocationName] = p2.LocationName),
p1.Email = p2.Email,
p1.OptInPermission = CONVERT(BIT, p2.OptInPermission),
p1.DateAdded = p1.DateAdded,
p1.DateLastUpdated = (SELECT GETDATE()),
p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES (#PanelID, (SELECT TOP(1) [LocationID]
FROM [dbo].[Location]
WHERE [LocationName] = p2.LocationName),
p2.Email, CONVERT(BIT, p2.OptInPermission),
(SELECT GETDATE()));
END
Just apply a bit more logic rather than trying to blindly convert to bit:
p1.OptInPermission = convert( bit,
CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission END)
(Or, to avoid having to duplicate this logic in both branches of the MERGE, do it in the source:
USING (select Email,LocationName,convert( bit,
CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission END as OptInPermission from #tblPanelMember) p2
)
Inserts records from CSV file into staging table first.
Then run the actual insert into your table and your select statement should look like this:
INSERT INTO ActualTable(column1, column2, column3)
SELECT column1
, column2
, CAST(CASE column3
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE column3
END AS BIT) AS YourBitColumn
FROM StagingTable;
Based on your approach, this should be working:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
(
#tblPanelMember PanelMemberType READONLY
, #PanelID INT
, #UserID NVARCHAR(128)
)
AS
BEGIN TRY
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING #tblPanelMember p2
ON p1.Email = p2.Email
WHEN MATCHED THEN
UPDATE
SET p1.PanelID = #PanelID
, p1.LocationID = (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p1.Email = p2.Email
, p1.OptInPermission = CONVERT(BIT, CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission
END)
, p1.DateAdded = p1.DateAdded
, p1.DateLastUpdated = GETDATE()
, p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES
(
#PanelID
, (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p2.Email
, CONVERT(BIT, CASE p2.OptInPermission
WHEN 'Yes' THEN 1
WHEN 'No' THEN 0
ELSE p2.OptInPermission
END)
, GETDATE()
);
END TRY
BEGIN CATCH
THROW;
END CATCH
You cannot override default function, but you can write your own one. for instance:
CREATE FUNCTION dbo.ConvertBit
(
#Input VARCHAR(5)
)
RETURNS TABLE AS RETURN
SELECT CONVERT(BIT, CASE #Input
WHEN 'True' THEN 1
WHEN 'Yes' THEN 1
WHEN '1' THEN 1
WHEN 'False' THEN 0
WHEN 'No' THEN 0
WHEN '0' THEN 0
END AS BitColumn;
And then just query it this way:
ALTER PROCEDURE [dbo].[PanelMemberBulkUpdate]
(
#tblPanelMember PanelMemberType READONLY
, #PanelID INT
, #UserID NVARCHAR(128)
)
AS
BEGIN TRY
SET NOCOUNT ON;
MERGE INTO PanelMember p1
USING (
SELECT T.Email
, T.LocationName
, B.OptInPermission
FROM #tblPanelMember AS T
CROSS APPLY dbo.ConvertBit(T.OptInPermission) AS B(OptInPermission)
) AS p2
ON p1.Email = p2.Email
WHEN MATCHED THEN
UPDATE
SET p1.PanelID = #PanelID
, p1.LocationID = (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p1.Email = p2.Email
, p1.OptInPermission = p2.OptInPermission
, p1.DateAdded = p1.DateAdded
, p1.DateLastUpdated = GETDATE()
, p1.LastUpdateUserID = #UserID
WHEN NOT MATCHED THEN
INSERT (PanelID, LocationID, Email, OptInPermission, DateAdded)
VALUES
(
#PanelID
, (SELECT TOP (1) [LocationID] FROM [dbo].[Location] WHERE [LocationName] = p2.LocationName)
, p2.Email
, p2.OptInPermission
, GETDATE()
);
END TRY
BEGIN CATCH
THROW;
END CATCH

Sort row on datetime in stored procedure with temp table

I am having a stored procedure which selects data from multiple tables(using joins) and returns it in a sorted order (asc or desc) based on the provided column.
For generating the sorted result based on the input, I use a Temp Table.
My problem is, when the provided column is of datetime, then the sorting is not working.
For other columns, the procedure works as expected.
This is the code I a using.
ALTER PROCEDURE [dbo].[usp_GetEULADetails]
(
#OrgKey INT
,#FilterParams FilterTypes READONLY,
/*– Sorting Parameters */
#SortColumn nvarchar(20) = 'Status' -- BranchCode
,#SortOrder nvarchar(4) = 'Asc'
/*– Pagination Parameters */
,#PageNumber int = 0
,#PageSize int = 0
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SortCol nvarchar(20),
#FirstRec int,
#LastRec int,
#TotalRows int,
#GlobalSearch nvarchar(100),
#EULAVersionNumber nvarchar(100)
DECLARE #StatusKey INT =(SELECT dbo.GetStatusKey('ACTIVE'))
DECLARE #RowCountSelected INT
SELECT
#EULAVersionNumber = LTRIM(RTRIM(Value))
FROM #FilterParams
WHERE [FieldName] = 'EULAVersions'
SELECT
#GlobalSearch = LTRIM(RTRIM(Value))
FROM #FilterParams
WHERE [IsGlobal] = 1
SET #SortCol = LTRIM(RTRIM(#SortColumn))
SET #FirstRec = (#PageNumber - 1) * #PageSize
SET #LastRec = (#PageNumber * #PageSize + 1)
CREATE TABLE #ResultTempTable (
ROWNUM int
,ORGKEY int
,EULAVersionKey int
,EULAVersionNumber varchar(25)
,EULAVersionUpdateDate datetime
,STATUSKEY tinyint
,DocumentFileName varchar(100)
,DocumentGUID varchar(100)
,DocumentTypeName varchar(50)
,DocumentDescription varchar(128)
,ContactKey int
,ContactFirstName varchar(50)
,ContactMiddleName varchar(50)
,ContactLastName varchar(50)
,StatusName varchar(25)
)
insert into #ResultTempTable (
ROWNUM
,ORGKEY
,EULAVersionKey
,EULAVersionNumber
,EULAVersionUpdateDate
,STATUSKEY
,DocumentFileName
,DocumentGUID
,DocumentTypeName
,DocumentDescription
,ContactKey
,ContactFirstName
,ContactMiddleName
,ContactLastName
,StatusName
)
(
SELECT
ROW_NUMBER() OVER (ORDER BY
CASE
WHEN (#SortCol = 'EULAVersionNumber' AND
#SortOrder = 'ASC') THEN V.EULAVersionNumber
END ASC,
CASE
WHEN (#SortCol = 'EULAVersionNumber' AND
#SortOrder = 'DESC') THEN V.EULAVersionNumber
END DESC,
CASE
WHEN (#SortCol = 'DocumentFileName' AND
#SortOrder = 'ASC') THEN V.DocumentFileName
END ASC,
CASE
WHEN (#SortCol = 'DocumentFileName' AND
#SortOrder = 'DESC') THEN V.DocumentFileName
END DESC,
CASE
WHEN (#SortCol = 'EULAVersionUpdateDate' AND
#SortOrder = 'ASC') THEN convert(date, V.EULAVersionUpdateDate,103)
END ASC,
CASE
WHEN (#SortCol = 'EULAVersionUpdateDate' AND
#SortOrder = 'DESC') THEN convert(date, V.EULAVersionUpdateDate,103)
END DESC,
CASE
WHEN (#SortCol = 'ContactFirstName' AND
#SortOrder = 'ASC') THEN V.ContactFirstName
END ASC,
CASE
WHEN (#SortCol = 'ContactFirstName' AND
#SortOrder = 'DESC') THEN V.ContactFirstName
END DESC,
CASE
WHEN (#SortCol = 'StatusKey' AND
#SortOrder = 'ASC') THEN V.StatusKey
END ASC,
CASE
WHEN (#SortCol = 'StatusKey' AND
#SortOrder = 'DESC') THEN V.StatusKey
END DESC
) AS ROWNUM
,[ORGKEY]
,[EULAVersionKey]
,[EULAVersionNumber]
,[EULAVersionUpdateDate]
,[STATUSKEY]
,[DocumentFileName]
,[DocumentGUID]
,[DocumentTypeName]
,[DocumentDescription]
,[ContactKey]
,[ContactFirstName]
,[ContactMiddleName]
,[ContactLastName]
,[StatusName]
FROM (
SELECT
EUV.[ORGKEY]
,EUV.[EULAVersionKey]
,EUV.[EULAVersionNumber]
,EUV.[EULAVersionUpdateDate]
,EUV.[STATUSKEY]
,DOC.[DocumentFileName]
,DOC.[DocumentGUID]
,DOC.[DocumentDescription]
,DOCTYP.[DocumentTypeName]
,CN.[ContactKey]
,CN.[ContactFirstName]
,CN.[ContactMiddleName]
,CN.[ContactLastName]
,ST.[StatusName]
FROM [dbo].[EULAVersions] EUV
JOIN [dbo].[Documents] DOC
ON DOC.[DocumentKey] =EUV.[DocumentKey]
JOIN[dbo].[DocumentTypes] DOCTYP
ON DOCTYP.[DocumentTypeKey]=EUV.[DocumentTypeKey]
JOIN [dbo].[UserContacts] UC
ON UC.[UserKey]=EUv.[EULAVersionUpdatedBy]
JOIN [dbo].[Contacts] CN
ON CN.[ContactKey]=UC.[ContactKey]
JOIN [dbo].[StatusTypes] ST
ON ST.[StatusKey]=EUV.[StatusKey]
WHERE
EUV.[ORGKEY]=#OrgKey --AND EUV.[StatusKey]=#StatusKey
AND EUV.[EULAVersionNumber] LIKE '%' + ISNULL(#EULAVersionNumber, EULAVersionNumber) + '%'
AND EUV.[EULAVersionNumber] LIKE '%' + ISNULL(#GlobalSearch, EULAVersionNumber) + '%') AS V
)
IF (#PageNumber <> 0)
BEGIN
SELECT
#TotalRows = COUNT(1)
FROM #ResultTempTable AS CPC
WHERE ROWNUM BETWEEN #FirstRec AND CASE
WHEN #PageNumber = 0 THEN #TotalRows
ELSE #LastRec
END
SELECT
[ORGKEY]
,[EULAVersionKey]
,[EULAVersionNumber]
,[EULAVersionUpdateDate]
,[STATUSKEY]
,[DocumentFileName]
,[DocumentGUID]
,[DocumentDescription]
,[DocumentTypeName]
,[ContactFirstName]
,[ContactMiddleName]
,[ContactLastName]
,[StatusName]
FROM #ResultTempTable AS CPC
WHERE ROWNUM BETWEEN #FirstRec AND CASE
WHEN #PageNumber = 0 THEN #TotalRows
ELSE #LastRec
END
ORDER BY ROWNUM ASC
END
ELSE
BEGIN
SELECT
#TotalRows = COUNT(1)
FROM #ResultTempTable AS CPC
SELECT
[ORGKEY]
,[EULAVersionKey]
,[EULAVersionNumber]
,[EULAVersionUpdateDate]
,[STATUSKEY]
,[DocumentFileName]
,[DocumentGUID]
,[DocumentDescription]
,[DocumentTypeName]
,[ContactFirstName]
,[ContactMiddleName]
,[ContactLastName]
,[StatusName]
FROM #ResultTempTable AS CPC
ORDER BY ROWNUM ASC
END
SELECT #TotalRows AS TotalCount
IF OBJECT_ID('tempdb..#ResultTempTable') IS NOT NULL
DROP TABLE #ResultTempTable
END
--FilterTypes Details
CREATE TYPE [dbo].[FilterTypes] AS TABLE(
[FieldName] [varchar](100) NOT NULL,
[Value] [varchar](800) NOT NULL,
[IsGlobal] [bit] NULL DEFAULT ((0))
)
Sample Exec
declare #FilterParams AS FilterTypes;
insert into #FilterParams values('EULAVersions','',1)
exec [usp_GetEULADetails] 2,#FilterParams,'EULAVersionUpdateDate','desc',0,0
Obtained Result
Expected Result
declare #FilterParams AS FilterTypes;
insert into #FilterParams values('EULAVersions','',1)
exec [usp_GetEULADetails] 2,#FilterParams,'ContactFirstName','desc',0,0
The issue I face is how to properly sort the data when data type is of datetime ?
Thanks for the help in advance....
You are converting 'V.EULAVersionUpdateDate' to date DataType (...THEN convert(date, V.EULAVersionUpdateDate,103)) , use DATETIME Datatype to convert
THEN convert(DateTime, V.EULAVersionUpdateDate,103)

Values from 2 variables are being swapped in stored procedure

I have modified a stored procedure and added an extra parameter to be added to a table. The problem is the value for the added parameter is being swapped with an original parameter.
ALTER PROCEDURE [dbo].[spWeb_BulkGenerateWRsDevices]
(
#WorkRequestDeviceId nvarchar(max) = NULL,
#TechnicianId int = NULL,
#RequiredBy datetime = NULL,
#Priority int = NULL,
#WRTypeId int,
#WorkRequestSummary nvarchar(255) = NULL,
#AuthorOfRequest int,
#Contact nvarchar(40) = NULL,
#PhoneNo nvarchar(20) = NULL,
#StatusId int,
#Created datetime = NULL,
#CustomerId int
)
AS
/* Update the WR record */
BEGIN
DECLARE #COUNT INT
SET #COUNT =(SELECT COUNT(*) FROM WorkRequest WHERE WorkRequestDeviceId IN(SELECT stringval FROM dbo.CSV(#WorkRequestDeviceId)))
IF #COUNT >0
BEGIN
DECLARE #InsertedRows AS TABLE (WorkRequestId int,WorkRequestDeviceId int)
INSERT INTO WorkRequest
(AllocatedTo,RequiredBy,Priority,WRTypeId,WorkRequestSummary,AuthorOfRequest,
Contact,PhoneNo,StatusId,DateOfRequest,WorkRequestDeviceId,CustomerId)
OUTPUT Inserted.WorkRequestId,Inserted.WorkRequestDeviceId INTO #InsertedRows
SELECT #TechnicianId ,#RequiredBy,#Priority,#WRTypeId,#WorkRequestSummary,#AuthorOfRequest,#Contact
,#PhoneNo,#StatusId,#Created,#CustomerId,* from dbo.fnSplit(#WorkRequestDeviceId, ',')
END
IF #COUNT = 0
BEGIN
INSERT INTO WorkRequest
(WorkRequestDeviceId)
SELECT * from dbo.fnSplit(#WorkRequestDeviceId, ',')
UPDATE WorkRequest
SET
AllocatedTo =#TechnicianId ,
RequiredBy = #RequiredBy,
Priority = #Priority,
WRTypeId = #WRTypeId,
WorkRequestSummary =#WorkRequestSummary,
AuthorOfRequest= #AuthorOfRequest,
Contact = #Contact,
PhoneNo = #PhoneNo,
StatusId = #StatusId,
DateOfRequest = #Created,
CustomerId = #CustomerId
WHERE WorkRequestDeviceId IN(SELECT stringval FROM dbo.CSV(#WorkRequestDeviceId))
END
I have added the CustomerId parameter. When I call the procedure and say set WorkRequestDeviceId = 312 and CustomerId = 148 the table WorkRequest has a new record but with WorkRequestDeviceId = 148 and CustomerId = 312. I am new to stored procedure so sorry for my ignorance, any ideas?
James
Your insert is transposing the variables in the insert statement and the select.
Change your insert to read:
INSERT INTO WorkRequest
(AllocatedTo,RequiredBy,Priority,WRTypeId,WorkRequestSummary,AuthorOfRequest,
Contact,PhoneNo,StatusId,DateOfRequest,CustomerId,WorkRequestDeviceId)
And all should be fine.

SQL Server recursive CTE and paging

I have this table
CREATE TABLE [dbo].[friend_blocked_list](
[subdomain] [varchar](50) NOT NULL,
[un] [nvarchar](50) NOT NULL,
[friend] [nvarchar](50) NOT NULL,
[is_blocked] [bit] NOT NULL,
[approved] [bit] NOT NULL)
where i select data from it with below query. Select query combines users that added user as friend and users that have been added as friend by user
declare #un varchar(50), #subdomain varchar(50)
set #un='user2';
set #subdomain ='test.domain.com';
WITH FRIENDS as
(
SELECT friend
FROM friend_blocked_list
WHERE un=#un and subdomain=#subdomain and approved=1 and is_blocked=0
UNION ALL
SELECT un as friend
FROM friend_blocked_list
WHERE friend=#un and subdomain=#subdomain and approved=1 and is_blocked=0
)
select friend from FRIENDS group by FRIENDS.friend order by FRIENDS.friend asc
It works fine with small amout of data but i want to be able to do a paging on the server side in order to reduce load. I am trying to combine it with my paging sp below
create PROCEDURE [dbo].[Paging]
#subdomain varchar(50),
#un varchar(50),
#PageNumber int,
#PageSize int
AS
BEGIN
--paging
DECLARE #FirstRow INT,#LastRow INT,#RowCount INT,#PageCount INT
--find recordcount and pages
SELECT #RowCount = COUNT(*), #PageCount = COUNT(*) / #PageSize
FROM friend_blocked_list
WHERE subdomain=#subdomain AND un=#un AND approved=1 AND is_blocked=0;
--- calculate pages
IF #RowCount % #PageSize != 0 SET #PageCount = #PageCount + 1
IF #PageNumber < 1 SET #PageNumber = 1
IF #PageNumber > #PageCount SET #PageNumber = #PageCount
SELECT
CurrentPage = #PageNumber,
TotalPages = #PageCount,
TotalRows = #RowCount
-- mora calculation
SELECT #FirstRow = ( #PageNumber - 1) * #PageSize + 1,
#LastRow = (#PageNumber - 1) * #PageSize + #PageSize ;
WITH MyTopics AS
(
SELECT *, ROW_NUMBER() OVER (order by un asc) AS RowNumber
FROM friend_blocked_list
WHERE subdomain=#subdomain AND un=#un AND approved=1 AND is_blocked=0
)
SELECT *
FROM MyTopics
WHERE RowNumber BETWEEN #FirstRow AND #LastRow
ORDER BY RowNumber ASC;
end
But as always i am having trouble :). Main problem is the UNION ALL in my query. It prevents me using ROW_NUMBER() OVER.
Any ideas?
Here's your procedure updated for paging:
CREATE PROCEDURE [dbo].[Paging]
#subdomain varchar(50),
#un varchar(50),
#PageNumber int,
#PageSize int
AS
DECLARE #start_row int
DECLARE #end_row int
SET #end_row = #PageNumber * #PageSize
SET #start_row = #end_row - (#PageSize - 1)
BEGIN
WITH FRIENDS AS (
SELECT t.friend
FROM FRIEND_BLOCKED_LIST t
WHERE t.un = #un
AND t.subdomain = #subdomain
AND t.approved = 1
AND t.is_blocked = 0
UNION ALL
SELECT t.un as friend
FROM FRIEND_BLOCKED_LIST t
WHERE t.friend = #un
AND t.subdomain = #subdomain
AND t.approved = 1
AND t.is_blocked = 0)
SELECT t.friend
FROM (SELECT f.friend,
ROW_NUMBER() OVER (ORDER BY f.friend) AS rownum
FROM FRIENDS f
GROUP BY f.friend) t
WHERE t.rownum BETWEEN #start_row AND #end_row
END
It might be possible to change the query to use one CTE if you could provide more information on the FRIEND_BLOCKED_LIST table. The UNION of two queries with identical WHERE clauses while differentiating between two columns makes me wonder if it couldn't be written better. Could the FRIENDS CTE be rewritten as:
SELECT COALESCE(t.un, t.friend) as friend
FROM FRIEND_BLOCKED_LIST t
WHERE #un = COALESCE(t.un, t.friend)
AND t.subdomain = #subdomain
AND t.approved = 1
AND t.is_blocked = 0
Apply the row number to the list you want to return:
WITH FRIENDS as
(
SELECT friend
FROM friend_blocked_list
WHERE un=#un and subdomain=#subdomain and approved=1 and is_blocked=0
UNION ALL
SELECT un as friend
FROM friend_blocked_list
WHERE friend=#un and subdomain=#subdomain and approved=1 and is_blocked=0 )
, recursive_friends as (
select friend
, row_number() over (order by friend asc) as rn
from FRIENDS )
select friend
from recursive_friends
where rn between #firstRow and #lastRow
order by FRIENDS.friend asc;

Resources