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 |
|
nic
Posting Yak Master
209 Posts |
Posted - 2004-04-21 : 11:52:45
|
Hi,I'm building an application that will have some dynamic rule capabilities. Esentially I am building a data driven rule generator (for loss of a better name). The generator will consist of a number of different tables. In the tables, I will store metadata about a particular record. I will need to get the meta-data from these tables, query the appropriate records and then return the values inorder to make some comparisons. I'm curious if anyone has done anything like this before and might have some suggestions (I can power through it, but there might be an elegant way to do it). In a rule table I store a tableName and fieldName information. I need to build a procedure that will query this table, retrieve the values which will then be used inorder to get the required data.-- rule tableCREATE TABLE [HomeEndorsementFieldRuleDetails] ( [RuleName] [varchar] (20), [DataTable] [varchar] (50), [DataField] [varchar] (50), [StartRange] [varchar] (50), [EndRange] [varchar] (50), [DataType] [varchar] (10))GO-- table where I need to make a comparisonCREATE TABLE [QuoteDwellings] ( [QuoteID] int, [FormType] [varchar] (20), [RoofType] [varchar] (20), -- other columns)GOINSERT INTO HomeEndorsementFieldRuleDetails VALUES ('Rule1','QuoteDwellings','RoofType','Clay','Steel','str')goINSERT INTO HomeEndorsementFieldRuleDetails VALUES ('Rule1','QuoteDwellings','RoofType','Wood','Wood','str')goINSERT INTO HomeEndorsementFieldRuleDetails VALUES ('Rule1','QuoteDwellings','FormType','HO3','HO4','str')goINSERT INTO QuoteDwellings VALUES (100,'HO3','Wood')goINSERT INTO QuoteDwellings VALUES (101,'DP','Clay')gofor the particular rule (rule1) I need to get the FormType and RoofType for a particular record inorder to make some comparisons. Depending on whether the comparison is true/false I will read from other tables to perform some actionSo for QuoteID 100, I want to see if rule1 is valid. It is since both FormType and RoofType meet the comparison values (StartRange/EndRange allows me to make string comparisons as will as range (i.e. between 100 and 200) comparisons)For QuoteID 101, rule1 fails. RoofType is true but FormType returns false. This is a shot in the dark, but everyone in this forum have great ideas and was curious what people think. This is my idea:Create a sp that retrieves the table and field information which is put into a cursor, loop through the result set building the dynamic sql which will then return one select statement per comparison item. Then in the application code (C#) I will compare what is in the meta-data table with what was returned from the cursor. If the comparison is true, an action will be performed.(I know cursors are generally bad but I don't see any other way, which is why I'm posting a question. I could return the data to C# and loop through it that way but why make two calls when I could do it in one sp (with a cursor))Nic |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2004-04-21 : 12:12:30
|
Great Post![thud]ouchOMGDDL and sample Data!Gotta get up off the floor and climb on to my barst...uh office chari[/thud] SELECT * FROM QuoteDwellings qINNER JOIN HomeEndorsementFieldRuleDetails r1 ON q.FormType >= r1.StartRange AND q.FormType <= r1.StartRange AND r1.DataField = 'FormType'INNER JOIN HomeEndorsementFieldRuleDetails r2 ON q.RoofType >= r2.StartRange AND q.RoofType <= r2.StartRange AND r2.DataField = 'RoofType' Brett8-) |
 |
