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
Related
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
Right now I am using 3 stored procedures to Add a person to the person.person table. I would like to cut this down to a single stored procedure to resolve this issue.
INSERT new GUID and DateModified to table Person.BusinessEntity
SELECT the auto generate BusinessEntityID form table Person.BusinessEntity
INSERT new Person to Person.Person Table
The Stored Procedures all use parameters which I pass via a C# application and I have confirmed that the a user is in fact added to the AdventureWorks2019 Db.
Procedure: Person.CreateNewBusinessEntity
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
VALUES
(
#RowGUID
, GetDate()
)
Procedure: Person.GetBusinessEntityID
SELECT
[BusinessEntityID]
FROM
[AdventureWorks2019].[Person].[BusinessEntity]
WHERE [rowguid] = #RowGuid
Procedure: Person.CreateNewPerson
INSERT INTO [Person].[Person]
(
[BusinessEntityID]
,[PersonType]
,[NameStyle]
,[Title]
,[FirstName]
,[MiddleName]
,[LastName]
,[Suffix]
,[EmailPromotion]
,[AdditionalContactInfo]
,[Demographics]
,[rowguid]
,[ModifiedDate]
)
VALUES
(
#BusinessEntityID
, #PersonType
, #NameStyle
, #Title
, #FirstName
, #MiddleName
, #LastName
, #Suffix
, #EmailPromotion
, #AdditionalContactInfo
, #Demographics
, #RowGUID
, GetDate()
)
Any help here is appreciated. Thanks!
Thanks to HABO, I am now using this solution. Now I only need two procedures.
DECLARE #Inserted table ( [BusinessEntityID] int );
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
OUTPUT inserted.[BusinessEntityID] INTO #Inserted([BusinessEntityID])
VALUES
(
#RowGUID
, GetDate()
)
The below answer shows you how to get the inserted id and add it to the next insert in side the Same SP.
USE AdventureWorks2012
GO
CREATE PROC CreateNewPerson
AS
BEGIN
DECLARE #OutputTbl TABLE ([BusinessEntityID] INT, ModifiedDate DATETIME)
DECLARE #BusinessEntityID AS INT
INSERT INTO [Person].[BusinessEntity]
(
[BusinessEntity].rowguid
, [BusinessEntity].ModifiedDate
)
--Get the output value inserted to a table.
OUTPUT inserted.[BusinessEntityID], inserted.ModifiedDate INTO
#OutputTbl([BusinessEntityID],[ModifiedDate])
VALUES
(
NEWID()
, GetDate()
)
--Assigned to a variable. You can get this using subquery as well inside the insert statment.
SELECT #BusinessEntityID = [BusinessEntityID] FROM #OutputTbl
INSERT INTO [Person].[Person]
(
[BusinessEntityID]
,[PersonType]
,[NameStyle]
,[Title]
,[FirstName]
,[MiddleName]
,[LastName]
,[Suffix]
,[EmailPromotion]
,[AdditionalContactInfo]
,[Demographics]
,[rowguid]
,[ModifiedDate]
)
VALUES
(
#BusinessEntityID
, #PersonType --These columns with # sign needed to be declared or supply values
, #NameStyle
, #Title
, #FirstName
, #MiddleName
, #LastName
, #Suffix
, #EmailPromotion
, #AdditionalContactInfo
, #Demographics
, NEWID() --This will generate a new GUID for each row.
, GetDate()
)
END
GO
Second way is using Scope_identity(). Replace the
"SELECT #BusinessEntityID = [BusinessEntityID] FROM #OutputTbl'
from below lines in the Sp will do the same thing for you.
SELECT #BusinessEntityID = SCOPE_IDENTITY() --[BusinessEntityID] FROM #OutputTbl
Select #BusinessEntityID
We are creating a view as follows:
create view [dca].[CodeDescriptions_VW]
as
select distinct
ek.EmpKey
, RTRIM(CONVERT(varchar(60), abt.fdesc)) AS AboriginalTypeDescription
, RTRIM(CONVERT(varchar(60), cma.fdesc)) AS CensusMetroAreaDescription
, RTRIM(CONVERT(varchar(60), q.c_desc)) AS CobraCodeDescription
, RTRIM(CONVERT(varchar(60), ct.fdesc)) AS ConsentTypeDescription
, RTRIM(CONVERT(varchar(60), li.fdesc)) AS DirectOrIndirectDescription
, RTRIM(CONVERT(varchar(60), dt.fdesc)) AS DisabilityTypeDescription
, RTRIM(CONVERT(varchar(60), doca.fdesc)) AS DocumentADescription
FROM
dbo.hrpersnl AS h
INNER JOIN
HRActions.dbo.EmployeeKey AS ek ON RTRIM(LTRIM(UPPER(h.p_empno))) = UPPER(ek.EmpNo) COLLATE SQL_Latin1_General_CP1_CI_AS
AND h.p_company = ek.Company COLLATE SQL_Latin1_General_CP1_CI_AS
LEFT OUTER JOIN
dbo.hrtables AS abt ON abt.ftable = ''AL'' AND RTRIM(h.p_abotype) = RTRIM(abt.code)
LEFT OUTER JOIN
dbo.hrtables AS cma ON cma.ftable = ''CM'' AND RTRIM(h.p_cma) = RTRIM(cma.code)
LEFT OUTER JOIN
dbo.hrtables AS ct ON ct.ftable = ''CS'' AND RTRIM(h.p_constype) = RTRIM(ct.code)
LEFT OUTER JOIN
dbo.hrtables AS li ON li.ftable = ''IN'' AND RTRIM(h.p_laborind) = RTRIM(li.code)
LEFT OUTER JOIN
dbo.hrtables AS dt ON dt.ftable = ''DI'' AND RTRIM(h.p_distype) = RTRIM(dt.code)
LEFT OUTER JOIN
dbo.hrtables AS doca ON doca.ftable = ''I2'' AND RTRIM(h.p_doca) = RTRIM(doca.code)
I am wondering if there is a more efficient way to reference the same table (dbo.hratables) multiple times. As is, this is a very costly view (there are actually about 3 dozen different 'Descriptions' that we need to query, I have only shown a few).
While not ideal, perhaps you could create an in-line TVF and use that vs all the joins.
Something like:
CREATE FUNCTION dbo.HRDescription (
#ftable VARCHAR(2), #code VARCHAR(50), #field VARCHAR(50)
)
RETURNS TABLE
AS
RETURN
(
SELECT RTRIM( CONVERT( VARCHAR(60),
CASE
WHEN #field = 'c_desc' THEN c_desc
ELSE fdesc
END ) ) AS [Value]
FROM dbo.hrtables
WHERE
ftable = #ftable AND RTRIM( code ) = #code
)
GO
And then modify your query:
SELECT DISTINCT
ek.EmpKey
, ( SELECT [Value] FROM dbo.HRDescription( 'AL', h.p_abotype, 'fdesc' ) ) AS AboriginalTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'CM', h.p_cma, 'fdesc' ) ) AS CensusMetroAreaDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'CS', h.p_constype, 'fdesc' ) ) AS ConsentTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'IN', h.p_laborind, 'fdesc' ) ) AS DirectOrIndirectDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'DI', h.p_distype, 'fdesc' ) ) AS DisabilityTypeDescription
, ( SELECT [Value] FROM dbo.HRDescription( 'I2', h.p_doca, 'fdesc' ) ) AS DocumentADescription
FROM dbo.hrpersnl AS h
INNER JOIN HRActions.dbo.EmployeeKey AS ek
ON RTRIM(LTRIM(UPPER(h.p_empno))) = UPPER(ek.EmpNo) COLLATE SQL_Latin1_General_CP1_CI_AS
AND h.p_company = ek.Company COLLATE SQL_Latin1_General_CP1_CI_AS;
Again, not ideal, but it may save on performance over the joins.
I tried to implement procedure which main goal is to store data into new separate table.First I create table which I want to populate with data
CREATE TABLE dbo.CustomerReportLogs (
ID int IDENTITY (1,1) NOT NULL,
CustomerFullName NVARCHAR(100) NULL,
LocationName NVARCHAR(100) NULL,
Amount decimal (18,2) NULL,
Currency NVARCHAR (20) NULL,
EmployeeId int NULL,
ValidFrom date NULL,
ValidTo date NULL,
CONSTRAINT PK_ID_CustomerReportLogs PRIMARY KEY CLUSTERED (
ID ASC
))
GO
So next step is how to populate this table with stored procedure. I order to do this I wrote this lines of code:
CREATE OR ALTER PROCEDURE dbo.procedure2 (#CustomerId int, #validFrom date, #ValidTo date,#EmployeeID int)
AS
BEGIN
SELECT CONCAT(c.FirstName, ' ', c.LastName) AS CustomerFullName, lo.Name as LocationName,acd.Amount as Amount,cu.Name as Currency,acc.EmployeeId,#validFrom as ValidFrom,#ValidTo as ValidTo
FROM dbo.Customer as c
INNER JOIN dbo.Account AS acc ON acc.CurrencyId=c.Id
INNER JOIN dbo.AccountDetails AS acd ON acd.AccountId=acc.Id
INNER JOIN dbo.Currency AS cu ON cu.id=acc.CurrencyId
INNER JOIN dbo.Location as lo ON lo.Id=acd.LocationId
INNER JOIN dbo.Employee AS emp ON emp.ID=acc.EmployeeId
WHERE acc.CustomerId=#CustomerId and acd.TransactionDate between #validFrom and #ValidTo and acc.EmployeeId=#EmployeeID
DECLARE #CustomerFullName NVARCHAR(100)
DECLARE #LocationName NVARCHAR(100)
DECLARE #Amount decimal (18,2)
DECLARE #Currency NVARCHAR (20)
INSERT INTO dbo.CustomerReportLogs(CustomerFullName,LocationName,Amount,Currency,EmployeeId,ValidFrom,ValidTo)
VALUES (#CustomerFullName,#LocationName,#Amount,#Currency,#EmployeeId,#ValidFrom,#ValidTo)
SELECT #CustomerFullName as CustomerFullName,#LocationName AS LocationName,#Amount AS Amount,#Currency as Currency,
#EmployeeId as EmployeeId,#ValidFrom as ValidFrom ,#ValidTo as ValidTo
END
GO
Above line code create stored procudure but now new problem arise namely when I try to execute first whit this command
EXEC dbo.procedure2 #CustomerId=8,#validFrom='2019.01.25', #ValidTo='2019.03.01', #EmployeeID=8
So this procedure can't update properly dbo.CustomerReportLogs so I got some results with null and some with values.Output you can see on pic below:
[![enter image description here][1]][1]
So can anybody help me how to update this table properly not with null
CREATE OR ALTER PROCEDURE dbo.procedure2 (
#CustomerId INT
,#validFrom DATE
,#ValidTo DATE
,#EmployeeID INT
)
AS
BEGIN
INSERT INTO dbo.CustomerReportLogs (
CustomerFullName
,LocationName
,Amount
,Currency
,EmployeeId
,ValidFrom
,ValidTo
)
OUTPUT INSERTED.[CustomerFullName],INSERTED.[LocationName],INSERTED.[Amount],INSERTED.[Currency],INSERTED.[EmployeeId],INSERTED.[ValidFrom] ,INSERTED.[ValidTo]
SELECT CONCAT (c.FirstName,' ',c.LastName) AS CustomerFullName
,lo.Name AS LocationName
,acd.Amount AS Amount
,cu.Name AS Currency
,acc.EmployeeId
,#validFrom AS ValidFrom
,#ValidTo AS ValidTo
FROM dbo.Customer AS c
INNER JOIN dbo.Account AS acc ON acc.CurrencyId = c.Id
INNER JOIN dbo.AccountDetails AS acd ON acd.AccountId = acc.Id
INNER JOIN dbo.Currency AS cu ON cu.id = acc.CurrencyId
INNER JOIN dbo.Location AS lo ON lo.Id = acd.LocationId
INNER JOIN dbo.Employee AS emp ON emp.ID = acc.EmployeeId
WHERE acc.CustomerId = #CustomerId
AND acd.TransactionDate BETWEEN #validFrom
AND #ValidTo
AND acc.EmployeeId = #EmployeeID
END
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