Reputation: 682
I am writing a stored procedure that will be executed from an SSRS report. It receives 2 parameters: SourceID, and ConfirmationNumber but it is not working for all the tests that I am running
this returns recs:[dbo].[GetParkingPaymentInformation] 'PARC', ''
this does not return recs:[dbo].[GetParkingtPaymentInformation] 'PARC', NULL
this does not return recs:[dbo].[GetParkingPaymentInformation] '', '002077770'
this does not return recs:[dbo].[GetParkingPaymentInformation] NULL, '002077770'
this does return recs:[dbo].[GetParkingPaymentInformation] 'PARC', '002077770'
I want the sp to work when one or the other parameter are either null, or blank.
This is what I have so far for code:
SET @s_SQL = 'SELECT d.ID, d.TransactionNumber, h.SourceType, ' + @s_ColumnName + ', d.FirstName, d.LastName,' +
'LTRIM(RTRIM(d.FirstName)) + '' '' + LTRIM(RTRIM(d.LastName)) [Name], '+
'd.PaymentAmount, CONVERT(VARCHAR(10), CAST(d.InitiationDate AS DATE), 101) [InitiationDate]' +
', d.Fee, d.TotalAmount, d.PaymentStatus, d.PaymentType, d.CreditCardType, ' +
'CONVERT(VARCHAR(10), CAST(d.PaymentEffectiveDate AS DATE), 101) [PaymentEffectiveDate]' +
', CONVERT(VARCHAR(10), CAST(d.ProcessDate AS DATE), 101) [ProcessDate], CONVERT(VARCHAR(10), CAST(d.CreatedDate AS DATE), 101) [CreatedDate],' +
'd.CashCode, d.TransConfirmID' +
', d.Phone, d.StreetAddress1, d.StreetAddress2, ' +
'LTRIM(RTRIM(d.StreetAddress1)) + '' '' + CASE WHEN LEN(d.StreetAddress2) > 0 THEN LTRIM(RTRIM(d.StreetAddress2)) ELSE '''' END [Address]' +
', d.City, d.[State], d.ZipFive, d.ZipFour, d.Email ' +
'FROM '+ @s_TableHeader + ' h WITH (NOLOCK) ' +
'INNER JOIN ' + @s_TableDetail + ' d WITH (NOLOCK) ' +
'ON h.ID = d.headerID ' +
'WHERE' +
' ((h.sourcetype = ' + '''' + @s_Source_Type + '''' + ') OR ' + '''' + @s_Source_Type + '''' + ' IS NULL OR ' + '''' + @s_Source_Type + '''' + '= '''')' +
' AND ((d.transconfirmid = ' + '''' + @s_Confirmation_Number + '''' + ') OR ' + '''' + @s_Confirmation_Number + '''' + ' IS NULL OR ' + '''' + @s_Confirmation_Number + '''' + '= '''')'
Any help I can get to figure why my checks are not working, it would be great.
Upvotes: 1
Views: 2299
Reputation: 549
Try changing your WHERE to something like this:
'where' +
' h.sourcetype = ' + isnull(quotename(nullif(@s_Source_Type, ''), ''''), 'h.sourcetype') +
' AND d.transconfirmid = ' + isnull(quotename(nullif(@s_Confirmation_Number, ''), ''''), 'd.transconfirmid')
Upvotes: 0
Reputation: 106
*Please note that your example sql code is incomplete and that you name the parameters slightly different from the variables which makes for difficulty understanding the question. *
It is not without reason that the use of dynamic sql is discouraged even in cases where the dangers of sql injection are negligible. One of the primary reasons for this is that dynamic sql is difficult to write, read and debug. That being said I have often found myself using it to solve for problems within poorly designed systems.
I assume that you have investigated alternatives appropriately.
To reduce the complexity of dynamic sql statements I have found that constructing the statement in a modular way to be a good strategy.
In your particular case the use of an 'if' statement (or some variation) may help reduce the complexity of your dynamic where clause and likely help resolve your problem.
Example:
`
set @sql = 'select....... your select statement..... where'
if (@a_Source_Type is not null and len(@a_Source_Type) > 0) begin set @sql += '''' + @a_Source_Type + ''' = some_field and ' end else begin set @sql += ' len(isnull(some_field, '''')) = 0 and ' end
set @sql += ' 1 = 1 '
`
The above attempts to move the comparison operators out of the dynamic sql.
I suggest refactoring your query to use a strategy similar to this example as you may find it easier to identify erroneous code.
the final line of the example has proven useful in circumstances where the resulting dynamic sql statement may or may not have where clauses to append
Upvotes: 1