Products

Solutions

Resources

Partners

Community

Blog

About

QA

Ideas Test

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

Welcome to the DNN Community Forums, your preferred source of online community support for all things related to DNN.
In order to participate you must be a registered DNNizen

HomeHomeOur CommunityOur CommunityGeneral Discuss...General Discuss...Two Procedures which one is good?Two Procedures which one is good?
Previous
 
Next
New Post
10/25/2006 2:12 AM
 

Two ways to write the procedure, discuss which is the good one

Suppose that we have a table name [Article]:

ID

Title

Content

Hot

Elite

1

Title1

Content1 here …

True

False

2

Title2

Content2 here …

True

True

3

Title3

Content3 here …

False

False

4

Title4

Content4 here …

False

True

sometimes we want to select top 10 rows where the [Hot] is true or select top 5 rows where the [Elite] is true and sometimes we expect both the [Hot] and [Elite] are true…

Then what should we do?

The bad way is to write three procedures to fit all these situations

Another way maybe like that:

/*In the DAL*/

public static IDataReader List_Data(bool Hot,bool Elite,int PageSize)

{

SqlHelper.ExecuteReader(ConnectionString, "Article_List", GetNull(Hot), GetNull(Elite),GetNull(PageSize));

}

/* the procedure */

ALTER PROCEDURE dbo.Article_List

               (@Hot bit,

                @Elite bit,

                @PageSize int,

                @SortField varchar(50))

AS

        IF (@PageSize>0)

        BEGIN

                SET ROWCOUNT @PageSize   //return 10 or 5 rows depend on the params @PageSize

        END

        SELECT ID,Title

        FROM Article

        WHERE

            (Hot=@Hot OR @Hot=NULL)  //if you want to get data by Hot,then set @Hot=true 

        AND (Elite=@Elite OR @Elite=NULL)

        ORDER BY

                CASE @SortField          

                        WHEN 'Hits' THEN Hits  //sort by the Hit point

                        ELSE AddDate  //sort by date

                END DESC

        RETURN

------------------------------------------------------------------------------

this work no problems but if we want to add another column look like:

ID

Title

Content

Hot

Elite

Another

Then in order to run the application,we must

1、  add a new column to the DB table

2、  edit the DAL method (add one param)

3、  edit the procedure

so bad the idea!

Then I have found another way ,first create two table :

ID

Title

Content

SelectIndex

1

Title1

Content1 here …

1

2

Title2

Content2 here …

3

3

Title3

Content3 here …

8

4

Title4

Content4 here …

15

 

SelectIndexID

Name

1

Hot

2

Elite

4

Another

8

Another two

16

Another three

 

You can notice that, at the first table

1 means “Hot’

3 means “Hot”+”Elite” 1+2

8 means “Another two”

15 means “Hot”+”Elite”+”Another”+”Another two” 1+2+4+8

…….

So we can write the procedure easily:

ALTER PROCEDURE dbo. Article_List

        @SelectIndex int

AS

        SELECT ID,Title

        FROM Article

        WHERE

             SelectIndex=@SelectIndex           

        RETURN  

-----------------------------------------

compare to the first procedure,

no need to add new column to the [Article] table,we just add one record to the second table

no need to edit the DAL method and the Procedure

we can add the Index to the DB table column [SelectIndex] so it run quickly

at last be care  that ,the SelectIndexID must be 1,2,4,8,16,32,64,128…..

in this case ,we can mix up all the elements with no repeat

 

maybe someone has another good idea?

 
New Post
10/25/2006 8:20 AM
 
Personally I would favour the last method.  The "Hot", "Elite" and "Another" columns could be considered as the status of a particular article and thinking back to my DB normalisation classes you would capture this information in a seperate table as you have done in the 2nd example.

Another possible way to achieve this with only one table would be to replace the Hot, Elite and Another columns with just one column, e.g., "Status" then use bitwise comparison to return your results, but this may be a little tricky if the number of categories is dynamic.  But for example:

 4    2       1     (Binary Value)
HOT ELITE ANOTOHER
=== ===== ========
1 1 0 = 4 + 2 = 6

so your column would contain the value 6 if an article was both hot and elite

More information on SQLServer Bitwise operators can be found here:

http://msdn2.microsoft.com/en-us/library/ms176122.aspx

Hope this helps.
 
New Post
10/25/2006 11:51 AM
 

as long as there are a  limited number of attributes, your second solution using bit patterns is preferable. But for querying you need boolean expressions e.g.

SELECT * FROM Articles WHERE SelectIndex AND @SelectIndex <> 0

if you need attributes other than boolean, this approch won't work. For dynamic table structures, there are serialized approaches, like UserDefinedTable and User Profiles use to store data.


Cheers from Germany,
Sebastian Leupold

dnnWerk - The DotNetNuke Experts   German Spoken DotNetNuke User Group

Speed up your DNN Websites with TurboDNN
 
New Post
10/25/2006 1:16 PM
 

One thing to also consider is that if this table will be getting large, the index on your selectIndex column won't help when search for a single bit.  So if you want to select all the "hot" rows (selectindex = 1,3,5,9...) SQL will have to look at every row in the table.  Plus your stored procedure won't be a simple "where selectIndex = @SelectIndex"  it will be something like "where (SelectIndex & @selectIndex) = @selectIndex" at least that is how I understand it.

Also I've been told that Sql doesn't do these bit operation very efficiently and if you have separate columns for each option or setting, it will perform better.  The stored procedures will be a bit easier to read with out the bit operations. 

If you need performance at it's best you will loose some flexibility. Like easily adding columns later.  If you require that kind of flexibility you will give up some performance.  In many cases that may not even be noticeable. 

Another thing that was drilled into my head by some really smart DBA's was that "select *" should only be used sparingly.  You almost never need all the columns.  You waste resources sending and retrieving all those extra columns.  There have been times when someone adds about 20 columns to a table and all the old sp's that do select * get all this data.  It is also faster for sql to process if you identify each column you want, even if it is all of them.  SQL doesn't have to look up what columns there are each time; you just have to do it once. 

mj


Michael Jackson
Brillnat.com
Custom module development
Database access tokenized HTML modules
 
New Post
10/27/2006 8:13 PM
 
mhj96813 wrote

...So if you want to select all the "hot" rows (selectindex = 1,3,5,9...) ...

in fact,if i want to select all the "hot" rows, the @SelectIndex=1 ,but not "selectIndex=1,3,5,9...)

3 equals "Hot"+"Elite" and 5 equals "Hot"+"Another", 9 equals "Hot"+"another two"

 
Previous
 
Next
HomeHomeOur CommunityOur CommunityGeneral Discuss...General Discuss...Two Procedures which one is good?Two Procedures which one is good?


These Forums are dedicated to discussion of DNN Platform and Evoq Solutions.

For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:

  1. No Advertising. This includes promotion of commercial and non-commercial products or services which are not directly related to DNN.
  2. No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
  3. Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
  4. No Flaming or Trolling.
  5. No Profanity, Racism, or Prejudice.
  6. Site Moderators have the final word on approving / removing a thread or post or comment.
  7. English language posting only, please.
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out