|
|
nic
Posting Yak Master
209 Posts |
Posted - 2004-04-21 : 14:11:49
|
Thanks for the help. The problem is in the ruleDetails table the tableName and FieldName are dynamic. I need to read from that table and then use that data to retrieve the data from the "Quotes" tables. For each rule there may be a number of different records (for comparisons of different fields in different tables).I need to return what is currently stored in the quotes table (in this example the QuoteDwellings) so I can make the comparison to see if the rule returns as true.Here is a rough example (in reality there are more tables involved)-- this will be part of a sp declare @sqlTxt varchar(1000),@dataField varchar(50),@dataTable varchar(50),@state varchar(2),@id int,@maxId int,@QuoteID int-- this will be passed into the spset @QuoteID = 100-- sp will also return all the field data that this result set will need to be compared against-- create temp tableCREATE TABLE #EndorseRulesTemp( id INT identity (1,1) ,DataTable varchar(50) ,DataField varchar(50)) -- get table/field info and insert into temp table-- in reality the ruls are associated with different companies etc (so there is a where clause etc)INSERT #EndorseRulesTemp( DataTable ,DataField) SELECT a.DataTable ,a.DataFieldFROM HomeEndorsementFieldRuleDetails a GROUP BY a.DataTable ,a.DataField-- get ordinal positions of temp tableSELECT @id = 0 ,@maxid = MAX(id) FROM #EndorseRulesTemp WHILE @id < @maxid BEGIN -- get next column id SELECT @id = MIN(id) FROM #EndorseRulesTemp WHERE id > @id -- retrieve data from temp table SELECT @dataTable = DataTable ,@dataField = DataField FROM #EndorseRulesTemp WHERE id = @id -- build data SELECT @sqlTxt = 'SELECT ' SELECT @sqlTxt = @sqlTxt + '''' + @dataTable + ''' AS DataTable ' SELECT @sqlTxt = @sqlTxt + ',''' + @dataField + ''' AS DataField ' SELECT @sqlTxt = @sqlTxt + ',' + @dataField + ' AS DataValue ' SELECT @sqlTxt = @sqlTxt + 'FROM ' + @dataTable + ' WHERE QuoteID = ' + CAST(@QuoteID AS varchar) --PRINT(@sqlTxt) EXEC(@sqlTxt) ENDDROP TABLE #EndorseRulesTemp Nic |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2004-04-21 : 14:31:34
|
I think it'd be easier if it was more normalized like thisCREATE TABLE [QuoteDwellings] ( [QuoteID] int, [HousePartType] varchar(20), [HousePart] [varchar] (20) -- No other columns)GOINSERT INTO QuoteDwellings (QuoteID, HousePartType, HousePart) SELECT 100,'FormType','H03' UNION ALLSELECT 100,'RoofType','Wood' UNION ALLSELECT 101,'FormType','DP' UNION ALLSELECT Brett8-) |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2004-04-21 : 15:44:07
|
| I'm actually trying this...but I'm having a little trouble...[CODE]USE NorthwindGOSET NOCOUNT ONGOCREATE TABLE [HomeEndorsementFieldRuleDetails] ( [RuleName] [varchar] (20), [DataTable] [varchar] (50), [DataField] [varchar] (50), [StartRange] [varchar] (50), [EndRange] [varchar] (50), [DataType] [varchar] (10))GOINSERT INTO HomeEndorsementFieldRuleDetails([RuleName],[DataTable],[DataField],[StartRange],[EndRange],[DataType])SELECT 'Rule1','QuoteDwellings','RoofType','Clay','Steel','str' UNION ALLSELECT 'Rule1','QuoteDwellings','RoofType','Wood','Wood','str' UNION ALLSELECT 'Rule1','QuoteDwellings','FormType','HO3','HO4','str'GOCREATE TABLE [QuoteDwellings] ( [QuoteID] int, [HousePartType] varchar(20), [HousePart] [varchar] (20), [RowId] int IDENTITY(1,1) -- No other columns)GOINSERT INTO QuoteDwellings (QuoteID, HousePartType, HousePart) SELECT 100,'FormType','HO3' UNION ALLSELECT 100,'RoofType','Wood' UNION ALLSELECT 101,'FormType','DP' UNION ALLSELECT 101,'RoofType','Clay'GOSELECT * FROM QuoteDwellingsDECLARE @sql varchar(8000), @QuoteId intSELECT @SQL = 'SELECT * FROM QuoteDwellings q ', @QuoteId = 100SELECT @SQL = @SQL + 'INNER JOIN HomeEndorsementFieldRuleDetails r'+CONVERT(varchar(3),[RowId]) + ' ON q.HousePart >= r'+CONVERT(varchar(3),[RowId])+'.StartRange' + ' AND q.HousePart <= r'+CONVERT(varchar(3),[RowId])+'.EndRange' + ' AND r'+CONVERT(varchar(3),[RowId])+'.DataField = ' + '''' + HousePartType+ ''''FROM QuoteDwellingsWHERE QuoteID = @QuoteIdSELECT @SQL = @SQL + 'WHERE QuoteId = ' + CONVERT(varchar(10),@QuoteId)SELECT @SQL EXEC(@SQL)SET NOCOUNT OFFGODROP TABLE QuoteDwellingsDROP TABLE HomeEndorsementFieldRuleDetailsGO[/CODE]Brett8-) |
 |
|
|
|
|
|
|
|