Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 multiple variable select statement

Author  Topic 

SimonGough
Starting Member

23 Posts

Posted - 2002-03-19 : 11:15:29
Hi,
I have about 10 vars on a form and they are passed to a stored procedure which runs a select statement. The problem is that not all 10 vars will always be filled in, sometimes 1, 3 5 - whatever the user types in to search by. If nothing is typed, 0 is passed for numeric values and '' for the strings.
In my select statement I need to pull from a table where the relevant fields are equal to the relevant vars. if I use 'or' in the where part of the statement, nothing is filtered properly and the whole (or near enough) table is pulled out. If I use 'and' then nothing is pulled out.

does anyone know how to get around this problem and only search by the vars with values.

thanks for any help,
Simon.

Onamuji
Aged Yak Warrior

504 Posts

Posted - 2002-03-19 : 11:20:06
Something I used way back when ...

CREATE PROCEDURE poAdvSearch (
@number VARCHAR(255) = NULL,
@statusid INT = NULL,
@pr VARCHAR(255) = NULL,
@ar VARCHAR(255) = NULL,
@vendorid INT = NULL,
@event VARCHAR(255) = NULL,
@startdate DATETIME = NULL,
@enddate DATETIME = NULL,
@buyer VARCHAR(255) = NULL,
@typeid INT = NULL,
@category VARCHAR(255) = NULL,
@item VARCHAR(255) = NULL
) AS
SET NOCOUNT ON

DECLARE @categories TABLE (CategoryID INT)
DECLARE @items TABLE(ItemID INT)

INSERT INTO @categories
SELECT CatalogCategoryID
FROM CatalogCategories
WHERE Name LIKE '%' + @category + '%'
OR @category IS NULL

INSERT INTO @items
SELECT ItemID
FROM vActiveCatalogItems
WHERE Name LIKE '%' + @item + '%'
OR @item IS NULL

SELECT po.ID PurchaseOrderID,
v.Name Vendor,
po.POPrefix + CONVERT(VARCHAR, po.PONumber) + po.POPostfix Number,
CONVERT(VARCHAR, ISNULL(po.PRID, '')) PR,
ISNULL(ar.ControlNumber, '') AR,
pot.Name Type,
pos.Name Status,
po.OrderDate,
ISNULL((SELECT SUM(Quantity * UnitPrice) FROM PurchaseOrderItems WHERE PurchaseOrderID = po.ID GROUP BY PurchaseOrderID), 0) Total
FROM PurchaseOrders po
INNER JOIN PurchaseOrderTypes pot
ON po.TypeID = pot.ID
INNER JOIN PurchaseOrderStatuses pos
ON po.StatusID = pos.ID
INNER JOIN Vendors v
ON po.VendorID = v.VendorID
LEFT JOIN AppropriationsRequests ar
ON po.ARID = ar.AppropriationsRequestID
LEFT JOIN PurchaseOrderItems poi
ON po.ID = poi.PurchaseOrderID
LEFT JOIN CatalogItems ci
ON poi.CatalogItemID = ci.CatalogItemID
LEFT JOIN PurchaseOrderEvents poe
ON po.ID = poe.PurchaseOrderID
WHERE ((po.POPrefix + CONVERT(VARCHAR, po.PONumber) + po.POPostfix) LIKE '%' + @number + '%'
OR @number IS NULL)
AND (po.StatusID = @statusid
OR @statusid IS NULL)
AND (CONVERT(VARCHAR, po.PRID) LIKE '%' + @pr + '%'
OR @pr IS NULL)
AND (ar.ControlNumber LIKE '%' + @ar + '%'
OR @ar IS NULL)
AND (po.VendorID = @vendorid
OR @vendorid IS NULL)
AND (poe.Event = @event
OR @event IS NULL)
AND ((CONVERT(DATETIME, poe.Value) BETWEEN @startdate AND @enddate)
OR (@startdate IS NULL AND CONVERT(DATETIME, poe.Value) <= @enddate)
OR (@enddate IS NULL AND CONVERT(DATETIME, poe.Value) >= @startdate)
OR (@startdate IS NULL AND @enddate IS NULL))
AND (po.Buyer LIKE '%' + @buyer + '%'
OR @buyer IS NULL)
AND (po.TypeID = @typeid
OR @typeid IS NULL)
AND (ci.CategoryID IN (SELECT CategoryID FROM @categories) OR @category IS NULL)
AND (ci.CatalogItemID IN (SELECT ItemID FROM @items) OR @item IS NULL)
GROUP BY po.ID,
v.Name,
po.POPrefix + CONVERT(VARCHAR, po.PONumber) + po.POPostfix,
CONVERT(VARCHAR, ISNULL(po.PRID, '')),
ISNULL(ar.ControlNumber, ''),
pot.Name,
pos.Name,
po.OrderDate
Go to Top of Page

kmcvior
Starting Member

3 Posts

