| Author |
Topic |
|
steamngn
Constraint Violating Yak Guru
306 Posts |
Posted - 2005-03-10 : 17:46:24
|
Here we go again!Consider for a moment the following SELECT query:select *from (SELECT svc_dat,nam,time01,time04,time07,time10,time13,time16,cast('testing the error message' as varchar(512)) as ERR_MSG From Timetablewhere 1=1 and svc_dat>=convert(datetime, convert(varchar(10), getdate(), 120)) and (isnumeric(time01)=1 or isnumeric(time04)=1 or isnumeric(time07)=1 or isnumeric(time10)=1 or isnumeric(time13)=1 or isnumeric(time16)=1)) Query1left join( Select * from SY_USR) SY_USRon Query1.NAM = SY_USR.NAM order by SY_USR.USR_IDThis query works fine as long as there is at least one timexx column that meets the ISNUMERIC tests, but if there are NO rows of data that match the tests, it returns nothing as it should.Is there a way to get this query to return one row of NULLS for all the timexx columns and also the resulting error message when no data meets the ISNUMERIC tests? I need the query to return as-is when data meets the tests, but I still need the error flag ecen when NO data meets the test. The timexx columns are varchar, and the ISNUMERIC test is used to find any rows that have a document number in them and ignore the rest. Seems like a job for CASE to me, but I just can't seem to get my head around it..Andybtw- the "1=1" thing is for Crystal; it is a placeholder for filter text passed in by our app-There's never enough time to type code right, but always enough time for a hotfix... |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-03-10 : 18:32:30
|
| Can you give us a DDL and some data?Be One with the OptimizerTG |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2005-03-10 : 18:57:09
|
| you should consider normalizing your table if you can; it makes things MUCH simplier.- Jeff |
 |
