Passing parametrs to dynamic query - sql

I have a stored procedure as following, I need to pass paramters to the dynamic pivot. My query runs, I just need to do some filtering based on the passed parameters
-- AND (#SelectedSystemIDs IS NULL OR System.ID IN(select * from dbo.SplitInts_RBAR_1(#SelectedSystemIDs, ',')))
--AND ((#PlatformID IS NULL) OR (System.PlatformID = #PlatformID) OR (#PlatformID = 12 AND System.PlatformID <= 2))
-- AND (ServiceEntry.ServiceDateTime between #StartDate and #EndDate)
so I want to add the above criteria, how could achieve that?
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int
)
AS
DECLARE #InstrumentType int = NULL
DECLARE #PlatformID int = null
IF (#SelectedSystemIDs = '')
begin
SET #SelectedSystemIDs = NULL
END
IF (#SelectedTsbIDs = '')
begin
SET #SelectedTsbIDs = NULL
END
IF(#UserRoleID = 1)
BEGIN
SET #PlatformID = 1
END
IF(#UserRoleID = 2)
BEGIN
SET #PlatformID = 2
END
IF (#UserRoleID = 3)
BEGIN
SET #PlatformID = 12
END
IF(#UserRoleID = 4)
BEGIN
SET #PlatformID = 3
END
IF(#UserRoleID = 5)
BEGIN
SET #PlatformID = 4
END
IF(#UserRoleID = 6)
BEGIN
SET #PlatformID = NULL
END
DECLARE #PivotColumnHeaders NVARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + cast(SystemFullName as Nvarchar) + ']',
'[' + cast(SystemFullName as varchar)+ ']'
)
FROM System
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE(#PivotTableSQL)

you can construct the required criteria as another input to the stored procedure and append it to the dynamic query
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int,
#WhereClause varchar(max) -> this is the new parameter.
)
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
' + #WhereClause -> you can append the where clause here.
EXECUTE(#PivotTableSQL)

Related

Error in using SELECT to set a variable value in SQL

I have following stored procedure and I have identified the issue with the stored procedure is that using select to set the value of #DeliveryAddress variable and so for all the Letter Requests raised it is only retaining the last value which is in Requests. I tried using SET by explicitly setting each value used in #DeliveryAddresss Calculation but of no use as I ended of getting error that subquery returns multiple rows.
I am unable to understand what shall I change in this SP, so that for each value in #Requests, a different #deliveryAddress value is set and used for insertion in LetterRequest table. Please help.
Note #WorkFlowAcct is a temp table having around 10 unique AccountIds and for each account we have atleast one debtorid.
ALTER PROCEDURE [dbo].[WorkFlow_Action_RequestLetterPref]
AS
DECLARE #LetterID INTEGER;
DECLARE #LetterType CHAR(3);
DECLARE #LetterDescription VARCHAR(50);
DECLARE #JobName VARCHAR(256);
DECLARE #DateCreated DATETIME;
DECLARE #DeliveryMethod VARCHAR(7);
DECLARE #DeliveryAddress VARCHAR(1023);
SELECT #LetterID = [LetterID],
#LetterType = CASE
WHEN [type] IN ('SIF', 'PIF', 'PPS', 'PDC', 'ATT', 'CUS') THEN [type]
ELSE 'DUN'
END,
#LetterDescription = ISNULL([Description], ''),
FROM [dbo].[letter]
WHERE [code] = #LetterCode;
DECLARE #Requests TABLE (
[AccountID] INTEGER NOT NULL,
[DebtorID] INTEGER NOT NULL,
[Seq] INTEGER NOT NULL,
[ErrorMessage] VARCHAR(500) NULL
);
IF #PrimaryDebtor = 1 OR #LetterType IN ('CUS', 'ATT') BEGIN
INSERT INTO #Requests ([AccountID], [DebtorID], [Seq])
SELECT DISTINCT [master].[number] AS [AccountID],
[Debtors].[DebtorID] AS [DebtorID],
[Debtors].[Seq] AS [Seq],
FROM #WorkFlowAcct AS [WorkFlowAcct]
INNER JOIN [dbo].[master] WITH (NOLOCK)
ON [WorkFlowAcct].[AccountID] = [master].[number]
INNER JOIN [dbo].[customer] WITH (NOLOCK)
ON [master].[customer] = [customer].[customer]
INNER JOIN [dbo].[Debtors] WITH (NOLOCK)
ON [master].[number] = [Debtors].[number]
AND [Debtors].[Seq] = [master].[PSeq]
LEFT OUTER JOIN [dbo].[DebtorAttorneys]
ON [Debtors].[DebtorID] = [DebtorAttorneys].[DebtorID];
END;
DECLARE #Street1 VARCHAR(512);
DECLARE #Street2 VARCHAR(512);
DECLARE #City VARCHAR(512);
DECLARE #Country VARCHAR(512);
DECLARE #Zip VARCHAR(512);
IF #Pref = 'Letter'
BEGIN
SET #DeliveryMethod = 'Letter';
SELECT #DeliveryAddress = [Street1] + ' ' + [Street2] + ' ' + [City] + ' ' + [Zipcode] + ' ' + [Country], #Street1 = [Street1], #Street2 = [Street2], #City = [City], #Country = [Country], #Zip = [ZipCode] FROM [Debtors] inner join #Requests AS Requests on [Debtors].[DebtorID] = Requests.[DebtorID] AND [Street1] IS NOT NULL;
IF #Street2 IS NULL
BEGIN
SET #DeliveryAddress = #Street1 + ' ' + #City + ' ' + #Zip + ' ' + #Country;
END
END
SET #DateCreated = GETDATE();
SET #JobName = 'WorkFlow_' + CAST(NEWID() AS CHAR(36)) + CAST(NEWID() AS CHAR(36)) + CAST(NEWID() AS CHAR(36)) + CONVERT(VARCHAR(50), GETDATE(), 126);
BEGIN TRANSACTION;
--Updated params for current Letter Request Table
INSERT INTO [dbo].[LetterRequest] ([AccountID], [LetterID], [LetterCode], [DeliveryMethod], [DeliveryAddress])
SELECT [Requests].[AccountID],
[Requests].[CustomerCode],
#LetterID AS [LetterID],
#LetterCode AS [LetterCode],
#DeliveryMethod AS [DeliveryMethod],
#DeliveryAddress AS [DeliveryAddress]
FROM #Requests AS [Requests]
INNER JOIN #AllowedCustomers AS [AllowedCustomers]
ON [Requests].[CustomerCode] = [AllowedCustomers].[CustomerCode]
WHERE [Requests].[ErrorMessage] IS NULL;
COMMIT TRANSACTION;
RETURN 0;

How to execute the sql function

How can I execute this function?
I tried as Select [dbo].[GetPaidInfo]("1"), but I get the error:
An insufficient number of arguments were supplied for the procedure or
function dbo.GetPaidInfo.
USE [PCJ_BM]
GO
/****** Object: UserDefinedFunction [dbo].[GetPaidInfo] Script Date: 3/24/2018 5:05:15 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetPaidInfo] (
#InvId INT
,#PmtType VARCHAR(10)
)
RETURNS NVARCHAR(200)
AS
BEGIN
-- Declare the return variable here
DECLARE #PaidInfo NVARCHAR(200)
DECLARE #payment2 VARCHAR(50) = ''
DECLARE #payment3 VARCHAR(50) = ''
DECLARE #card VARCHAR(50) = (
SELECT Card
FROM Payment
WHERE (InvId = #InvId)
)
DECLARE #Currency2 VARCHAR(50) = (
SELECT Currency2
FROM Payment
WHERE (InvId = #InvId)
)
DECLARE #Amt2 VARCHAR(50) = (
SELECT Amt2
FROM Payment
WHERE (InvId = #InvId)
)
DECLARE #Currency3 VARCHAR(50) = (
SELECT Currency3
FROM Payment
WHERE (InvId = #InvId)
)
DECLARE #Amt3 VARCHAR(50) = (
SELECT Amt3
FROM Payment
WHERE (InvId = #InvId)
)
IF (#PmtType = 'Cash')
BEGIN
IF (#Currency2 != NULL OR #Currency2 != '')
BEGIN
SET #payment2 = ' + ' + #Currency2 + ' ' + #Amt2
END
IF (#Currency3 != NULL OR #Currency3 != '')
BEGIN
SET #payment3 = ' + ' + #Currency3 + ' ' + #Amt3
END
SET #PaidInfo = (
SELECT 'Paid in Cash by ' + Currency1 + ' ' + CONVERT(VARCHAR, Amt1) + #payment2 + #payment3
FROM Payment
WHERE (InvId = #InvId)
)
END
ELSE
BEGIN
SET #PaidInfo = (
SELECT 'Paid in Card by ' + CONVERT(VARCHAR, Amt1) --, Currency2, Amt2, Currency3, Amt3
FROM Payment
WHERE (InvId = #InvId)
)
END
-- Return the result of the function
RETURN #PaidInfo
END
My table looks like:
Call your function like this (INT no quotes, VARCHAR(10) single quotes):
SELECT [dbo].[GetPaidInfo] (1,'Cash');
Be aware your function returns NVARCHAR(200).
It appears you are planning to concatenate some information there, so if you start to see some of your string truncated, you might want to increase the length.
As per function definition, it requires 2 params : #InvId & #PmtType.
You should pass both of them during function call like follows:-
SELECT dbo.GetPaidInfo(2, 'Card');

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.

Dynamic TSQL Query output as XML

I have a dynamic TSQL query that is working perfectly. However, before I had it dynamic like this I was returning it as an XML output.
How can I do the same with my output now? I need the results in an XML format.
ALTER PROCEDURE [dbo].[empowermentFetchSubmissions2]
#category INT=NULL, #department INT=NULL, #startDate DATE=NULL, #endDate DATE=NULL, #empID VARCHAR (60)=NULL, #submissionID INT=NULL, #inVoting INT=NULL, #pastWinners INT=NULL
AS
DECLARE #sSQL AS NVARCHAR (3000),
#Where AS NVARCHAR (1000) = ' (1=1) ';
BEGIN
SET NOCOUNT ON;
BEGIN
SET #sSQL = 'SELECT A.[submissionID],
A.[subEmpID],
A.[nomineeEmpID],
A.[nomineeDepartment],
CONVERT (VARCHAR (10), A.[submissionDate], 101) AS submissionDate,
A.[situation],
A.[task],
A.[action],
A.[result],
A.[timestamp],
A.[statusID],
A.[approver],
A.[approvalDate],
B.[FirstName] + '' '' + B.[LastName] AS nomineeName,
B.[ntid] AS nomineeNTID,
B.[qid] AS nomineeQID,
C.[FirstName] + '' '' + C.[LastName] AS submitName,
C.[ntid] AS submitNTID,
D.[categoryName],
(SELECT CAST
(CASE WHEN EXISTS (SELECT TOP (1) submissionID
FROM empowermentEntries
WHERE sessionID = (SELECT TOP (1) sessionID
FROM empowermentSessions
WHERE status = 1
AND CAST(GETDATE() as date) >= startDate
AND CAST(GETDATE() as date) <= endDate ) AND submissionID = A.[submissionID])
THEN ''true''
ELSE ''false''
END AS XML) AS inVoting)
FROM empowermentSubmissions AS A
INNER JOIN
empTable AS B
ON A.[nomineeEmpID] = B.[empID]
INNER JOIN
empTable AS C
ON A.[subEmpID] = C.[empID]
INNER JOIN
empowermentCategories AS D
ON A.[categoryID] = D.[catID]';
IF #category IS NOT NULL
SET #Where = #Where + ' AND A.[categoryID] = #_category';
IF #department IS NOT NULL
SET #Where = #Where + ' AND A.[nomineeDepartment] = #_department';
IF #startDate IS NOT NULL
SET #Where = #Where + ' AND A.[submissionDate] >= #_startDate';
IF #endDate IS NOT NULL
SET #Where = #Where + ' AND A.[submissionDate] <= #_endDate';
IF #empID IS NOT NULL
SET #Where = #Where + ' AND A.[nomineeEmpID] = #_empID';
IF #submissionID IS NOT NULL
SET #Where = #Where + ' AND A.[submissionID] = #_submissionID';
IF #inVoting IS NOT NULL
SET #Where = #Where + ' AND A.[submissionID] IN (SELECT submissionID
FROM empowermentEntries
WHERE sessionID = (SELECT TOP (1) sessionID
FROM empowermentSessions
WHERE status = 1
AND CAST(GETDATE() as date) >= startDate
AND CAST(GETDATE() as date) <= endDate )
AND submissionID = A.[submissionID])';
IF #pastWinners IS NOT NULL
SET #Where = #Where + ' AND A.[submissionID] IN (SELECT E.[submissionID]
FROM empowermentEntries as E
JOIN empowermentWinners as F
ON E.[entryID] = F.[entryID]
WHERE submissionID = A.[submissionID])';
IF LEN(#Where) > 0
SET #sSQL = #sSQL + ' WHERE ' + #Where;
EXECUTE sp_executesql #sSQL, N'#_category INT, #_department INT, #_startDate DATE, #_endDate DATE, #_empID VARCHAR(60), #_submissionID INT, #_inVoting INT, #_pastWinners INT', #_category = #category, #_department = #department, #_startDate = #startDate, #_endDate = #endDate, #_empID = #empID, #_submissionID = #submissionID, #_inVoting = #inVoting, #_pastWinners = #pastWinners;
END
END
You need to take your existing Dynamic SQL, added the FOR XML... to the end, wrap that in parenthesis, and set that value to a variable which is used as OUTPUT for the sp_executesql. For example:
DECLARE #SQL NVARCHAR(MAX),
#Results XML;
SET #SQL = N'
SET #Out = (SELECT * FROM sys.objects FOR XML AUTO);
';
EXEC sp_executesql #SQL, N'#Out XML OUTPUT', #Out = #Results OUTPUT;
SELECT #Results;
So declare a new variable at the top for:
DECLARE #Results XML;
Then just before your EXECUTE sp_executesql #sSQL... line, do the following:
SET #sSQL = N'SET #Results = (' + #sSQL + N' FOR XML {xml options});';
Then update your param spec for sp_executesql to include, at the end:
N'#_category INT, ..., #Results XML OUTPUT'
And add the following to the end of the sp_executesql:
#_category = #category, ..., #Out = #Results OUTPUT

Update TableType variable in dynamic SQL query

I had created User defined table type in my database. After that I had declared a variable of that table type in my procedure. And I had return my rest of the logic. At the end I am trying to update that table type variable using dynamic SQL.
But I got an error:
Msg 10700, Level 16, State 1, Line 1
The table-valued parameter "#ttbl_TagList" is READONLY and cannot be modified.
How can I solve the error?
User defined table type:
CREATE TYPE [dbo].[tt_TagList] AS TABLE(
[tagListId] [tinyint] IDENTITY(1,1) NOT NULL,
[tagId] [tinyint] NOT NULL DEFAULT ((0)),
[tagName] [varchar](100) NOT NULL DEFAULT (''),
[tagValue] [nvarchar](max) NOT NULL DEFAULT ('')
)
GO
Procedure:
CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ttbl_TagList dbo.tt_TagList, #V_TagId INT, #V_Counter TINYINT = 1,
#V_FinalQuery NVARCHAR(MAX) = '', #V_TagValue NVARCHAR(MAX);
INSERT INTO #ttbl_TagList (tagId, tagName, tagValue)
SELECT DISTINCT T.tagId, T.tagName, '' AS tagValue
FROM dbo.tbl_Tag T;
WHILE (1 = 1)
BEGIN
SET #V_TagValue = '';
SELECT #V_TagId = tagId FROM #ttbl_TagList WHERE tagListId = #V_Counter;
IF (##ROWCOUNT = 0)
BEGIN
BREAK;
END
IF (#V_TagId = 1)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 1';
END
ELSE IF (#V_TagId = 2)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 2';
END
ELSE IF (#V_TagId = 3)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 3';
END
ELSE IF (#V_TagId = 4)
BEGIN
/* Logic for getting tag value */
SET #V_TagValue = 'Tag Value 4';
END
IF (#V_TagValue != '')
BEGIN
SET #V_FinalQuery = #V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), #V_Counter) + ' THEN ''' + #V_TagValue + '''';
END
SET #V_Counter = #V_Counter + 1;
END
IF (#V_FinalQuery != '')
BEGIN
SET #V_FinalQuery = N'UPDATE #ttbl_TagList SET tagValue = (CASE tagListId' + #V_FinalQuery + ' END)';
EXECUTE sp_executesql #V_FinalQuery, N'#ttbl_TagList dbo.tt_TagList readonly', #ttbl_TagList;
END
SELECT * FROM #ttbl_TagList;
END
TVP can not be updated directly. So try this one -
CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('tempdb.dbo.#t1') IS NOT NULL
DROP TABLE #t1
DECLARE
#ttbl_TagList dbo.tt_TagList
, #V_Counter TINYINT = 1
, #V_FinalQuery NVARCHAR(MAX) = ''
, #V_TagValue NVARCHAR(MAX);
INSERT INTO #ttbl_TagList (tagId, tagName, tagValue)
SELECT DISTINCT tagId, tagName, ''
FROM dbo.tbl_Tag;
WHILE (1 = 1) BEGIN
SELECT #V_TagValue =
CASE
WHEN tagId = 1 THEN 'Tag Value 1'
WHEN tagId = 2 THEN 'Tag Value 2'
WHEN tagId = 3 THEN 'Tag Value 3'
WHEN tagId = 4 THEN 'Tag Value 4'
ELSE ''
END
FROM #ttbl_TagList
WHERE tagListId = #V_Counter;
IF (##ROWCOUNT = 0) BREAK;
IF (#V_TagValue != '')
BEGIN
SET #V_FinalQuery = #V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), #V_Counter) + ' THEN ''' + #V_TagValue + '''';
END
SET #V_Counter = #V_Counter + 1;
END
IF (#V_FinalQuery != '')
BEGIN
CREATE TABLE #t1
(
tagId TINYINT
, tagName VARCHAR(100)
, tagValue NVARCHAR(MAX)
)
SET #V_FinalQuery = N'
INSERT INTO #t1
SELECT tagId, tagName, (CASE tagListId' + #V_FinalQuery + ' END)
FROM #ttbl_TagList';
EXEC sys.sp_executesql
#V_FinalQuery
, N'#ttbl_TagList dbo.tt_TagList readonly'
, #ttbl_TagList;
END
SELECT * FROM #t1;
END