| Author |
Topic |
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-28 : 19:09:59
|
Hi all,I have a asp.net page & SQL SERVER 7.0.that will pass following info to stored procedure below.1. start date (if blank set 01/01/1998)2. end date (if blank set tomorrow's date)3. invoice status (if blank select all jobs irrespective of status)4. client id (if blank show jobs for all cleint )5. CDSContact (if blank show all jobs)CREATE Procedure up_get_job_invoice_details(@StartDate AS VarChar(10)='',@EndDate AS VarChar(10)='',@ClientID as VARCHAR(8)='All',@CDSContact as VARCHAR(8)='All',@InvStatus as VARCHAR(20)='All')AS/* Testing VariableDECLARE @StartDate AS VarChar(10)DECLARE @EndDate AS VarChar(10)DECLARE @InvStatus as VARCHAR(20)DECLARE @ClientID as VARCHAR(8)SET @StartDate='01/01/2004'SET @EndDate='01/09/2004'SET @InvStatus ='All'--SET @InvStatus ='WS4'--SET @ClientID ='All'SET @ClientID ='197CA'*/SET NOCOUNT ONSET ARITHABORT ONSET XACT_ABORT ONDECLARE @SDate AS DATETIMEDECLARE @EDate AS DATETIME-- If Start Date is blank then set start date as '01/01/1998'IF @StartDate='' SET @SDate= CONVERT(DATETIME,'01/01/1998', 103)ELSE SET @SDate= CONVERT(DATETIME, @StartDate, 103)-- If End Date is blank then set end date as tomorrow's dateIF @EndDate='' SET @EDate=GETDATE()+1ELSE SET @EDate=CONVERT(DATETIME, @EndDate, 103)+1--print @SDate--print @EDateCREATE TABLE #Job (JobNumber VarChar(10),JobName VarChar(50),ClientID Varchar(8))CREATE TABLE #InvoiceStatus(InvoiceStatus Varchar(4))CREATE TABLE #Client(ClientID Varchar(8))IF @CDSContact = 'All' INSERT INTO #Job select JobNumber,JobName,ClientID from dbo.Job where OrderDate >= @SDate AND OrderDate < @EDateELSE INSERT INTO #Job select J.JobNumber,J.JobName,J.ClientID from dbo.Job J INNER JOIN CiRelationShip CI ON J.JobNumber=CI.ContractID where J.OrderDate >= @SDate AND J.OrderDate < @EDate AND CI.ResourceID=Cast(@CDSContact as INT)IF @InvStatus = 'All' INSERT INTO #InvoiceStatus(InvoiceStatus) select distinct workstatus from ScheduleItems WHERE PROCESSID='IV'ELSE INSERT INTO #InvoiceStatus(InvoiceStatus) select @InvStatusIF @ClientID = 'All' INSERT INTO #Client(ClientID) select DISTINCT ClientID from JobELSE INSERT INTO #Client(ClientID) select @ClientIDSELECT SI.JobNumber,J.JobName,J.ClientID,Comp.CompanyName,JI.InvoiceNo,C.CodeText as "InvStatus",SI.ItemIDFROM dbo.ScheduleItems SIINNER JOIN dbo.Codes C ON SI.WorkStatus=C.CodeIDINNER JOIN #Job J ON SI.JobNumber=J.JobNumberINNER JOIN dbo.Company Comp ON J.ClientID=Comp.CiIDINNER JOIN dbo.JobInvoice JI ON SI.JobNumber=JI.JobNumberINNER JOIN #InvoiceStatus INV_ST ON SI.WorkStatus=INV_ST.InvoiceStatusINNER JOIN #Client CL ON J.ClientID=CL.ClientIDWHERE SI.ProcessID='IV' AND SI.ProductNumber=1 AND--JI.InvoiceNo IS NOT NULL AND LEN(JI.InvoiceNo)>0ORDER BY SI.JobNumberDROP TABLE #JobDROP TABLE #InvoiceStatusDROP TABLE #ClientGO Please provide me your feedback.Is there any other way to do improve it?I created temp tables to avoide dynamic sql.Thanksmk_garg |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-29 : 18:42:48
|
| No thoughts?mk_garg |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2004-09-29 : 18:47:07
|
| It would help if you formatted your query so that we could easily read it. When you post code, use code tags around it so that formatting is retained. code tags like this without spaces:[ c o d e ]code goes here already formatted from Query Analyzer or whatever tool[ / c o d e ]Tara |
 |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-29 : 19:37:56
|
| Modified it!Thanksmk_garg |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2004-09-29 : 19:49:59
|
| Nothing jumps out at me.Are the JOIN conditions indexed? It is a common mistake to think that a foreign key is automatically indexed. When a PK is created, an index is automatically created to enforce it. But the same does not hold true for a FK. You have to create them yourself. FKs should be indexed to support the JOIN conditions.Tara |
 |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-29 : 19:57:09
|
| Yes Foreign keys are indexed.I am getting results in 2 secsAs you can see i am creating temp tables and adding data based on the input parametes and then joining these to get desired results.I want to know my approach is allright or i should do something else.Thanksmk_garg |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2004-09-29 : 20:00:59
|
| I guess in order to help optimize it (although 2 seconds doesn't sound like it needs any optimization) we would need an explanation as to what is going on. Why are you using Vyas' solution for arrays if you aren't using arrays?Tara |
 |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-29 : 21:18:34
|
quote: Originally posted by tduggan Why are you using Vyas' solution for arrays if you aren't using arrays?Tara
I can expand it to use arrays.even then if user does not pass any value, by defalut i want to perform operation on all records. if you look at following code, you can see if user does not provide any value for @ClientID parameter, select all clients otherwise only passed client.IF @ClientID = 'All' INSERT INTO #Client(ClientID) select DISTINCT ClientID from JobELSE INSERT INTO #Client(ClientID) select @ClientIDI hope you got some idea.Thanksmk_garg |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2004-09-30 : 09:19:57
|
| for the potential criteria on the varchar columns, i wouldn't use the temp table approach but rather:(at the start of procedure) :if @ClientID = 'All' set @ClientID = '%'(then, in your WHERE clause) :where ClientID LIKE @ClientIDPersonally, I would accept NULL values where you are not filtering on a particular column (instead of 'All'), and then you can write:where ClientID like isnull(@ClientID, '%')without the need for the IF in the beginning part.and so on for each varchar() column in your potential filter... that should be much faster than fill up and then joing to a temp table.- Jeff |
 |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-30 : 18:37:08
|
quote: Originally posted by jsmith8858 Personally, I would accept NULL values where you are not filtering on a particular column (instead of 'All'), and then you can write:where ClientID like isnull(@ClientID, '%')- Jeff
Great tip Jeff. i was looking for something like this.In my DB length of @clientID is not fixed. I may have 100AB and 100ABC as clientID so if i pass 100AB to @ClientId it will return data for 100ABC as well.Any suggestions for INT columns to avoid temp tablemk_garg |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2004-09-30 : 21:35:51
|
| no -- it will not. you are not filtering like this:where clientID like @clientID+ '%'you are filtering like this:where clientID like ISNULL(@clientID,'%')do you see the difference?- Jeff |
 |
|
|
mk_garg20
Constraint Violating Yak Guru
343 Posts |
Posted - 2004-09-30 : 21:42:06
|
| oh yeah!Thanks for that!i will change my stored procedure according to this.Any suggestions for INT columns as wellThanksmk_garg |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2004-10-11 : 06:45:35
|
| "where ClientID like isnull(@ClientID, '%')"is this better than (@ClientID IS NULL OR ClientID LIKE @ClientID)I wonder if the optimiser can step over the "@ClientID IS NULL" and not do the "LIKE" which has got to resolve to a table scan, hasn't it?In which case presumaby it may be crucial to do(@ClientID IS NULL OR ClientID LIKE @ClientID)rather than (ClientID LIKE @ClientID OR @ClientID IS NULL)if query planner is doing left-to-right thinking ...Kristen |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2004-10-12 : 15:42:12
|
| LIKE 'A%' will use an index seek; as long as the part you are comparing to doesn't begin with '%' or '_'.I have found in my experience that WHERE COL LIKE ISNULL(@SomeVar,'%') tends to outperformWHERE (@SomeVar is NULL) or (COL = @SomeVar)in many cases.Try this in Northwind and look at the plans:declare @CID nvarchar(10);set @CID = Null;select * from customerswhere customerID like ISNULL(@CID,'%')select * from customerswhere (@CID is null) or (CustomerID = @CID)- Jeff |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2004-10-12 : 15:51:23
|
| My worry is when I have something likeWHERE COL LIKE ISNULL(@SomeVar,'%') OR COL2 LIKE ISNULL(@SomeVar2,'%')where, on average, at least one of the "criteria" will be NULL - thus that test will become "LIKE '%'" and force a table scan.I was hoping that a bunch ofWHERE (@SomeVar IS NULL OR COL LIKE @SomeVar) OR (@SomeVar2 IS NULL OR COL2 LIKE @SomeVar2)would avoid the tablescan.I suppose I should do a TEST ...Kristen |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2004-10-12 : 15:57:44
|
quote: Posted - 10/12/2004 : 15:51:23 -------------------------------------------------------------------------------- My worry is when I have something likeWHERE COL LIKE ISNULL(@SomeVar,'%') OR COL2 LIKE ISNULL(@SomeVar2,'%')
No, you would not use an OR there -- you would use an AND. If you want to do the old "set Var1 to filter by col1, var2 to filter by col2" type thing, you need to use an AND not an OR.Put an AND in there and you are good to go, in terms of both efficiency and in terms of logically returning the proper results.- Jeff |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2004-10-12 : 18:02:54
|
| Sorry, typing mistake. I do this all the time (and make typing mistakes!)Assuming AND my original question stands about "COL2 LIKE ISNULL(@SomeVar2,'%')" distilling into a table scanKristen |
 |
|
|
|