Should I use a T-SQL function, view, or stored proc? -


i've got question reusing table data view won't work in scenario have parameter needs passed in. part of system requires travellerid sent procedure , list of arrangers returned specific traveller. there around 7 business rules used determine arrangers can returned , mutually exclusive, in order accommodate these optional rules have used series of unions inside derived query. working well, , performance seems across large database, need reuse these rules (unions) in 4 other parts of system.

i tried create view these unions didn't work due differing logic in each union , different parameter requirements, thinking maybe function solve issue? if created function took @travellerid param , returned list of arrangerid based on business rules, ideal/fast solution? using union , distinct in outer query proved faster using union's uniqueness of data.

current procedure business rules below (sql server 2008):

create procedure [dbo].[getarrangersfortraveller]    @travellerid int   declare @costcentreid int   declare @departmentid int  -- shorthand traveller costcentre , department use in queries below set @costcentreid = (select costcentreid traveller id = @travellerid) set @departmentid = (select departmentid traveller id = @travellerid)   select distinct t.id, t.firstname, t.lastname, ti.name title, dv.preferred traveller t  inner join title ti on t.titleid = ti.id      inner join       (              -- preferred arrangers linked department groups             select dg.arrangerid id             departmentgroup dg                  inner join department_departmentgroup ddg                  on (dg.id = ddg.departmentgroupid , ddg.departmentid = @departmentid)              union              -- preferred arrangers linked cost centre groups             select cg.arrangerid id             costcentregroup cg                  inner join costcentre_costcentregroup ccg                  on (cg.id = ccg.costcentregroupid , ccg.costcentreid = @costcentreid)              union              -- if cost centre group has linked department , department matches              -- travel arrangers department return these travel arrangers                  select t3.id             costcentregroup cg1                  inner join costcentre_costcentregroup ccg1                  on (cg1.id = ccg1.costcentregroupid , ccg1.costcentreid = @costcentreid)                   inner join traveller t3                   on t3.departmentid = cg1.departmentid                   t3.accesslevelid > 1                     union              -- direct linked travel arrangers                   select t1.travelarrangerid id               travelarranger_traveller t1              t1.travellerid = @travellerid              union              -- cost centre linked arrangers             select tc.travelarrangerid id               travelarranger_costcentre tc               tc.costcentreid = @costcentreid              union              -- department linked arrangers             select td.travelarrangerid               travelarranger_department td               td.departmentid = @departmentid              union              -- company flagged arrangers              select t2.id               traveller t2                    inner join company c on t2.companyid = c.id               t2.accesslevelid > 1                    , ((c.allowtravelarrangerdepartmentaccess = 1 , t2.departmentid = @departmentid)             or  (c.allowtravelarrangercostcentreaccess = 1 , t2.costcentreid = @costcentreid))       ) dv on dv.id = t.id  t.accesslevelid > 1 -- arranger or manager , t.isenabled = 1 order dv.preferred desc, t.lastname, t.firstname; 

i tried create view these unions didn't work due differing logic in each union , different parameter requirements, thinking maybe function solve issue? if created function took param @travellerid, , returned list of arrangerid's based on business rules, ideal/fast solution?

you're thinking procedural/oo programming, sql set based.
function work, ensure index not used when use function decision criteria/etc. non-materialized view better; in sql server there's option use indexed view (aka materialized view) notoriously constrained. goes against modular programming concepts, sql works better less try modularize , use need to.

i re-wrote query, noticed dv.preferred column referenced in outer query isn't present in inner one. being dv conglomerate of various tables & logic, id value being returned isn't of real value outside inner query because you'd need know table value came from. said, here is:

select t.id, t.firstname, t.lastname, ti.name title /*, dv.preferred */   traveller t   join title ti on t.titleid = ti.id  (exists(select null -- preferred arrangers linked department groups                  departmentgroup dg                   join department_departmentgroup ddg on ddg.departmentgroupid = dg.id                                                      , ddg.departmentid = @departmentid                 dg.arrangerid = t.id)     or exists(select null -- preferred arrangers linked cost centre groups                 costcentregroup cg                  join costcentre_costcentregroup ccg on ccg.costcentregroupid = cg.id                                                     , ccg.costcentreid = @costcentreid                cg.arrangerid = t.id)     or exists(select null -- if cost centre group has linked department , department matches travel arrangers department return these travel arrangers                      costcentregroup cg1                 join costcentre_costcentregroup ccg1 on ccg1.costcentregroupid = cg1.id                                                      , ccg1.costcentreid = @costcentreid                 join traveller t3 on t3.departmentid = cg1.departmentid                                      ,  t3.accesslevelid > 1                t3.id = t.id)     or exists(select null  -- direct linked travel arrangers                     travelarranger_traveller t1                t1.travellerid = @travellerid                  , t1.travelarrangerid = t.id)     or exists(select null -- cost centre linked arrangers                 travelarranger_costcentre tc                 tc.costcentreid = @costcentreid                  , tc.travelarrangerid = t.id)     or exists(select null -- department linked arrangers                 travelarranger_department td                 td.departmentid = @departmentid                  , td.travelarrangerid = t.id)     or exists(select null -- company flagged arrangers                  traveller t2                 join company c on t2.companyid = c.id                               , t2.accesslevelid > 1                       (   (c.allowtravelarrangerdepartmentaccess = 1 , t2.departmentid = @departmentid)                       or (c.allowtravelarrangercostcentreaccess = 1 , t2.costcentreid = @costcentreid))                  , t2.id = t.id))    , t.accesslevelid > 1 -- arranger or manager    , t.isenabled = 1 order /*dv.preferred desc,*/ t.lastname, t.firstname; 

using subquery (in, exists) alleviate duplicates issue comes using joins if there more 1 child record attached parent.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -