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 |
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-19 : 13:32:25
|
It appears that I will be the lucky receipent of a transition of an application.Access From End, SQL 2000 backendThis rocket scientist coded like:SELECT TOP 100 PERCENT Col1, col2 FROM Table1 LEFT JOIN Table2SELECT col1, col2, col3 FROM Table GROUP BY col1, col2, col317 Table JoinsThe list goes on.Now the question.There are 5 SPROCS, but each 1 has over a hundred "function" calls. In other words, the Access front makes 1 call to s sproc, but passes in which function needs to be executed (along with parameters.I don't understand how the damn things runs or stays afloat.Isn't this a serious design flaw?(Not that I plan on opening the damn thing unless I have too).Brett8-) |
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-05-19 : 13:45:06
|
Hey Jeff, where'd your reply go? Decide to delete it?Tara |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-19 : 13:55:59
|
What did he say?Brett8-) |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-05-19 : 13:57:20
|
He gave explanations as to why the rocket scientist could have coded that way.Tara |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-19 : 14:09:18
|
Well I'm sure he did.Mostly it appears that this developer decided to take an existing poorly design access database and port it.You know how queries are usually called from queries? I've seen levels as deep as 12 with many branchs. Why? Because:Here's a sample of what I'm looking at. (Notice the Group By, there's no aggregation or scalar function in the SELECT..he really wanted a distinct row...and how do you do that in Access if you don't know the keyword DISTINCT...)SELECT tblCaseTrackerUnique.CompletedBy, [FirstName] + ' ' + [LastName] AS Handler, tblLkUpTLCs.TeamLeader, qryCaseTrackerPrivacyCardByUser.CountOfRecordID AS TotalHandled, qryCaseTrackerPrivacyCardPending.CountOfRecordID AS Pending, qryCaseTrackerPrivacyCardComplete.CountOfRecordID AS Completed, qryCaseTrackerPrivacyCardPendingQR.CountOfRecordID AS PendingQR, qryCaseTrackerPrivacyCardNotToBeQRd.CountOfRecordID AS NotToBeQRd, qryCaseTrackerPrivacyCardBypass.CountOfRecordID AS Bypass, qryCaseTrackerPrivacyCardCorrect.CountOfRecordID AS Correct, qryCaseTrackerPrivacyCardIncorrect.CountOfRecordID AS IncorrectFROM ((((((((tblCaseTrackerUnique WITH (NOLOCK)LEFT OUTER JOIN (tblNames LEFT OUTER JOIN tblLkUpTLCs ON tblNames.TLCsID = tblLkUpTLCs.TLCsID) ON tblCaseTrackerUnique.CompletedBy = tblNames.IonsID) -- qryCaseTrackerUniqueCaseIDByUserLEFT OUTER JOIN ( SELECT qryCaseTrackerUniqueCaseIDByUser.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) AS CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerUniqueCaseIDByUser ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerUniqueCaseIDByUser.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerUniqueCaseIDByUser.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) --added AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) GROUP BY qryCaseTrackerUniqueCaseIDByUser.CompletedBy )AS qryCaseTrackerPrivacyCardByUser ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardByUser.CompletedBy) LEFT OUTER JOIN -- qryCaseTrackerPrivacyCardPending ( SELECT qryCaseTrackerPrivacyCardPending.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardPending ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardPending.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardPending.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberE=2 AND tblCaseTrackerAddInfo.NumberJ=4 GROUP BY qryCaseTrackerPrivacyCardPending.CompletedBy )AS qryCaseTrackerPrivacyCardPending ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardPending.CompletedBy) LEFT OUTER JOIN -- qryCaseTrackerPrivacyCardComplete ( SELECT qryCaseTrackerPrivacyCardComplete.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardComplete ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardComplete.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardComplete.CaseID WHERE ((((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberE=2 AND tblCaseTrackerAddInfo.NumberJ<>4) OR ((((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberE<>2) GROUP BY qryCaseTrackerPrivacyCardComplete.CompletedBy )AS qryCaseTrackerPrivacyCardComplete ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardComplete.CompletedBy) LEFT OUTER JOIN --qryCaseTrackerPrivacyCardPendingQR ( SELECT qryCaseTrackerPrivacyCardPendingQR.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardPendingQR ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardPendingQR.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardPendingQR.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberE=1 AND tblCaseTrackerAddInfo.NumberJ=4 AND qryCaseTrackerPrivacyCardPendingQR.QRdBy Is Null GROUP BY qryCaseTrackerPrivacyCardPendingQR.CompletedBy )AS qryCaseTrackerPrivacyCardPendingQR ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardPendingQR.CompletedBy) LEFT OUTER JOIN --qryCaseTrackerPrivacyCardNotToBeQRd ( SELECT qryCaseTrackerPrivacyCardNotToBeQRd.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardNotToBeQRd ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardNotToBeQRd.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardNotToBeQRd.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) --AND (tblCaseTrackerAddInfo.NumberE=1 or tblCaseTrackerAddInfo.NumberE=2) AND tblCaseTrackerAddInfo.NumberJ=4 AND qryCaseTrackerPrivacyCardNotToBeQRd.QRdBy Is Not Null GROUP BY qryCaseTrackerPrivacyCardNotToBeQRd.CompletedBy )AS qryCaseTrackerPrivacyCardNotToBeQRd ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardNotToBeQRd.CompletedBy)LEFT OUTER JOIN --qryCaseTrackerPrivacyCardBypass ( SELECT qryCaseTrackerPrivacyCardBypass.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardBypass ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardBypass.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardBypass.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberJ=3 GROUP BY qryCaseTrackerPrivacyCardBypass.CompletedBy )AS qryCaseTrackerPrivacyCardBypass ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardBypass.CompletedBy) LEFT OUTER JOIN --qryCaseTrackerPrivacyCardCorrect ( SELECT qryCaseTrackerPrivacyCardCorrect.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardCorrect ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardCorrect.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardCorrect.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberJ=1 GROUP BY qryCaseTrackerPrivacyCardCorrect.CompletedBy )AS qryCaseTrackerPrivacyCardCorrect ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardCorrect.CompletedBy) LEFT OUTER JOIN --qryCaseTrackerPrivacyCardIncorrect ( SELECT qryCaseTrackerPrivacyCardIncorrect.CompletedBy, Count(tblCaseTrackerAddInfo.RecordID) As CountOfRecordID FROM tblCaseTrackerAddInfo WITH (NOLOCK) INNER JOIN ( SELECT tblCaseTrackerUnique.* FROM tblCaseTrackerUnique WITH (NOLOCK) WHERE ((tblCaseTrackerUnique.ProjectID)=@ProjectID) ) as qryCaseTrackerPrivacyCardIncorrect ON tblCaseTrackerAddInfo.ProjectID=qryCaseTrackerPrivacyCardIncorrect.ProjectID AND tblCaseTrackerAddInfo.CaseID=qryCaseTrackerPrivacyCardIncorrect.CaseID WHERE (((tblCaseTrackerAddInfo.ProjectID)=30) AND (tblCaseTrackerAddInfo.NumberG<>0) AND ((tblCaseTrackerAddInfo.CreatedDate) Between @DateStart And @DateEnd)) AND tblCaseTrackerAddInfo.NumberJ=2 GROUP BY qryCaseTrackerPrivacyCardIncorrect.CompletedBy )AS qryCaseTrackerPrivacyCardIncorrect ON tblCaseTrackerUnique.CompletedBy = qryCaseTrackerPrivacyCardIncorrect.CompletedByWHERE (((qryCaseTrackerPrivacyCardByUser.CompletedBy) =@ID))GROUP BY tblCaseTrackerUnique.CompletedBy, [FirstName] + ' ' +[LastName], tblLkUpTLCs.TeamLeader, qryCaseTrackerPrivacyCardByUser.CountOfRecordID, qryCaseTrackerPrivacyCardPending.CountOfRecordID, qryCaseTrackerPrivacyCardComplete.CountOfRecordID, qryCaseTrackerPrivacyCardPendingQR.CountOfRecordID, qryCaseTrackerPrivacyCardNotToBeQRd.CountOfRecordID, qryCaseTrackerPrivacyCardBypass.CountOfRecordID, qryCaseTrackerPrivacyCardCorrect.CountOfRecordID, qryCaseTrackerPrivacyCardIncorrect.CountOfRecordID Brett8-) |
|
|
MichaelP
Jedi Yak
2489 Posts |
Posted - 2003-05-19 : 15:20:38
|
I've seen some complicated things in my day, but OH MY GOD!@!@Michael<Yoda>Use the Search page you must. Find the answer you will.</Yoda> |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-19 : 15:29:40
|
Thanks Mike...you feel my pain?And it's more ignorant than complicated...some things just don't make sense( GROUP BY) and some are just down right dangerous (SELECT * in a derived table...puleeze).Anyway, know anyone what a hundred function call sproc would be performance wise? At first I though it'd be bad, but if it keeps getting called won't it get stored in buffer space and be resident?And if 2 calls to a sproc occur at the same time, aren't they "launching" their own virtual whatever? Or will there be contention?Brett8-)Edited by - x002548 on 05/19/2003 15:30:55Edited by - x002548 on 05/20/2003 10:04:15 |
|
|
MichaelP
Jedi Yak
2489 Posts |
Posted - 2003-05-19 : 15:43:55
|
I'm not sure I fully understand what that old coder did, but maybe you should make a stored proc that has the "function calls" in it and the function calls call a stored proc that takes care of whatever the function call should do.Michael<Yoda>Use the Search page you must. Find the answer you will.</Yoda> |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2003-05-19 : 16:36:30
|
I got fed up drawing little boxes and arrows on the backs of envelopes trying to follow the queries in the last Access database I had dealings with: sat down and wrote something that (kind-of) works out what queries & tables get referenced by other queries, splats it into a GraphViz file and gets dot to draw the damned thing instead. |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-20 : 10:02:53
|
Arnold,I kind of follow but..quote: splats it into a GraphViz file and gets dot to draw the damned thing instead.
you lost me there...I'm guessing you wrote something (what) in vba/vb that interogates the collections...but the splats thing confuses me. Also how do you get a graphical representation (I'm assuming).I've been screen shooting a documenting the layers.Also any comment about a single stored procedure that has over a hundred uses? Pros/Cons of such an approach?I think I'm getting this damn mess sometime in July...After a "knowledge" transferBrett8-) |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-20 : 10:07:15
|
quote: I'm not sure I fully understand what that old coder did, but maybe you should make a stored proc that has the "function calls" in it and the function calls call a stored proc that takes care of whatever the function call should do.
Thanks Mike, but there are 5 sprocs, each with 100 "functions". That would mean I'd have to recode 500 sprocs...no thanks...I've been give this "gift" as maint mode only...and that's where I'll leave it...Just wondering when(if) perfromance will bottom out, in which case I'll have to do something...Brett8-) |
|
|
JimL
SQL Slinging Yak Ranger
1537 Posts |
Posted - 2003-05-20 : 10:20:07
|
I have been Creating systems in access for years. But This............ I think Someone was getting paid buy the hour, and wanted to create somthing no one could work on. Ive seen this done before we Refer to it as a MUGWAMP devopment. I will not give the translation for MUGWAMP as there may be more sensitive readers out there and it is not very nice. JimUsers <> Logic |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-20 : 13:33:33
|
Just blew my mind with that, I'll keep looking at that site, but if you could back fill a little in your spare time, that'd be great.Sounds like something I could definetly utilize.Brett8-) |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2003-05-20 : 16:53:22
|
Brett,Really I was picking up on your "You know how queries are usually called from queries? I've seen levels as deep as 12 with many branchs." comment. To be honest, I was probably not considering the SQL Server backend and your SP problems... sorry.Anyways... here's a story I'd already written a little Access database that interrogated the various collections in other Access databases and put the results into tables (not wholly dissimilar from the INFORMATION_SCHEMA views in SQL Server). I'd found this made it much easier to answer questions like what tables are not used as FKs, are there any duplicate indexes, and so on -- the sort of questions you have when someone dumps a complicated, undocumented database on your workdesk.Anyway, I was finding it difficult to visualize what connected to what and how parts of the database clustered, both for table relationships and queries referencing other queries.So to draw a pretty graph of what queries reference what...There's a query that looks at the SQL for the queries and decides whether each table / query is used by that query:PARAMETERS dbname Text;INSERT INTO QueryTQRefs ( [Database], Query, type, object )SELECT mQuery.Database, mQuery.Query, TableQueryUnion.type, TableQueryUnion.objectFROM TableQueryUnion INNER JOIN mQuery ON TableQueryUnion.database = mQuery.DatabaseWHERE (((mQuery.Database)=[dbname]) AND ((mQuery.SQL) Like ("*[!!.][[]" & [Object] & "]*"))) OR (((mQuery.Database)=[dbname]) AND ((TableQueryUnion.object) Not Like "*[- /+µ&()#]*") AND ((mQuery.SQL) Like ("*[, (]" & [Object] & "[,; )]*"))); As you can see, there are some nasty heuristics in the Like expressions! Since they don't always work, it has a list of false references to delete from QueryTQRefs.I think I used this to help somewhat, but I don't really remember where it came from!SELECT O.Name AS Query, Q.Name1 AS TabFROM MSysObjects AS OINNER JOIN MSysQueries AS Q ON O.Id = Q.ObjectIdWHERE Q.Attribute=5 Then it creates a text file that can be read by the GraphViz tools. Since the references between queries and tables are (one hopes!) acyclic, dot and dotty do a not-bad job, as long as things don't get too congested. It's probably possible to drive GraphViz directly through an API, but I didn't need anything that slick.It outputs a node definition for each distinct table and query, which is just a line of text that gives the node an identifier (sadly, I found I had to assign artificial names to each node since some Access object names were illegal), a label (the name), a shape (I drew tables as rectangles, queries as ellipses) and a colour (I had different colours for select, append, insert, update, etc.).It outputs an edge for each reference of a node in a query. The only attributes I used here were to have the result of action queries (make table, append, update, insert, delete) point 'upstream' and be a different colour.Identifying the table affected by the action queries was done by this query:SELECT O.Name AS Query, Q.Name1 AS TabFROM MSysObjects AS OINNER JOIN MSysQueries AS Q ON O.Id = Q.ObjectIdWHERE Q.Attribute=1 AND Q.Flag IN (2,3) Then it just starts dotty up with a Shell call.Edited by - Arnold Fribble on 05/20/2003 16:56:23 |
|
|
AjarnMark
SQL Slashing Gunting Master
3246 Posts |
Posted - 2003-05-21 : 13:35:35
|
quote: Thanks Mike, but there are 5 sprocs, each with 100 "functions". That would mean I'd have to recode 500 sprocs...no thanks...I've been give this "gift" as maint mode only...and that's where I'll leave it...Just wondering when(if) perfromance will bottom out, in which case I'll have to do something...Brett8-)
Aw, gee, Brett, you get ALL the fun projects!Not sure what would cause "performance to bottom out" other than perhaps some call that might trigger recursive calls to the sproc (such as calling another function inside the same sproc that calls another function, etc., etc.) Hopefully they don't do that. Other than that, I think it's mostly "just" a management and maintenance nightmare. But don't worry, I think hunting season for former employees and consultants opens in just a few weeks. ------------------------------------------------------The more you know, the more you know you don't know. |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-05-21 : 13:52:15
|
Arnold,Thanks a bunch, esp for taking the time. It should be a big help.Mark,10 gauge or 12 gauge?I'm seriously worried about this mess...It'll be like: "here you go...transition...BOOOOOOOOOOOOOOOOOOOOOOOOOOOM"Brett8-) |
|
|
AjarnMark
SQL Slashing Gunting Master
3246 Posts |
Posted - 2003-05-21 : 14:17:46
|
quote: Mark,10 gauge or 12 gauge?I'm seriously worried about this mess...It'll be like: "here you go...transition...BOOOOOOOOOOOOOOOOOOOOOOOOOOOM"
Use whatever you like, Brett. Personally, I kinda like poison-tipped darts from a blow gun, but my absolute favorite is the Gunting. It generates more pain and agony. And I don't want to scare you off here, but have you noticed how many of the folks who have posted more than 1000 times here have gone through a "transition" in their place of work in the last year?------------------------------------------------------The more you know, the more you know you don't know. |
|
|
|
|
|
|
|