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.
| Author |
Topic |
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 13:30:04
|
| I have a stored proc that has 5 parameters. Based on the params, a dataset gets created for the user. The 5 params are:Project, status, funder, start date and end date.Ideally, what I want the user to enter a project and status, OR enter a funder, OR enter a start date, OR enter an end dateMy where statement right now looks like this:WHERE ((p.project LIKE @project_ID + '%' AND p.status_pa LIKE @Active + '%')OR (p.customer = @Funder)OR (p.start_date >= Convert(datetime,(@startDate)))OR (p.end_date <= Convert(datetime,(@endDate))) )But of course it doesn't work. Anyone able to point me to my error? My guess is that I am not nesting the statement correctly, but I don't know how to correct it.Thanks in advance! |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-02-06 : 13:36:23
|
| do you mean they are all optional?i.e either Project & Statusor funderor startdateor end date? |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 13:41:24
|
| Thats correct. If project and status are chosen, the others would be ignored, if funder was chosen, all the others would be ignored, etc. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-02-06 : 13:52:53
|
| I cant see any error with your where statement. WHy do you think its not working? |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 13:59:01
|
One thing I noticed is that when you listed parameters in your question you said "status" but your statement showd "@active"Here is one way to handle a bunch of optional parameters:WHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)and p.customer = isNull(@Funder, p.customer)and p.start_date >= isNull(@startDate, p.start_Date)and p.end_date <= isNull(@endDate, p.end_date) Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 14:07:20
|
| Using that where statement, if I select just a project and a staus, I get everything - every project and every status. If I select just a funder, I get every funder, not just the one entered. Its something I have been slowly building, so I started with just the project and status, which worked fine. Then I added the funder, and with just those three it worked correctly. So I added the start date parameter the way the funder was added. But now, selecting one funder gives everything, selecting a date gives what seems to be random dates, not the one supplied. Thats what made me think that the where statement isn't working.The @active is just a badly named parameter - it does mean status! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 14:36:49
|
| >>I get everything - every project and every status. If I select just a funder, I get every funder, not just the one enteredMake sure you switched your "OR"s to "AND"s?Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 14:49:19
|
| I have tried that. I took your code, TG, and used that, as you have it (although I did add the CONVERT part to the dates) and I still am getting random results. I began by commenting out everything in the where statement. Then I started with just project and status params, entered a project and a status, and got about 100 records, which would be correct. I then added the funder param, entered the same project and status, and left the funder param as NULL, and got about 700 records - all different projects, all different status.I don't know why! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 15:18:58
|
Are you testing this from your application or from a query window? Because it sounds like when you are including the @funder value, the @project and @status values are going back to NULL.And based on your original question, it sounds like that may be the intention. Are these parameters mutually exlcusive or any combination?quote: I want the user to enter a project and status, OR enter a funder, OR enter a start date, OR enter an end date
Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 15:43:19
|
| I have tested from both, but currently I am using a query window, not the app. I want the params to be exclusive of each other, so that the user will EITHER enter a (project and status) OR a (funder). The (project and staus) combo will be used the most. If the project and status are left blank, then a Funder has to be entered. If that happens, then I want all records with that funder, regardless of project or status.If someone were to just enter a start date, and no other params, I want a dataset that returns everything that starts on or after the date entered.So, if the project/status combo is left blank, then ONE, and only one, of the others have to have something in them.Gosh, I never thought it would be so hard to put into words what I am trying to do! Sorry if I am confusing the issue! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 15:48:19
|
Well let's look at something we can all see. This is the way I intended the WHERE clause to work. Where any combination of parameters could be passed and all non-null parameter values would be honored. Is this the behavior that you are looking for?If not, set the parameter list to what you want and post the "correct" result set:declare @t table (project varchar(10) ,status_pa varchar(10) ,customer varchar(10) ,start_date datetime ,end_date datetime)insert @tselect 'p1', 'inActive', 'c1', getdate()-10, getdate() union allselect 'p1', 'active', 'c1', getdate()-5, getdate() union allselect 'p1', 'active', 'c1', getdate()-3, getdate() union allselect 'p1', 'active', 'c2', getdate()-3, getdate() union allselect 'p2', 'inActive', 'c1', getdate()-10, getdate() union allselect 'p2', 'active', 'c1', getdate()-5, getdate() union allselect 'p2', 'active', 'c1', getdate()-3, getdate() union allselect 'p2', 'active', 'c2', getdate()-3, getdate() declare @project_id varchar(10) ,@active varchar(10) ,@funder varchar(10) ,@startDate datetime ,@endDate datetime--------------------------------------------------------set your desired variables:--set @project_id = 'p1'set @active = 'active'set @funder = 'c1'--set @startDate = getdate()-10--set @endDate = getdate()+1------------------------------------------------------select * from @t pWHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)and p.customer = isNull(@Funder, p.customer)and p.start_date >= isNull(@startDate, p.start_Date)and p.end_date <= isNull(@endDate, p.end_date) Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 16:56:25
|
| That seems to be right. I took that code, and put it in a query window, then tested my variables. I didn't comment them out, but put in NULL. For the project and status, I had the following, which was perfect.set @project_id = 'p1'set @active = 'active'set @funder = NULLset @startDate = NULLset @endDate = NULLIf only funder gets selected, I hadset @project_id = NULLset @active = NULLset @funder = 'c1'set @startDate = NULLset @endDate = NULLand that worked too. So, I can only think there is something basic wrong in my stored proc.ALTER PROCEDURE [dbo].[sp_Linear_DonorReport]@project_ID varchar(6), @Active varchar(10), @Funder varchar(6),@startDate datetime, @endDate datetimeASBEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON;Create Table #tbl_LinearRpt(projectId char(6), project_desc char(100), customer char(10), projSite char(10), status_pa char(10), rpm char(5), rpmName char(50), padm char(5), padmName char(50), begin_date datetime, end_date datetime, total_1400 money, total_2300 money )--Create basic linear info from PJProjIf (@Active = 'zBoth') Select @Active = ''INSERT INTO #tbl_LinearRpt(projectId, project_desc, customer,projSite, status_pa, rpm, rpmName, padm, padmName, begin_date, end_date, total_1400, total_2300) SELECT distinct p.project, p.project_desc, p.customer, NULL, p.status_pa, p.manager1, NULL, p.manager2, NULL, p.start_date, p.end_date, NULL, NULL FROM PJPROJ p WHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)and p.customer = isNull(@Funder, p.customer)and p.start_date >= isNull(@startDate, p.start_Date)and p.end_date <= isNull(@endDate, p.end_date)ORDER BY p.project--Update linear info to include PADM & RPN Names, and the projSiteUpdate lSet padmName = (Select formalName from tblAbraData where projectId=l.projectId AND pen = padm), rpmName = (Select formalName from tblAbraData where projectId=l.projectId AND pen = rpm), projSite = (select case when count(distinct pe_id02) = 1 then min(pe_id02) else 'Many' end as [projSite] from PJPent where project = l.projectId), Total_1400 = (Select Sum([dramt]-[cramt])from tbl_Totals where projectId = l.projectId and acct = '1400'), Total_2300 = (Select Sum([dramt]-[cramt])from tbl_Totals where projectId = l.projectId and acct = '2300')FROM #tbl_LinearRpt lSelect * from #tbl_LinearRptOrder by projectID/*--Select everything needed for the report datasetselect t1.projectId, t1.project_desc, t1.customer, t1.projSite, t1.status_pa, t1.rpmName, t1.padmName, t1.begin_date, t1.end_date, t2.total_1400, t2.total_2300 from #tbl_LinearRpt t1 left outer join #tbl_Totals t2on t1.projectID = t2.projectID where t1.projectId LIKE @projectId + '%'*/ENDIf I run a query on the underlying table (PJPROJ) and select * where project = '12%' and status = 'A' I get 74 records.If I run this stored proc (I right click on it, and select 'Execute Stored Procedure...'), and enter @project = '12%' and @status = 'A', passing a NULL value for the other params, I get 6 records.If I remove the other params from the stored proc, and only have @project and @status, and run it using '12%' and 'A', I get 74 records.I really can't see where I am going wrong. Of course, if it turns out to be a typo I will cry, but at least I will know! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 17:12:44
|
| I never use that: "(I right click on it, and select 'Execute Stored Procedure...')"I would use t-sql to call it. Maybe for <null> values you are supposed to leave the box alone rather than enter "NULL"? It may interperet you entry as a string: 'NULL' rather than a true NULL.Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 17:41:56
|
| I tried leaving the box alone, but then it errors out saying the param hasn't been provided. But I think you are right - there must be something wrong with how its interpreting the NULL value, because everything you said works perfectly.I'll keep pugging along at it, and see what I can find.Thanks so much for your help - I really appreciate it! |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 17:59:51
|
| I made a stored proc from the code that you posted, TG, and tested it by right clicking and selecting "Execute stored procedure..". I passed a NULL value and it worked just fine. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 18:35:10
|
quote: If I run a query on the underlying table (PJPROJ) and select * where project = '12%' and status = 'A' I get 74 records.If I run this stored proc (I right click on it, and select 'Execute Stored Procedure...'), and enter @project = '12%' and @status = 'A', passing a NULL value for the other params, I get 6 records.
your adhoc query is "select * FROM"your proc is "Select DISTINCT ... FROM"That could explain why you get different number of rows.Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-06 : 18:42:39
|
| I tried removing the Distinct part, but it made no difference. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-06 : 18:52:13
|
so these two sections return different number of rows?exec sp_Linear_DonorReport @project_id = '12%' ,@active = 'A' ,@funder = null ,@startDate = null ,@endDate = null--==========================================================================declare @project_id varchar(6) ,@active varchar(10) ,@funder varchar(6) ,@startDate datetime ,@endDate datetimeselect @project_id = '12%' ,@active = 'A' ,@funder = null ,@startDate = null ,@endDate = nullSELECT distinct p.project, p.project_desc, p.customer, NULL, p.status_pa, p.manager1, NULL, p.manager2, NULL, p.start_date, p.end_date, NULL, NULLFROM PJPROJ p WHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)and p.customer = isNull(@Funder, p.customer)and p.start_date >= isNull(@startDate, p.start_Date)and p.end_date <= isNull(@endDate, p.end_date)ORDER BY p.project Be One with the OptimizerTG |
 |