Posted - 2002-03-19 : 11:33:28
You might try building the SQL dynamically based on whichever incoming vars are populated.
Something to the effect of:

DECLARE @sqlStr Varchar(1000)

SET @sqlStr = 'Select FIELDS From TABLES Where JOIN CONDITIONS '

IF @IncomingVar1 <> ''
SET @sqlStr = @sqlStr + 'AND TABLE.FIELD = @IncomingVar1 '

IF @IncomingVar2 > 0
SET @sqlStr = @sqlStr + 'AND TABLE.FIELD = @IncomingVar2 '

Do this until you've evaluated each incoming variable then use:

EXECUTE(@StrSQL)

It may also help to research dynamic SQL in general.

Hope this helps!
KM




Go to Top of Page

SimonGough
Starting Member

23 Posts

Posted - 2002-03-19 : 12:28:16

Ok, I think I am on the right track now but I am still getting the whole table returned after the stored proc is run. Here is my SQL so far:

Alter Procedure up_parmsel_list(@stockbooknum int,
@regnum varchar(15),
@make varchar(20),
@model varchar(20),
@enginesize int,
@trim varchar(20),
@fuelType int,
@shellType int,
@colour varchar(20),
@chassisNumber varchar(20)) as

declare @SQL varchar(2000)

set @SQL = 'select vehicles.vehicle_id, stock_book_number, make, model, colour, registration, engine_size, trim, shell_types.shell_type_id, fuel_types.fuel_type_id from vehicles left outer join shell_types on vehicles.shell_type = shell_types.shell_type_id left outer join fuel_types on vehicles.fuel_type = fuel_types.fuel_type_id '


if @stockbooknum > 0
set @SQL = @SQL + ' and vehicles.stock_book_number = ' + @stockbooknum

if datalength(ltrim(@regnum)) > 0
set @SQL = @SQL + ' and vehicles.registration like ''%' + @regnum + '%'''

if datalength(ltrim(@make)) > 0
set @SQL = @SQL + 'and vehicles.make like ''%' + @make + '%'''

if datalength(ltrim(@model)) > 0
set @SQL = @SQL + ' and vehicles.model like ''%' + @model + '%'''

if @enginesize > 0
set @SQL = @SQL + ' and vehicles.engine_size =' + @enginesize

if @fueltype > 0
select @SQL = @SQL + ' and vehicles.fuel_type = ' + @fueltype

if @shelltype > 0
set @SQL = @SQL + ' and vehicles.shell_type =' + @shelltype

if datalength(ltrim(@colour)) > 0
set @SQL = @SQL + ' and vehicles.colour like ''%' + @colour + '%'''

if datalength(ltrim(@chassisnumber)) > 0
set @SQL = @SQL + ' and vehicles.chassis_num like ''%' + @chassisnumber + '%'''

set @SQL = @SQL + ' order by vehicles.stock_book_number'

execute(@SQL)



Go to Top of Page

Jay99

468 Posts

Posted - 2002-03-19 : 12:48:09
Scrape the dynamic SQL . . . It is hard to read, it requires granting permissions on your base tables, its ugly and it smells funny.

Onamuji set you down the right path. I'll give you a little more of a nudge
Alter Procedure up_parmsel_list(
@stockbooknum int = null,
@regnum varchar(15) = null,
@make varchar(20) = null,
@model varchar(20) = null,
@enginesize int = null,
@trim varchar(20) = null,
@fuelType int = null,
@shellType int = null,
@colour varchar(20) = null,
@chassisNumber varchar(20) = null
)
as

select
vehicle.vehicle_id,
stock_book_number,
make,
model,
colour,
registration,
engine_size,
trim,
shell_types.shell_type_id,
fuel_types.fuel_type_id
from
vehicles
left outer join shell_types -- I think you probably want inner joins here
on vehicles.shell_type = shell_types.shell_type_id
left outer join fuel_types -- I think you probably want inner joins here
on vehicles.fuel_type = fuel_types.fuel_type_id
where
vehicles.stock_book_number = isnull(@stockbooknum, vehicles.stock_book_number) and
charindex(isnull(@regnum, vehicle.registration), vehicles.registration) > 0 and
charindex(isnull(@make, vehicle.make), vehicles.make) > 0
-- etc etc etc
order by
vehicles.stock_book_number

go


Jay
<O>


Edited by - Jay99 on 03/19/2002 12:49:40
Go to Top of Page

SimonGough
Starting Member

23 Posts

Posted - 2002-03-20 : 04:14:17
Nice one, cheers...

Simon.

Go to Top of Page

Merkin
Funky Drop Bear Fearing SQL Dude!

4970 Posts

Posted - 2002-03-20 : 06:50:31
quote:

Scrape the dynamic SQL . . . It is hard to read, it requires granting permissions on your base tables, its ugly and it smells funny.



ROFL

U funny man Jay!

Damian
Go to Top of Page
   

- Advertisement -