Reputation: 482
I am writing queries that are used on a website. When the query is needed it gets directly parsed to the server and the outcome is all controlled by the query. The website just returns the table. What I do have on the site is checkboxes that the client can select and those get parsed into the query as either @var = 1
or @var = 0
. Because of that, right now I have this code to check and add or not depending if it is checked. My question is, is there a better way to go about this than using the IF
statement like this as I have several sections of the code that include this:
SET @sql = 'select distinct '
If @mgchk = 1
SET @sql = @sql + 'p.MainGroup'
If @sgchk = 1 and @sql = 'select distinct '
SET @sql = @sql + 'p.SubGroup'
If @sgchk = 1 and @sql not like '%SubGroup'
SET @sql = @sql + ',p.SubGroup'
If @ssgchk = 1 and @sql = 'select distinct '
SET @sql = @sql + 'p.SubSubGroup'
If @ssgchk = 1 and @sql not like '%SubSubGroup'
SET @sql = @sql + ',p.SubSubGroup'
If @Seasonchk = 1 and @sql = 'select distinct '
SET @sql = @sql + 'p.Season'
If @Seasonchk = 1 and @sql not like '%Season'
SET @sql = @sql + ',p.Season'
If @vendorchk = 1 and @sql = 'select distinct '
SET @sql = @sql + 'p.VendorID'
If @vendorchk = 1 and @sql not like '%VendorID'
SET @sql = @sql + ',p.VendorID'
SET @sql =
@sql +
' into
##aa
from
RPProducts p,
RPIv i,
RPTrsd d,
RPTrs s
WHERE
s.StoreID = d.StoreID and
s.ReceiptNO = d.ReceiptNO and
i.UPC = d.UPC and
i.StoreID = d.StoreID and
i.IVProduct = p.Productid and
s.TRSdate >= '''+ convert(varchar(10), @trsfrom, 101) +''' and
s.TRSdate <= '''+ convert(varchar(10), @trsto, 101) +''''
execute sp_executesql @sql
@mgchk / @sgchk / @ssgchk / @seasonchk / @vendorchk are the checkboxes variables
To answer @Aaron,
Global temp because of the dynamic queries. The whole query gets processed and drop right away when the data is pulled. No clash will happen there.
My date variables are datetime
and it gives me an error within dynamic SQL.
Yes, recalling the same thing over to check, which is the reason for this whole question, if there is something better to use than the IF
checking.
And I find using alias joins easier...
Upvotes: 0
Views: 41
Reputation: 280272
-- rather than convert to a dangerously formatted string,
-- here is a much better way to strip time from a datetime
-- (if you need to!)
SET @trsfrom = DATEADD(DAY, DATEDIFF(DAY, 0, @trsfrom), 0);
SET @trsto = DATEADD(DAY, DATEDIFF(DAY, 0, @trsto), 0);
DECLARE @sql NVARCHAR(MAX) = N'SELECT DISTINCT ';
-- here's an easier way to strip the first comma:
SET @sql += SUBSTRING(
CASE WHEN @mgchk = 1 THEN ',p.MainGroup' ELSE '' END
+ CASE WHEN @sgchk = 1 THEN ',p.SubGroup' ELSE '' END
+ CASE WHEN @ssgchk = 1 THEN ',p.SubSubGroup' ELSE '' END
+ CASE WHEN @Seasonchk = 1 THEN ',p.Season' ELSE '' END
+ CASE WHEN @vendorchk = 1 THEN ',p.VendorID' ELSE '' END, 2, 2000);
SET @sql += ' INTO ##aa
FROM
dbo.RPProducts AS p -- use schema prefix!
INNER JOIN dbo.RPIv AS i -- use PROPER JOINS!
ON i.IVProduct = p.Productid
INNER JOIN dbo.RPTrsd AS d
ON i.UPC = d.UPC
AND i.StoreID = d.StoreID
INNER JOIN dbo.RPTrs AS s
ON s.StoreID = d.StoreID
AND s.ReceiptNO = d.ReceiptNO
WHERE s.TRSdate >= @trsfrom -- use strongly typed parameters!
AND s.TRSdate <= @trsto;';
EXEC sp_executesql @sql,
N'@trsfrom DATETIME, @trsto DATETIME',
@trsfrom, @trsto;
----^^^^^^^^^^^^^^^^ here is how the query gets the @trsfrom & @trsto values
I still think your use of a ##global temp table is quite dangerous. If two people run this code at the same time, they are going to have serious problems.
Upvotes: 4