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 |
|
glock
Starting Member
8 Posts |
Posted - 2003-06-17 : 09:24:34
|
| Hi all,There are two questions that I want to ask you guys and I would appreciate your help on this.I have a set of tables in a relational database. For example,Person tablePersonID, Surname, Forename etc..Employee TableEmployeeID, PersonID, NationalIDNumber, DateJoinedCompanyThe relationship between the two tables is pretty obvious. The two tables join on the PersonID. If we introduce a further relationship to the above so that we now have :DivorceDivorceID, PersonID, DateOfDivorceAnd,EarmarkedDivorceID, ReceipientOfOrderAgain, we can see that the Divorce table links to the Person table and the Earmarked table joins with the Divorce table. I hope you are all happy with this extremely simplified version of a relational database.I am currently writing an SP that would take a person NationalIDNumber and return to me the tables where there is data that belongs to this member.So something like,DECLARE @PersonID INTEGERSET @PersonID = (Select PersonID from Person where NationalIDNumber = ‘XXXYYY123’)Once we have our PersonID, we can then search our Employee table for the PersonID and we can do the same for Divorce. The problem is, the Earmarked table does not directly links to the Person table so how do you do it?I thought of implementing a Binary tree structure, but I am not sure how to approach the whole concept. Any suggestion son how to tackle this kind of problems? |
|
|
dsdeming
479 Posts |
Posted - 2003-06-17 : 09:51:02
|
| This assumes that there are person/employee rows for which no corresponding row exists in Divorce or Earmarked.SELECT p.Surname, p.Forename, e.EmployeeID, e.DateJoinedCompany, d.DivorceID, d.DateOfDivorce, m.RecipientOfOrderFROM Person p JOIN Employee e ON p.PersonID = e.PersonID LEFT OUTER JOIN Divorce d ON p.PersonID = d.PersonID LEFT OUTER JOIN Earmarked m ON d.DivorceID = m.DivorceIDWHERE e.NationalIDNumber = @valueDennis |
 |
|
|
glock
Starting Member
8 Posts |
Posted - 2003-06-17 : 10:01:44
|
| Denis,Thanks for your input.I don't think I a explained my problem very well to be honest. Your solution kind of works for my original explanation of the problem but it doesn’t actually solve the problem I have.As I said in my original post. The relational database I am working with is more complex than my example. In fact, there 418 tables involved!What I am attempting to do is to be able to navigate the database and pick up the tables which have records for the person I want.So for example, I know that the person table (having PersonID as the primary key) links to the tables : Address, Notes, Employee, Divorce etc.So if Mr Bloggs has a record in those tables then by entering his ID number, the SP should return those tables.The problem is, how does the SP know that while the Peron table links to the table Divorce, how does it know that Divorce links to Earmarked?In other words, Mr Bloggs has a record in Person, a record in Divorce and a Record in Earmarked.Person links to Divorce and Divorce links to Earmarked etc..Hope this explains my position. |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2003-06-17 : 18:51:13
|
quote: What I am attempting to do is to be able to navigate the database and pick up the tables which have records for the person I want.
Take a look at this article:http://www.sqlteam.com/item.asp?ItemID=13122And look in Books Online under the "INFORMATION_SCHEMA" views, there is a view that lists the foreign key relationships between tables. You might be able to write something that can auto-generate the SQL you need to search all the related tables, but it is going to be pretty difficult (and if you don't have foreign keys defined, then you're SOL)I know you don't want to hear this, but having the computer try to figure out how tables are joined is kinda backwards. The person querying the database should know how they relate, and write queries that use those relationships. The computer does not know these things unless an operator tells it so. If you're not familiar enough with the database structure to do so, study it until you are. SQL Server's diagram feature can help get you started on deterimining how each table relates to another, you can access it through Enterprise Manager under the "Diagrams" section of the database. |
 |
