Writing a dreaded SQL search query - sql-server-2005

I am working on a search query that does not seem to work.
The complete query is:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[usp_Item_Search]
#Item_Num varchar(30) = NULL
,#Search_Type int = NULL
,#Vendor_Num varchar(10) = NULL
,#Search_User_ID int = NULL
,#StartDate smalldatetime = NULL
,#EndDate smalldatetime = NULL
AS
DECLARE #SQLstr as nvarchar(4000)
Set #SQLstr = 'SELECT RecID, Vendor_Num, Vendor_Name, InvoiceNum, Item_Num,
(SELECT CONVERT(VARCHAR(11), RecDate, 106) AS [DD MON YYYY]) As RecDate, NeedsUpdate, RecAddUserID FROM [tbl_ItemLog] '
IF (#Item_Num IS NOT NULL)
Begin
If #Search_Type = 0
BEGIN
Set #SQLstr = #SQLstr + 'WHERE Item_Num LIKE ''' + #Item_Num + '%'''
END
If #Search_Type = 1
BEGIN
Set #SQLstr = #SQLstr + 'WHERE Item_Num LIKE ''%' + #Item_Num + '%'''
END
If #Search_Type = 2
BEGIN
Set #SQLstr = #SQLstr + 'WHERE Item_Num LIKE ''%' + #Item_Num + ''''
END
End
IF (#Vendor_Num IS NOT NULL)
Begin
Set #SQLstr = #SQLstr + ' AND Vendor_Num = ''' + #Vendor_Num + ''''
End
IF (Search_User_ID IS NOT NULL)
Begin
Set #SQLstr = #SQLstr + ' AND RecAddUserID = ' + convert(nvarchar(20),#Search_User_ID)
End
Set #SQLstr = #SQLstr + ' AND (RecDate BETWEEN ''' + convert(nvarchar(10),#StartDate,101) + ''' AND ''' + convert(nvarchar(10),#EndDate,101) + ''')'
PRINT (#SQLstr)
--Execute (#SQLstr)
When I pass paramters to the query, and if the Vendor_Num value is blank, the output from PRINT(#SQLstr) is
SELECT RecID, Vendor_Num, Vendor_Name, InvoiceNum, Item_Num,
(SELECT CONVERT(VARCHAR(11), RecDate, 106) AS [DD MON YYYY]) As RecDate,
NeedsUpdate, RecAddUserID FROM [tbl_ItemLog] WHERE Item_Num LIKE '2200%'
**AND Vendor_Num = ''** AND RecAddUserID = 2 AND (RecDate BETWEEN '01/01/2001'
AND '12/12/2002')
What I want the output to be is:
SELECT RecID, Vendor_Num, Vendor_Name, InvoiceNum, Item_Num,
(SELECT CONVERT(VARCHAR(11), RecDate, 106) AS [DD MON YYYY]) As RecDate,
NeedsUpdate, RecAddUserID FROM [tbl_ItemLog] WHERE Item_Num LIKE '2200%'
AND RecAddUserID = 2 AND (RecDate BETWEEN '01/01/2001' AND '12/12/2002')
How can I structure the query so if the param value is blank, it does not show the field.

Try changing
IF (#Vendor_Num IS NOT NULL)
to
IF (#Vendor_Num IS NOT NULL and LTRIM(#Vendor_Num) <> '')

Related

How to create a "Catalyst" to view data before x minutes from z timestamp and x minutes after z timestamp for every 'ABC' specific data

" I want a SSRS report that can identify all activations received within the last 5 minutes before the CNT signal was received from a store and signals that were received within 5 minutes after the CNT signal "
Need to know what is the best practice to achieve this goal - what to google to fix my query to make it easier to design in report builder
I have q query below but within SSRS I cant group it or expand it in a way useful for viewing
I have a proof of concept (image) but don't know how to approach the query to get to the result
a bit ambitious for a Jnr report writer!
POC Catalyst Idea <<<<<-
DECLARE #Division varchar(2) = '*',
#SubDivision varchar(4) = '*',
#MainArea varchar(3) = '*',
#SubArea varchar(3) = '*',
#StartD datetime = '2022-03-29',
#StartTime Varchar(10) = '06:00:00',
#EndD datetime = '2022-03-29',
#EndTime Varchar(10) = '18:00:00',
#X int = 5,
#Catylist varchar(3) = 'CNT'
DECLARE #Arc varchar(100),
#Svr varchar(50),
#db varchar(50),
#Str varchar(max) = '',
#Qry varchar(max) = '',
#mon varchar(100) = '',
#StartDate varchar(20),
#EndDate varchar(20)
SET #StartDate = CONVERT(varchar(11),#StartD,106) + ' ' + #StartTime
SET #EndDate = CONVERT(varchar(11),#EndD,106) + ' ' + #EndTime
SELECT #mon = IIF(UPPER(ServerName)=UPPER(##ServerName),DatabaseName,'[' + ServerName + '].' + DatabaseName) + '.dbo.'
FROM maBranchModules WITH (NOLOCK) WHERE Module = 'MONITOR'
CREATE TABLE #FirstBL
(CustId int, Signl varchar(10), StartTime datetime, EndTime datetime,Seq int,Catalyst char(1))
DECLARE Arc_cursor CURSOR FOR
SELECT SQLServer, SQLDatabase FROM RW_ArchiveDTL WITH (NOLOCK)
WHERE StartDTTM >= DATEADD(month,-1,EOMONTH(#StartDate))
AND EndDTTM <= DATEADD(day,1,EOMONTH(#EndDate))
ORDER BY StartDTTM
OPEN Arc_cursor
FETCH NEXT FROM Arc_cursor INTO #Svr, #db
WHILE ##FETCH_STATUS = 0
BEGIN
IF #Svr = ##ServerName
SET #Arc = #db + '.dbo.'
ELSE
SET #Arc = '[' + #Svr + '].' + #db + '.dbo.'
IF #Str = ''
SET #Str = 'INSERT INTO #FirstBL (CustId,Signl,StartTime,Seq)'
ELSE
SET #Str = #Str + char(13) + 'UNION ALL '
/*GET ALL CATYLIST SIGNALS IN DATE RANGE*/
SET #Str = #Str + char(13) + 'SELECT
a.CustId, a.FirstAlarm,a.SignalTime,ROW_NUMBER() OVER (PARTITION BY a.CustId ORDER BY a.SignalTime) AS Seq
FROM ' + #Arc + 'ArchiveHistory AS a WITH (NOLOCK) INNER JOIN
' + #mon + 'Address AS b WITH (NOLOCK) ON a.AddressId = b.AddressId
WHERE a.SignalTime >= ''' + CONVERT(varchar,#StartDate,121) + '''
AND a.SignalTime < ''' + CONVERT(varchar,#EndDate,121) + '''
AND a.FirstAlarm = ''' + #Catylist + '''
AND a.CustId > 0 '
IF #Division <> '*'
SET #Str = #Str + char(13) + 'AND b.Division = ''' + #Division + ''' '
IF #SubDivision <> '*'
SET #Str = #Str + char(13) + 'AND b.SubDivision = ''' + #SubDivision + ''' '
IF #MainArea <> '*'
SET #Str = #Str + char(13) + 'AND a.MainArea = ''' + #MainArea + ''' '
IF #SubArea <> '*'
SET #Str = #Str + char(13) + 'AND a.SubArea = ''' + #SubArea + ''' '
IF #Qry <> ''
SET #Qry = #Qry + char(13) + 'UNION ALL '
/*GET ALL SIGNALS FOR #X MINUTES BEFORE & AFTER CATYLIST SIGNAL RECEIVED*/
SET #Qry = #Qry + char(13) + 'SELECT DISTINCT
--a.CustId, b.StartTime, a.SignalTime, a.FirstAlarm, b.EndTime,
a.CustId, a.SignalTime, a.FirstAlarm, a.OBNumber,
c.CustCode, c.CustDesc, d.Division, d.SubDivision, d.MainArea, d.SubArea, c.SuspendMode
FROM ' + #Arc + 'ArchiveHistory AS a WITH (NOLOCK) INNER JOIN
#FirstBL AS b WITH (NOLOCK) ON a.CustId = b.CustId INNER JOIN
' + #mon + 'Client AS c WITH (NOLOCK) ON a.CustId = c.CustId INNER JOIN
' + #mon + 'Address AS d WITH (NOLOCK) ON c.AddressId = d.AddressId
AND a.SignalTime BETWEEN DATEADD(minute,-' + CONVERT(varchar,#X) + ',b.StartTime) AND b.EndTime '
FETCH NEXT FROM Arc_cursor INTO #Svr, #db
END
CLOSE Arc_cursor;
DEALLOCATE Arc_cursor;
SET #Str = #Str + char(13) + 'ORDER BY CustId, SignalTime'
EXEC(#Str)
/*CLEAN OUT ALL EXTRA CATYLIST SIGNALS THAT FALLS WITHIN #X OF "FIRST"*/
UPDATE #FirstBL SET EndTime = DATEADD(minute,#X,StartTime) WHERE Seq = 1
UPDATE a SET a.Catalyst = IIF(a.StartTime BETWEEN b.StartTime AND b.EndTime,'N','Y')
FROM #FirstBL AS a INNER JOIN
#FirstBL AS b ON a.CustId = b.CustId
WHERE b.Seq = 1
AND a.Seq > 1
DELETE FROM #FirstBL WHERE Catalyst = 'N'
DECLARE #N int
SET #N = 1
WHILE (SELECT COUNT(*) FROM #FirstBL WHERE EndTime IS NULL) > 0
begin
UPDATE #FirstBL SET EndTime = DATEADD(minute,#X,StartTime), Seq = #N + 1
WHERE Seq = (SELECT TOP 1 a.Seq FROM #FirstBL a WHERE #FirstBL.CustId = a.CustId AND Seq > #N ORDER BY a.Seq)
UPDATE a SET a.Catalyst = IIF(a.StartTime BETWEEN b.StartTime AND b.EndTime,'N','Y')
FROM #FirstBL AS a INNER JOIN
#FirstBL AS b ON a.CustId = b.CustId
WHERE b.Seq = #N
AND a.Seq > #N
DELETE FROM #FirstBL WHERE Catalyst = 'N'
Set #N = #N +1
end
/*ALL TOGETHER NOW*/
SET #Qry = #Qry + char(13) + 'ORDER BY CustId, SignalTime'
EXEC(#Qry)
/*GET RID OF THE #*/
DROP TABLE #FirstBL
If you want to look behind and ahead 5 minutes, recommend just using APPLY. For example, here's how to find every match to a "CNT" event within 5 minutes
Using APPLY to Find Events +/- 5 Minutes
DROP TABLE IF EXISTS #Data
CREATE TABLE #Data (
ID INT IDENTITY(1,1) PRIMARY KEY
,SignalDateTime DATETIME2(0)
,FirstAlarm CHAR(3)
)
INSERT INTO #Data VALUES
('2022-03-29 10:06','LRQ')
,('2022-03-29 10:07','CNF')
,('2022-03-29 10:07','CNT')
,('2022-03-29 10:07','DNT')
,('2022-03-29 13:19','LRQ')
,('2022-03-29 13:20','CNF')
,('2022-03-29 13:20','CNT')
,('2022-03-29 13:20','DNT')
,('2022-03-29 13:24','LRQ')
,('2022-03-29 13:24','CNF')
,('2022-03-29 13:24','CNT')
,('2022-03-29 13:24','DNT')
,('2022-03-29 13:25','CNF')
,('2022-03-29 13:25','CNT')
,('2022-03-29 13:25','DNT')
,('2022-03-29 14:31','LRQ')
,('2022-03-29 14:31','CNF')
,('2022-03-29 14:31','CNT')
,('2022-03-29 14:31','DNT')
SELECT CNTGroupID = DENSE_RANK() OVER (ORDER BY A.ID)
,*
FROM #Data AS A
CROSS APPLY (
SELECT *
FROM #Data AS DTA
WHERE DTA.FirstAlarm <> 'CNT'
AND DTA.SignalDateTime BETWEEN DATEADD(mi,-5,A.SignalDateTime) AND DATEADD(mi,5,A.SignalDateTime)
) AS B
WHERE A.FirstAlarm = 'CNT'

Dynamic SQL - parametrized query

I use dynamic sql with parameters and have problem :)
In block of code it works, but when I call procedure I have error that I need to declare scalar variable #name_dummy
So:
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT
o.SCHEMA_N
,o.TABLE_N
,o.Condition
,o.TargetDB
,o.SourceDB
,STUFF((SELECT
', ' + c.name
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH (''))
, 1, 1, '')
FROM Table_A o
ORDER BY 1,
2
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = ( SELECT CAST(Wartosc AS VARCHAR) FROM Table_B WHERE Id = 3 )
IF #TOP < 40000
SET #TOP = 40000
WHILE ( 1 = 1 )
BEGIN
DECLARE #CHECK BIT = 0
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM '
+ #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
SELECT #sqlCMD , #CHECK
END
END
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
CLOSE KUR;
DEALLOCATE KUR
And when I execute this it's compiling and works ( returns values ) for example sql which I want to execute.
SELECT TOP 1 #check_exists = 1 FROM MSSF15_WarstwaPosrednia.KatalogZdarzen.MSSF_RaportZdarzenPLKB2CS2K WHERE StatusPrzetwarzania = 4 AND DataWpisu < DATEADD(MONTH, -3, #START_TIME)
Parameters work here ( #check_exists which is output and #START_TIME condition param ) , but when I execute this in procedure I'm getting error
Must declare the scalar variable "#START_TIME". 137
SP definition:
USE xxxx
/****** Object: StoredProcedure dbo.dummy Script Date: 06/09/2018 13:40:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE dbo.dummy
AS
BEGIN
/*
PRZENIESIENIE DANYCH
*/
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT o.SCHEMA_N,
o.TABLE_N,
o.Condition,
o.TargetDB,
o.SourceDB,
STUFF((
SELECT ', ' + c.NAME
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH('')
), 1, 1, '')
FROM dbo.Table_A o
ORDER BY 1,
2
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = (
SELECT CAST(Wartosc AS VARCHAR)
FROM dbo.Table_B
WHERE Id = 3
)
IF #TOP < 40000
SET #TOP = 40000
WHILE (1 = 1)
BEGIN
BEGIN TRY
BEGIN TRANSACTION T_TEST
DECLARE #CHECK BIT = 0
DECLARE #START_TIME_P DATE = GETDATE()
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
SELECT #CHECK,
#START_TIME_P,
#sqlCMD
EXEC sp_executesql #sqlCMD,
N'#check_exists bit OUTPUT, #START_TIME DATE',
#check_exists = #CHECK OUTPUT,
#START_TIME = #START_TIME_P;
IF OBJECT_ID('tempdb..#TMP_ID') IS NOT NULL
DROP TABLE #TMP_ID
CREATE TABLE #TMP_ID (Id INT)
EXEC (
'INSERT INTO #TMP_ID
SELECT TOP ' + #TOP + ' Id
FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
)
DECLARE #sqlCMD_Ins NVARCHAR(MAX)
SET #sqlCMD_Ins = 'INSERT INTO ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' '
SET #sqlCMD_Ins = #sqlCMD_Ins + 'SELECT ' + #COLUMN_LIST + ' FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Ins IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Ins)
DECLARE #sqlCMD_Del NVARCHAR(MAX)
SET #sqlCMD_Del = 'DELETE FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Del IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Del)
DROP TABLE #TMP_ID
COMMIT TRANSACTION T_TEST
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION T_TEST
PRINT 'Wycofanie zmian'
PRINT ERROR_MESSAGE() + ' ' + CAST(ERROR_NUMBER() AS VARCHAR(256))
END
END CATCH
IF #CHECK = 0
BREAK
END
EXEC ('SELECT ''' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' UNION ALL ' + 'SELECT ''' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N)
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
END
CLOSE KUR;
DEALLOCATE KUR;
DECLARE #END_TIME DATETIME = GETDATE()
SELECT 'Daty przetworzenia',
#START_TIME_P AS 'START',
#END_TIME AS 'END'
SELECT 'Czas (min)',
DATEDIFF(MINUTE, #START_TIME_P, #END_TIME)
END
Guys, maybe u have similar situation and can help.
Error msg
Wycofanie zmian
Must declare the scalar variable "#START_TIME". 137
Thanks
Instead of
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
try
declare #date_in DATE = GETDATE()
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #date_in;

How to pass datetime in dynamic query in sql?

I have written a stored procedure like this
ALTER PROCEDURE [dbo].[spLoadPendingPaymentSheetByFilter] --'2015-04-01','2015-04-02','Select-One','Select-One','Select-One',''
#FromDate as datetime,
#ToDate as datetime,
#Status as nvarchar(50),
#Remarks as nvarchar(50),
#Paymenttype as nvarchar(50),
#BillID as nvarchar(50)
AS
Declare #Where as nvarchar(max)
set #Where = '( MenifestDate BETWEEN ''' + CONVERT(VARCHAR(10),#FromDate, 101) + ''' and ''' + CONVERT(VARCHAR(10),#ToDate, 101) + ''' )'
if(#Status <> 'Select-One')
set #Where = 'Status = '+ #Status
if(#Remarks <> 'Select-One')
set #Where = #Where + 'and Remarks = '+ #Remarks
if(#Paymenttype <> 'Select-One')
set #Where = #Where + 'and PaymentType = ' + #Paymenttype
if(#BillID <> '')
set #Where = #Where + 'and BillID = '+ #BillID
Declare #SelectString as nvarchar(1000)
set #SelectString = 'SELECT MasterID,BillID, MenifestDate, FarwardingNo,ReceverCountryName,Status,Remarks,PaymentType
FROM tblMenifest
WHERE ' + #Where
exec #SelectString
When I execute it I got this error
The name 'SELECT MasterID,BillID, MenifestDate, FarwardingNo,ReceverCountryName,Status,Remarks,PaymentType FROM tblMenifest WHERE ( MenifestDate BETWEEN '04/01/2015' and '04/02/2015' )' is not a valid identifier
The MenifestDate column datatype is datetime.
I believe that you want to put EXEC(#SelectString) rather than exec #SelectString.

cast list of strings as int list in sql query / stored procedure

I have this stored procedure:
exec SearchResume #KeywordSearch=N'', #GreaterThanDate='2013-09-22 00:00:00',
#CityIDs=N'0,56,31,271,117,327,3,328,228',
#ProvinceIDs=N'0,1,12,13',
#CountryIDs=N'1',
#IndustryIDs=N'0,2,3,4,38,113,114,115,116,117'
Which doesn't return any results because the ids are in nvarchar but the actual values are integer.
Now, when I test the actual SP with a manual list of int values I'm able to get the results, this is the example:
SELECT DISTINCT
UserID,
ResumeID,
CASE a.Confidential WHEN 1 THEN 'Confidential' ELSE LastName + ',' + FirstName END as 'Name',
a.Description 'ResumeTitle',
CurrentTitle,
ModifiedDate,
CASE ISNULL(b.SalaryRangeID, '0') WHEN '0' THEN CAST(SalarySpecific as nvarchar(8)) ELSE c.Description END 'Salary',
h.Description 'Relocate',
i.Description + '-' + j.Description + '-' + k.Description 'Location'
FROM dbo.Resume a JOIN dbo.Candidate b ON a.CandidateID = b.CandidateID
LEFT OUTER JOIN SalaryRange c ON b.SalaryRangeID = c.SalaryRangeID
JOIN EducationLevel e ON b.EducationLevelID = e.EducationLevelID
JOIN CareerLevel f ON b.CareerLevelID = f.CareerLevelID
JOIN JobType g ON b.JobTypeID = g.JobTypeID
JOIN WillingToRelocate h ON b.WillingToRelocateID = h.WillingToRelocateID
JOIN City i ON b.CityID = i.CityID
JOIN StateProvince j ON j.StateProvinceID = b.StateProvinceID
JOIN Country k ON k.CountryID = b.CountryID
WHERE (b.CityID IN (0,56,31,125,229,5,219,8,228))
AND (b.StateProvinceID IN (0,1,13))
AND (b.CountryID IN (1))
AND (b.IndustryPreferenceID IN (0,2,3,4,5,6,115,116,117))
I would like to know what can I do to send a list of int values, not a list of nvarchar values since as you can see the query doesn't work properly.
Update
Original SP:
ALTER PROCEDURE [dbo].[SearchResume]
#KeywordSearch nvarchar(500),
#GreaterThanDate datetime,
#CityIDs nvarchar(500),
#ProvinceIDs nvarchar(500),
#CountryIDs nvarchar(500),
#IndustryIDs nvarchar(500)
AS
BEGIN
DECLARE #sql as nvarchar(4000)
SET #sql = 'SELECT DISTINCT
UserID,
ResumeID,
CASE a.Confidential WHEN 1 THEN ''Confidential'' ELSE LastName + '','' + FirstName END as ''Name'',
a.Description ''ResumeTitle'',
CurrentTitle,
ModifiedDate,
CurrentEmployerName,
PersonalDescription,
CareerObjectives,
CASE ISNULL(b.SalaryRangeID, ''0'') WHEN ''0'' THEN CAST(SalarySpecific as nvarchar(8)) ELSE c.Description END ''Salary'',
e.Description ''EducationLevel'',
f.Description ''CareerLevel'',
g.Description ''JobType'',
h.Description ''Relocate'',
i.Description + ''-'' + j.Description + ''-'' + k.Description ''Location''
FROM dbo.Resume a JOIN dbo.Candidate b ON a.CandidateID = b.CandidateID
LEFT OUTER JOIN SalaryRange c ON b.SalaryRangeID = c.SalaryRangeID
JOIN EducationLevel e ON b.EducationLevelID = e.EducationLevelID
JOIN CareerLevel f ON b.CareerLevelID = f.CareerLevelID
JOIN JobType g ON b.JobTypeID = g.JobTypeID
JOIN WillingToRelocate h ON b.WillingToRelocateID = h.WillingToRelocateID
JOIN City i ON b.CityID = i.CityID
JOIN StateProvince j ON j.StateProvinceID = b.StateProvinceID
JOIN Country k ON k.CountryID = b.CountryID
WHERE ( (ModifiedDate > ''' + CAST(#GreaterThanDate as nvarchar(55)) + ''')
'
IF (LEN(#CityIDs) >0)
BEGIN
SET #sql = #sql + 'AND (b.CityID IN (' + #CityIDs + '))'
END
IF (LEN(#ProvinceIDs) >0)
BEGIN
SET #sql = #sql + 'AND (b.StateProvinceID IN (' + #ProvinceIDs + '))'
END
IF (LEN(#CountryIDs) >0)
BEGIN
SET #sql = #sql + 'AND (b.CountryID IN (' + #CountryIDs + '))'
END
IF (LEN(#IndustryIDs) >0)
BEGIN
SET #sql = #sql + 'AND (b.IndustryPreferenceID IN (' + #IndustryIDs + '))'
END
IF (LEN(#KeywordSearch) > 0)
BEGIN
SET #sql = #sql + ' AND (' + #KeywordSearch + ')'
END
SET #sql = #sql + ') ORDER BY ModifiedDate desc'
--select #sql
exec sp_executesql #sql
END
You can create a Table-Valued Function which takes the nVarChar and creates a new record for each value, where you tell it the delimiter. My example here returns a table with a single Value column, you can then use this as a sub query for your IN Selection :
Create FUNCTION [dbo].[fnSplitVariable]
(
#List nvarchar(2000),
#delimiter nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Variable varchar(15),
Value nvarchar(100)
)
AS
BEGIN
Declare #Count int
set #Count = 1
While (Charindex(#delimiter,#List)>0)
Begin
Insert Into #RtnValue (Value, Variable)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#delimiter,#List)-1))),
Variable = 'V' + convert(varchar,#Count)
Set #List = Substring(#List,Charindex(#delimiter,#List)+len(#delimiter),len(#List))
Set #Count = #Count + 1
End
Insert Into #RtnValue (Value, Variable)
Select Value = ltrim(rtrim(#List)), Variable = 'V' + convert(varchar,#Count)
Return
END
Then in your where statement you could do the following:
WHERE (b.CityID IN (Select Value from fnSplitVariable(#CityIDs, ','))
I have included your original Procedure, and updated it to use the function above:
ALTER PROCEDURE [dbo].[SearchResume]
#KeywordSearch nvarchar(500),
#GreaterThanDate datetime,
#CityIDs nvarchar(500),
#ProvinceIDs nvarchar(500),
#CountryIDs nvarchar(500),
#IndustryIDs nvarchar(500)
AS
BEGIN
DECLARE #sql as nvarchar(4000)
SET #sql = N'
DECLARE #KeywordSearch nvarchar(500),
#CityIDs nvarchar(500),
#ProvinceIDs nvarchar(500),
#CountryIDs nvarchar(500),
#IndustryIDs nvarchar(500)
SET #KeywordSearch = '''+#KeywordSearch+'''
SET #CityIDs = '''+#CityIDs+'''
SET #ProvinceIDs = '''+#ProvinceIDs+'''
SET #CountryIDs = '''+#CountryIDs+'''
SET #IndustryIDs = '''+#IndustryIDs+'''
SELECT DISTINCT
UserID,
ResumeID,
CASE a.Confidential WHEN 1 THEN ''Confidential'' ELSE LastName + '','' + FirstName END as ''Name'',
a.Description ''ResumeTitle'',
CurrentTitle,
ModifiedDate,
CurrentEmployerName,
PersonalDescription,
CareerObjectives,
CASE ISNULL(b.SalaryRangeID, ''0'') WHEN ''0'' THEN CAST(SalarySpecific as nvarchar(8)) ELSE c.Description END ''Salary'',
e.Description ''EducationLevel'',
f.Description ''CareerLevel'',
g.Description ''JobType'',
h.Description ''Relocate'',
i.Description + ''-'' + j.Description + ''-'' + k.Description ''Location''
FROM dbo.Resume a JOIN dbo.Candidate b ON a.CandidateID = b.CandidateID
LEFT OUTER JOIN SalaryRange c ON b.SalaryRangeID = c.SalaryRangeID
JOIN EducationLevel e ON b.EducationLevelID = e.EducationLevelID
JOIN CareerLevel f ON b.CareerLevelID = f.CareerLevelID
JOIN JobType g ON b.JobTypeID = g.JobTypeID
JOIN WillingToRelocate h ON b.WillingToRelocateID = h.WillingToRelocateID
JOIN City i ON b.CityID = i.CityID
JOIN StateProvince j ON j.StateProvinceID = b.StateProvinceID
JOIN Country k ON k.CountryID = b.CountryID
WHERE ( (ModifiedDate > ''' + CAST(#GreaterThanDate as nvarchar(55)) + ''')
'
IF (LEN(#CityIDs) >0)
BEGIN
SET #sql = #sql + N'AND (b.CityID IN (Select Value from fnSplitVariable(#CityIDs,'','') ))'
END
IF (LEN(#ProvinceIDs) >0)
BEGIN
SET #sql = #sql + N'AND (b.StateProvinceID IN (Select Value from fnSplitVariable(#ProvinceIDs,'','') ))'
END
IF (LEN(#CountryIDs) >0)
BEGIN
SET #sql = #sql + N'AND (b.CountryID IN (Select Value from fnSplitVariable(#CountryIDs,'','') ))'
END
IF (LEN(#IndustryIDs) >0)
BEGIN
SET #sql = #sql + N'AND (b.IndustryPreferenceID IN (Select Value from fnSplitVariable(#IndustryIDs,'','') ))'
END
IF (LEN(#KeywordSearch) > 0)
BEGIN
SET #sql = #sql + N' AND (' + #KeywordSearch + ')'
END
SET #sql = #sql + N') ORDER BY ModifiedDate desc'
--select #sql
exec sp_executesql #sql
END
DECLARE #SQL AS NVARCHAR(MAX)
SET #SQL = 'SELECT DISTINCT
UserID,
ResumeID,
CASE a.Confidential WHEN 1 THEN ''Confidential'' ELSE LastName + '','' + FirstName END as ''Name'',
a.Description ''ResumeTitle'',
CurrentTitle,
ModifiedDate,
CASE ISNULL(b.SalaryRangeID, ''0'') WHEN ''0'' THEN CAST(SalarySpecific as nvarchar(8)) ELSE c.Description END ''Salary'',
h.Description ''Relocate'',
i.Description + ''-'' + j.Description + ''-'' + k.Description ''Location''
FROM dbo.Resume a JOIN dbo.Candidate b ON a.CandidateID = b.CandidateID
LEFT OUTER JOIN SalaryRange c ON b.SalaryRangeID = c.SalaryRangeID
JOIN EducationLevel e ON b.EducationLevelID = e.EducationLevelID
JOIN CareerLevel f ON b.CareerLevelID = f.CareerLevelID
JOIN JobType g ON b.JobTypeID = g.JobTypeID
JOIN WillingToRelocate h ON b.WillingToRelocateID = h.WillingToRelocateID
JOIN City i ON b.CityID = i.CityID
JOIN StateProvince j ON j.StateProvinceID = b.StateProvinceID
JOIN Country k ON k.CountryID = b.CountryID
WHERE (b.CityID IN (' + #CityIDs + '))
AND (b.StateProvinceID IN (' + #ProvinceIDs + '))
AND (b.CountryID IN (' + #CountryIDs + '))
AND (b.IndustryPreferenceID IN (' + #IndustryIDs + '))'
EXEC #SQL
You could do a split on the id's that are coming in to the store procedure. So consider this split function:
CREATE FUNCTION [dbo].[Split]
(
#String NVARCHAR(4000),
#Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(#Delimiter,#String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(#Delimiter,#String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(#String,stpos,COALESCE(NULLIF(endpos,0),LEN(#String)+1)-stpos)
FROM Split
)
Then you could write your where statement like this:
WHERE
EXISTS(SELECT NULL FROM dbo.Split(#CityIDs,',') AS city
WHERE city.Data=b.CityID)
AND EXISTS(SELECT NULL FROM dbo.Split(#ProvinceIDs,',') AS Province
WHERE Province.Data=b.StateProvinceID)
AND EXISTS(SELECT NULL FROM dbo.Split(#CountryIDs,',') AS Country
WHERE Country.Data=b.CountryID)
AND EXISTS(SELECT NULL FROM dbo.Split(#IndustryIDs,',') AS Industry
WHERE Industry.Data=b.IndustryPreferenceID)

SQL Server: Error message on dynamic procecure

I don't have much experience with dynamic procedures so the following was only an attempt.
The only part that is actually dynamic here is the table name which I tried to create by combining the fix part "MOC_" and the variable part #level.
Can someone tell me what I have to change here to make this work ?
The error I get when executing this points to the IF NOT EXISTS part:
Conversion failed when converting the nvarchar value 'IF NOT EXISTS (
SELECT *
FROM MOC_Nav2
WHERE itemID = ' to data type int.
My procedure:
ALTER PROCEDURE [dbo].[MOC_UpdateNav]
#level nvarchar(20),
#itemID int,
#parentID int,
#itemName nvarchar(100),
#sortID int,
#logStatus nvarchar(20),
#lastUpdate nvarchar(50),
#modBy varchar(50)
AS
BEGIN
SET NOCOUNT ON;
BEGIN
DECLARE #sql nvarchar(max)
SET #sql = 'IF NOT EXISTS
(
SELECT *
FROM MOC_' + #level + '
WHERE itemID = ' + #itemID + '
)
INSERT INTO MOC_' + #level + '
(
parentID,
itemName,
sortID,
logStatus,
lastUpdate,
modDate,
modBy
)
SELECT ' + #parentID + ',
' + #itemName + ',
' + #sortID + ',
' + #logStatus + ',
' + #lastUpdate + ',
GETDATE(),
' + #modBy + '
ELSE
UPDATE MOC_' + #level + '
SET parentID = ' + #parentID + ',
itemName = ' + #itemName + ',
sortID = ' + #sortID + ',
logStatus = ' + #logStatus + ',
lastUpdate = ' + #lastUpdate + ',
modDate = GETDATE(),
modBy = ' + #modBy + '
WHERE itemID = ' + #itemID + ''
EXEC(#sql)
END
END
#itemID is an int. Because it is used in the expression, everything else must be converted to a number, including your SQL text.
Convert #itemID (and other numbers) to nvarchar before concatenating it into the query:
SET #sql = N'IF NOT EXISTS
(
SELECT *
FROM MOC_' + #level + '
WHERE itemID = ' + cast(#itemID as nvarchar(30)) + ...