|
|
steamngn
Constraint Violating Yak Guru
306 Posts |
Posted - 2005-03-10 : 19:05:25
|
Hey TG,The table is populated off a proc and a udf. here is the table:create table TimeTable(SVC_DAT T_DAT, NAM T_NAM,CONSTRAINT PK_TimeTable PRIMARY KEY CLUSTERED ( SVC_DAT, NAM),Time01 T_DOC_NO, Time02 T_DOC_NO, Time03 T_DOC_NO, Time04 T_DOC_NO,Time05 T_DOC_NO, Time06 T_DOC_NO, Time07 T_DOC_NO, Time08 T_DOC_NO,Time09 T_DOC_NO, Time10 T_DOC_NO, Time11 T_DOC_NO, Time12 T_DOC_NO,Time13 T_DOC_NO, Time14 T_DOC_NO, Time15 T_DOC_NO, Time16 T_DOC_NO,Time17 T_DOC_NO, City01 T_CITY, CIty02 T_CITY, CITY03 T_CITY, City04 T_CITY,City05 T_CITY, City06 T_CITY, City07 T_CITY, City08 T_CITY,City09 T_CITY, City10 T_CITY, City11 T_CITY, City12 T_CITY,City13 T_CITY, City14 T_CITY, City15 T_CITY, City16 T_CITY,City17 T_CITY, Cust01 T_LST_NAM, Cust02 T_LST_NAM, Cust03 T_LST_NAM, Cust04 T_LST_NAM,Cust05 T_LST_NAM, Cust06 T_LST_NAM, Cust07 T_LST_NAM, Cust08 T_LST_NAM, Cust09 T_LST_NAM,Cust10 T_LST_NAM, Cust11 T_LST_NAM, Cust12 T_LST_NAM, Cust13 T_LST_NAM, Cust14 T_LST_NAM,Cust15 T_LST_NAM, Cust16 T_LST_NAM, Cust17 T_LST_NAM) Here is the proc:create procedure pr_CreateTimeTableasset nocount ondeclare @RunDate datetime,@PrevDate datetime,@StartDate datetime,@EndDate datetime,@DateCount datetime,@WriteAhead int,@DeleteThreshold int--set write ahead to 1 monthset @WriteAhead = 1--set delete threshold to 6 monthsset @DeleteThreshold = 6--find today's dateset @RunDate = convert(datetime, convert(varchar(10), getdate(), 120))--find date that procedure last ranselect @PrevDate = max(SVC_DAT) from TimeTableif @PrevDate is nullset @PrevDate = dateadd(dd, -1, @RunDate)--set start date to day after last runset @StartDate = dateadd(dd, @WriteAhead, @PrevDate)--set end date to next month set @EndDate = dateadd(mm, 1, @RunDate)set @DateCount = @StartDate--loop through dates and insert recordswhile @DateCount <= @EndDatebegininsert TimeTable(SVC_DAT, NAM,Time01, Time02, Time03, Time04,Time05, Time06, Time07, Time08,Time09, Time10, Time11, Time12,Time13, Time14, Time15, Time16,Time17, City01, City02, City03,City04, City05, City06, City07,City08, City09, City10, City11,City12, City13, City14, City15,City16, City17, Cust01, Cust02,Cust03, Cust04, Cust05, Cust06,Cust07, Cust08, Cust09, Cust10,Cust11, Cust12, Cust13, Cust14,Cust15, Cust16, Cust17)select @DateCount,NAM,dbo.udf_DefaultTime(@datecount, NAM, 1),dbo.udf_DefaultTime(@datecount, NAM, 2),dbo.udf_DefaultTime(@datecount, NAM, 3),dbo.udf_DefaultTime(@datecount, NAM, 4),dbo.udf_DefaultTime(@datecount, NAM, 5),dbo.udf_DefaultTime(@datecount, NAM, 6),dbo.udf_DefaultTime(@datecount, NAM, 7),dbo.udf_DefaultTime(@datecount, NAM, 8),dbo.udf_DefaultTime(@datecount, NAM, 9),dbo.udf_DefaultTime(@datecount, NAM, 10),dbo.udf_DefaultTime(@datecount, NAM, 11),dbo.udf_DefaultTime(@datecount, NAM, 12),dbo.udf_DefaultTime(@datecount, NAM, 13),dbo.udf_DefaultTime(@datecount, NAM, 14),dbo.udf_DefaultTime(@datecount, NAM, 15),dbo.udf_DefaultTime(@datecount, NAM, 16),dbo.udf_DefaultTime(@datecount, NAM, 17),dbo.udf_DefaultTime(@datecount, NAM, 18),dbo.udf_DefaultTime(@datecount, NAM, 19),dbo.udf_DefaultTime(@datecount, NAM, 20),dbo.udf_DefaultTime(@datecount, NAM, 21),dbo.udf_DefaultTime(@datecount, NAM, 22),dbo.udf_DefaultTime(@datecount, NAM, 23),dbo.udf_DefaultTime(@datecount, NAM, 24),dbo.udf_DefaultTime(@datecount, NAM, 25),dbo.udf_DefaultTime(@datecount, NAM, 26),dbo.udf_DefaultTime(@datecount, NAM, 27),dbo.udf_DefaultTime(@datecount, NAM, 28),dbo.udf_DefaultTime(@datecount, NAM, 29),dbo.udf_DefaultTime(@datecount, NAM, 30),dbo.udf_DefaultTime(@datecount, NAM, 31),dbo.udf_DefaultTime(@datecount, NAM, 32),dbo.udf_DefaultTime(@datecount, NAM, 33),dbo.udf_DefaultTime(@datecount, NAM, 34),dbo.udf_DefaultTime(@datecount, NAM, 35),dbo.udf_DefaultTime(@datecount, NAM, 36),dbo.udf_DefaultTime(@datecount, NAM, 37),dbo.udf_DefaultTime(@datecount, NAM, 38),dbo.udf_DefaultTime(@datecount, NAM, 39),dbo.udf_DefaultTime(@datecount, NAM, 40),dbo.udf_DefaultTime(@datecount, NAM, 41),dbo.udf_DefaultTime(@datecount, NAM, 42),dbo.udf_DefaultTime(@datecount, NAM, 43),dbo.udf_DefaultTime(@datecount, NAM, 44),dbo.udf_DefaultTime(@datecount, NAM, 45),dbo.udf_DefaultTime(@datecount, NAM, 46),dbo.udf_DefaultTime(@datecount, NAM, 47),dbo.udf_DefaultTime(@datecount, NAM, 48),dbo.udf_DefaultTime(@datecount, NAM, 49),dbo.udf_DefaultTime(@datecount, NAM, 50),dbo.udf_DefaultTime(@datecount, NAM, 51)from SY_USRwhere IS_SERVICER='Y'set @DateCount = dateadd(dd, 1, @DateCount)end--delete records older than thresholddeletefrom TimeTablewhere datediff(mm, SVC_DAT, @RunDate) > @DeleteThreshold And here is the udf:create function udf_DefaultTime(@SVC_DAT T_DAT,@NAM T_NAM,@TimeSlot int)returns varchar(15)asbegindeclare @OutString varchar(15),@WorkDays char(7),@Lunchtime char(51),@DayWeek int/*@DayWeek defined as: Sunday=1, Monday=2, Tuesday=3...Saturday=7WorkDays field in SY_USR table should be char(7)and formatted like 'SMTWTFS' if they work all seven daysany days that aren't worked should be changed to X like 'XMTWTXS'WorkTimes field in SY_USR table should be char(51)and formatted like 'XXXBXXLLXXXXXBXXXX;XXXBXXLLXXXXXBXXXX;XXXBXXLLXXXXXBXXXX'X indicates working, B indicates Break and L indicates lunchit must repeat 3 times to fill time city and last name columns (no semicolons)*/select @WorkDays = WorkDays,@Lunchtime = Lunchtimefrom SY_USRwhere NAM = @NAMset @DayWeek = datepart(dw, @SVC_DAT)set @OutString = nullif substring(@Workdays, @DayWeek, 1) = 'X'set @OutString = 'NO SVC'if @OutString is nullset @OutString = case substring(@Lunchtime, @TimeSlot, 1)when 'B' then 'BREAK'when 'L' then 'LUNCH'else nullendreturn @OutStringend You will also need to have an SY_USR table:BEGIN TRANSACTIONSET QUOTED_IDENTIFIER ONSET TRANSACTION ISOLATION LEVEL SERIALIZABLESET ARITHABORT ONSET NUMERIC_ROUNDABORT OFFSET CONCAT_NULL_YIELDS_NULL ONSET ANSI_NULLS ONSET ANSI_PADDING ONSET ANSI_WARNINGS ONCOMMITBEGIN TRANSACTIONCREATE TABLE dbo.SY_USR ( usr_id varchar(1) NOT NULL, NAM varchar(50) NULL, IS_SERVICER varchar(1) NULL, Workdays varchar(7) NULL, Lunchtime varchar (51) NULL ) ON [PRIMARY]GOALTER TABLE dbo.Table1 ADD CONSTRAINT PK_Table1_1 PRIMARY KEY CLUSTERED ( usr_id ) ON [PRIMARY]GOCOMMIT And finally, here is some data:Insert into SY_USR (usr_id,NAM,IS_SERVICER,Workdays,Lunchtime)VALUES (1,Joe Blow,Y,XMTWTXS,XXBXXLLXXXXXBXXXXXXXBXXLLXXXXXBXXXXXXXBXXLLXXXXXBXX) All of this mess will create the timetable with one user and no numeric entries in the timexx columns. using the original query I posted will return nothing from the timetable, which is where we need to get the err_msg to come over. if you put a numeric entry into any of the timexx columns used in the proc(01,04,07,10,13, or 16), then the query will return that row with the err_msg. Aren't you glad you asked?There's never enough time to type code right, but always enough time for a hotfix... |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-03-10 : 22:26:01
|
| Yes, I'm very sorry I asked :) I couldn't even start to work on this because all your datatypes are custom types. Also, I'm just going to pretend that whatever the logic is behind that mess is the best way to do it.If your objective is to return one row of nulls if your query doesn't return results, how about if you check @@Rowcount after the select. If it's 0, do a seperate select:Select cast(null as T_DOC_NO) as Time01, cast(null as T_DOC_NO) as Time02, etc...Be One with the OptimizerTG |
 |
|
|
steamngn
Constraint Violating Yak Guru
306 Posts |
Posted - 2005-03-11 : 15:00:15
|
Hey TG!!Sorry, I forgot the custom datatype stuff....It's Ok, I came up with a solution just now within Crystal Reports that will allow me to handle the exception when no data exists in the query. This whole timetable thing is unreal:Denormalized tables, update tests that loop within loops (Get a load of the cursor ROWCOUNT test at the beginning; isn't this cool??),and of course, udf's and the ever popular Crystal Reports.Life is good....Anyway, I already knew about doing a @@ROWCOUNT, but that would require resetting the @SQL select in order to get into Crystal, which is something that Crystal just does not like doing (once a query is executed, Crystal gets an attitude if you do it again)Hey Dr. Cross Join!That's it?Just "Normalize if possible?" After reading some of your posts (really good stuff!), I expected to see some multi-table-invert-join-not-in-if-exists-then-replace-after-update-while-having query to do the job! AndyThere's never enough time to type code right, but always enough time for a hotfix... |
 |
|
|
|
|
|