|
|
bmahony993
Yak Posting Veteran
58 Posts |
Posted - 2008-02-07 : 11:38:01
|
| No, those two sections give me 6 records back. If I change the params, and just keep @project and @active, as below, I get 74 records back.exec sp_Linear_DonorReport @project_id = '12%' ,@active = 'A' SELECT distinct p.project, p.project_desc, p.customer, NULL, p.status_pa, p.manager1, NULL, p.manager2, NULL, p.start_date, p.end_date, NULL, NULLFROM PJPROJ p WHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)ORDER BY p.projectSo then, I would add the @funder param, but leave it NULL, and I am back to 6 records.exec sp_Linear_DonorReport @project_id = '12%' ,@active = 'A' ,@funder = NULLSELECT distinct p.project, p.project_desc, p.customer, NULL, p.status_pa, p.manager1, NULL, p.manager2, NULL, p.start_date, p.end_date, NULL, NULLFROM PJPROJ p WHERE p.project LIKE isNull(@project_ID + '%', p.project)AND p.status_pa LIKE isNull(@Active + '%', p.status_pa)and p.customer = isNull(@Funder, p.customer)What I want to see is the same 74 records, and I can't see why it would only return 6. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-07 : 11:53:43
|
You must have NULL values in your data. This technique is not good for when the columns are nullable:and p.customer = isNull(@Funder, p.customer) if p.customer is null then it equates to "where NULL=NULL" which won't work.perhaps this would do it (although any existing indexes on these columns would not be used):and isNull(p.customer, 'noCust') = coalesce(@Funder, p.customer, 'noCust') Be One with the OptimizerTG |
 |
|
|
|
|
|
|
|