|
|
glock
Starting Member
8 Posts |
Posted - 2003-06-18 : 04:37:28
|
quote: I know you don't want to hear this, but having the computer try to figure out how tables are joined is kinda backwards. The person querying the database should know how they relate, and write queries that use those relationships. The computer does not know these things unless an operator tells it so. If you're not familiar enough with the database structure to do so, study it until you are.
I have to say that I do not completely understand the relationship of the 418 tables. If I did, I would be earning more money! But my idea is to develop a tool that would take a NationalIDNumber and search the database for records that belong to the specific person.quote: SQL Server's diagram feature can help get you started on deterimining how each table relates to another, you can access it through Enterprise Manager under the "Diagrams" section of the database.
That is something I have been playing around with lattely but it doesn't seem to work the way I thought it would. When I select the table that I want and also select the depth of the relationship, I only seem to get the table I select and no relationships at all. I've given up on it for now, but thanks for the link. I will check it out.Have a good day! |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-06-26 : 04:48:26
|
| Let me think for a while... :)Edited by - Stoad on 06/27/2003 05:09:28 |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-06-27 : 05:04:29
|
Here is my approach:____t0____ ______t1___________ ___t2___ ___t3___p0 p1 p1 p2 p3 p2 p3---------- ------------------- ------ ------0 11 1 222 3 2 300 1 11 22 3 22 33000 11 111 222 333 222 333---------- ------------------- ------- ---------___t4___ ____t5_________ __t6__ ____t7_____p4 p0 p5 p0 p6 p6 p7 p4-------- --------------- ---- -------------4 00 5 00 666 6 7 44444 00 55 0 6 66 77 44444 0 555 0 66 666 777 444-------- --------------- ----- ------------ REFERENCES OUTPUT __________t__________ _______tt_______ n1 c n2 s nn cc vv -------------------- ------------------- t0 p0 t0 0 t0 p0 0 << Initiator t0 p1 t1 0 t1 p1 11 t1 p1 t1 0 t2 p2 22 t1 p2 t2 0 t3 p3 3 t1 p3 t3 0 t4 p4 444 t2 p2 t2 0 t5 p5 55 t3 p3 t3 0 t5 p5 555 t4 p4 t4 0 t6 p6 6 t4 p0 t0 0 t6 p6 66 t5 p5 t5 0 t7 p7 7 t5 p0 t0 0 t7 p7 777 t5 p6 t6 0 ------------------------ t6 p6 t6 0 t7 p7 t7 0 t7 p4 t4 0 -------------------- =All here is input data except of 10 'last' rows in tt table. What is the best way to getthem into tt? Of course, not for this special case of 8 tables only. Surely the populatingof tt table means solving glock's problem. Simplifying conditions:1) first column in each table is its PK;2) all columns are 'varchar(50)' data type;3) names of PK-FK columns are the same thru all tables;My newbie's solution (T-SQL 7.0) seems works but looks messy. Would like to seesmarter ones. :)This my code populates tt table properly enough :) Of course, we can (inside of thecode) put together a Select Statement String along with inserting rows into tt table.Then we get something like this:'select * from t0, t1, ... where t0.p0='0' and t1.p1='11' and ... 'declare@nn varchar(50), @cc varchar(50), @vv varchar(50), @j varchar(999),@n1 varchar(50), @c varchar(50), @n varchar(50), @ss varchar(50)----------------------- Initialization ----------------------set @nn='t0' set @cc='p0' set @vv='0' --- choose any correct valuesset @n=@nn set @ss=@nn delete from ttinsert into tt (nn, cc, vv) select @nn, @cc, @vvupdate t set s='0'-------------------------------------------------------------while @@rowcount>0begin------------ processing of t0-t4 like relations -------------declare abc cursor for select nn, cc, vv from ttopen abcfetch next from abc into @nn, @cc, @vvwhile @@fetch_status=0begindeclare xyz cursor forselect a.n1, a.c from t a, t bwhere a.n1=b.n1 and a.n1=a.n2 and b.n2=@nn and b.n1<>b.n2 and b.s='0'open xyzfetch next from xyz into @n1, @cwhile @@fetch_status=0beginselect @j='insert into tt (nn, cc, vv) select '+"'"+@n1+"'"+','+"'"+@c+"'"+','+@c+' from '+@n1+' where '+@cc+'='+"'"+@vv+"'"exec (@j)select @j='update t set s=''2'' where n1='+"'"+@n1+"'"+' and n2='+"'"+@n+"'"exec (@j)fetch next from xyz into @n1, @cendclose xyzdeallocate xyzfetch next from abc into @nn, @cc, @vvendclose abcdeallocate abc----------- processing of to-t1 like relations --------------declare abc cursor for select nn, cc, vv from ttopen abcfetch next from abc into @nn, @cc, @vvwhile @@fetch_status=0beginif @ss<>@nn begin set @ss=@nn update t set s='2' where s='1' enddeclare xyz cursor forselect a.n1, a.c from t a, t b where b.n1=@nn and b.n1<>b.n2and a.n1=b.n2 and a.n1=a.n2 and b.s<>'2'open xyzfetch next from xyz into @n1, @cwhile @@fetch_status=0beginselect @j='insert into tt (nn, cc, vv) select '+"'"+@n1+"'"+','+"'"+@c+"'"+','+@c+' from '+@nn+' where '+@cc+'='+"'"+@vv+"'"exec (@j)select @j='update t set s=''1'' where n1='+"'"+@nn+"'"+' and n2='+"'"+@n1+"'"exec (@j)fetch next from xyz into @n1, @cendclose xyzdeallocate xyzfetch next from abc into @nn, @cc, @vvendclose abcdeallocate abcendEdited by - Stoad on 07/02/2003 06:43:11 |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-06-28 : 05:23:16
|
| Just have tried to rewrite the code into recursive one butit seems not going to be more compact nor plainer. |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-06-28 : 13:29:26
|
| Heh... what a recursion? Open BOL and read (capacity of objects):Nested stored procedure levels 16(ver. 6.5) 32(ver. 7.0) |
 |
|
|
Stoad
Freaky Yak Linguist
1983 Posts |
Posted - 2003-07-02 : 06:40:06
|
| This 'select' is for populating our (quasi) REFERENCES t table:select d.n1, d.cn, d.n2, '0'from (select a.table_name n1, b.column_name cn, c.table_name n2from information_schema.tables a, information_schema.columns b,information_schema.tables c where a.table_type='base table' anda.table_name=b.table_name and c.table_type='base table' anda.table_name<>'dtproperties' and c.table_name<>'dtproperties') dwhere exists(select 0 from sysindexes i, syscolumns c, sysobjects o, syscolumns c1where o.id=object_id(d.n2)and o.id=c.id and o.id=i.id and (i.status &0x800)=0x800 and c.name=index_col(d.n2,i.indid,c1.colid) and c1.colid<=i.keycnt and c1.id=object_id(d.n2) and d.cn=convert(sysname,c.name))order by 1, 2, 3- Vit |
 |
|
|
|
|
|
|
|