Handling SortOrder fields in SQL Server - asp.net

In a specific table I have a SortOrder integer field that tells my page in which order to display the data. There are sets of data in the this field (based on a CategoryID field), and each set will have its own ordering. Users can add/remove/update records in this table.
My question is what is the best way to manage this SortOrder field? I would like to "reseed" it everytime a record is deleted or updated. Is this something I should be using a trigger for? Or should my code handle it and manage the reseeding?

What I used to do is use only odd numbers in the SortOrder field so upon changing the order, I would add or subtract 3 from the current value of the modified item and then do a reseed (order the items again using odd number indexes). Also I used to reseed after every insert or delete.

All you really have to worry about is swapping any two fields. All new entries go to the end and i'm sure you've got a mechanism by which the user can change the order. The order change, move up or down, really is a swap with a neighboring field. All you really care about is that all the fields are sorted properly. Don't let a mathematical sense of aesthetic drive you into creating something overly complex. (You'll end up with holes in your sequence after deletes are made but that's OK. It's an internal sequence marker used for ORDER BY. the numbers don't need to be made contiguous.)

Related

check duplicate values in oracle forms multi record block

What I wanted is to display an alert when I move to the next row if the record that I inserted is already one of the records in the multi record block.
and in what trigger must I put it?
There are several options you can use.
One is to POST values entered (in WHEN-NEW-RECORD-INSTANCE) trigger. It will, well, post everything you entered so far. Then, you can write a WHEN-VALIDATE-ITEM trigger which SELECTs from that table and checks whether such a value already exists. Alternatively, if there's the UNIQUE CONSTRAINT on that (those) column(s), database will do its job itself, i.e. raise an exception.
Another option is to literally loop through all rows in a block and compare the first row's value with all the others, then the second row's values with all of them, etc.
Or, you can use a Record Group (usually used for Lists of Values). Basically, you'd check whether value you entered exists in a record group. More info, along with a FMB file, on Craig's blog.
Or, you can use calculated items, as described enter link description here (FMB attached as well).
As you can see, quite a few ways to do that; explore each of them and pick the one you find the most useful / attractive / easy to implement.

Choosing from multiple query results to display in a single form

I have a form that submits parameters to a query, then opens the resulting record in another form. The problem is, whenever there is more than one record it automatically puts the first one into the from without any kind of option to choose the record I want. I have a macro set up on the search button on the first form that submits the parameters to the query and then displays it in the second form, I've tried to set up another macro in between the two, but I don't know if it's possible to set up the expression creator to check the number of rows resulting from a query. Is it possible to modify the query to create a prompt to choose which record I want? Or should I change something else?
This is the query:(automatically created by access)
SELECT CHILD.CHILD_L_NAME, CHILD.CHILD_F_NAME, CHILD.DOB, CHILD.GENDER, CHILD.DAYS_IN_CARE,
CHILD.HOURS_PER_DAY, CHILD.ENROLLMENT_DATE, CHILD.CHILD_ADDRESS, CHILD.CHILD_CITY,
CHILD.CHILD_ZIP, CHILD.CHILD_STATE, CHILD.CLASSROOM, CHILD.SNACK, CHILD.LAST_UPDATED, CHILD.CIN
FROM CHILD
WHERE (((CHILD.CHILD_L_NAME)=[Forms]![Search]![L_NAME]) AND
((CHILD.CHILD_F_NAME)=[Forms]![Search]![F_NAME])) OR
(((CHILD.CHILD_L_NAME)=[Forms]![Search]![L_NAME]) AND
((CHILD.DOB)=[Forms]![Search]![DOB])) OR
(((CHILD.DOB)=[Forms]![Search]![DOB])) OR
(((CHILD.CHILD_L_NAME)=[Forms]![Search]![L_NAME]));
If I understood well your problem and you use VBA it's quite easy to do.
You can create a reduced query based on the query you're creating with the button. This new query should include all and only the fields that allows you to discriminate beetwen the records to show in the 2nd form.
For instance it could include LastName, FirstName and classroom to select between children with same full name.
You can count the number of records of this 2nd query and if greater than 1 it means that you have more than one children to show.
So you can use this 2nd query to populate a combo-box or a listbox for selecting the record you really want to show.
When number of records is 1 you can simply skip the listbox population using an if statement on recordcount.
Next step is opening the form with the selected (or unique) record.
Bye

Database schema design options

I'm struggling to decide what database schema to use. One large table, or many small (though more difficult to manage).
I have 10 templates each with their own text fields. I am trying to store the text for the templates in a database and then when the web page is called I will show the correct text in the html template. Because a mixture of these templates are to be in a sequence of screens where you can navigate backwards or forwards, I need to be able to sequence them, I can only think of adding a page_number column. I also would like to re-order them and delete them as necessary using the page_number column.
I was planning to do all this in a web application without the need for a standard folder/web page structure, like a small CMS system.
option 1,
I can create one large table with many columns, lot's of which will be empty, over half with each row. Is this bad?
option 2,
I could create many tables using only the relevant template columns required.
The problem I see with this, is the headache of repopulating a column in each table when I delete a row, because I need to re-sequence a column that represents page numbers. Which I reduce if I use one large table.
I've thought of moving page numbers into another table called page_order but I cannot think of a way to maintain an effective relationship between the other tables if I make changes.
I'm yet to figure out how to re-sequence a column in a database when a row is deleted. Surely this is a common problem!?
Thanks for taking the time to help!
Have one table that contains one row per template. It might look like:
id (INT, auto-increment)
page_order (INT, unique key here, so pages cannot have the same number)
field1 (STRING, name of the text field)
value1 (STRING, contents of the text field)
field2
value2
Then you have to decide the maximum fields that any page can have (N) and keep adding field/value columns up to N.
The advantage of this is you have one table that isn't sparsely populated (as long as the templates have about the same number of fields, even if the names of those fields are different).
If you want to make an improvement to his (maybe not necessary for a small amount of data) you could change field to an INT id and connect it to a lookup table that contains (field_id, field_name).

ASP.NET DropDownList - How do I handle missing values?

I have a list of values in a SQL Table which are used to popluate a DropDownList, having a unique Integer as the value of each item and a String as the visible text (via SqlDataSource). There is also a third field in the database which is a flag to indicate whether the list item is active or not (inactive items are not shown in the DropDownList)
Selections made in the dropdown are stored in the database as their integer value (as part of a dataset making up the overall record), not the text value.
Over time, the items in the DropDownList may be removed by marking the items as inactive. However, there is still a need to open old records which may have had a now-inactive item as part of it's data...
My question is, what's the best way to ensure that the missing value included in the dropdown for the old record?
The two methods that spring to mind are to either:
Populate DropDownList with only the currently active items and, when loading a record, catch when the app tries to select a value that doesn't exist, go back to the db to see what it should be (the text value) and manually add it into the dropdown.
or...
Populate DropDownList with all list items (both active and inactive), load the record and then programatically remove all the inactive items (execpt for any that are now selected).
Neither of these seem particularly efficient, so I was wondering whether there is a best practice for this kind of thing?
there are so many optimum ways to do that sort of things, i am defining here a couple of them, use any of following if your Drop down list items count is less than 200 , lets say drop down list is of Products
1)
i) Load all Products records in drop down list and hide the inactive ones by setting visible=false
i) When you load a user record than look for its drop down list value if its visible than select it and enjoy, if its not visible than make it visible by setting its property visible=true and select it and also set its index or id in a flag to change its visibility(visible=false) again after your/users required operation performed.
2)
i) load only active Product records in drop down list ii) while loading a user record also load its product details(name, id, inactive_status) using Joins in sql.
iii) check in that user record if item is inactive then add its record in drop down list as you have all its details now with user details record else just select it.
IMPORTANT NOTE: if you drop down list has items in millions than use ADVANCE SEARCH techniques
The first thing I would do is question your business logic - should you be able to make an item inactive if it is being used as a foreign key in an active row elsewhere? If you make it inactive should it not remove all foreign keys as well?
To answer your question though I would go with a variation on the second idea but filtering in the page like that is probably slower than doing directly with SQL so I guess you have something like this at the moment to populate the dropdown
SELECT * FROM Table WHERE Active = 1
You should already have your record and the foreign key value so I would change it to this
SELECT * FROM Table WHERE Active = 1 OR PrimaryKey = [YourForeignKey]
Then you will always have the selected item but should also be fairly efficient.

Asp.Net Sql Auto-Increment for Wall Post

I have a table that contains three columns.
"UserId" type-nvarchar
"PostAuthorId" type-nvarchar
"Post" type-text
This table will contain "wall" posts like in facebook for each user's page. I am going to use a gridview on each user's page to display the posts. The issue is I want to display them with the latest(most current) post being first and the earliest post being last.
I have never used autoincrement before and I am not sure if that is the answer. If it is, I do not know how to use it. I thought about adding a date posted column and then ordering by date.
If I end up using the date column, I could also display the date on the post. Is there a way to convert the date to a readable format?
What is the best way of implementing this type of ordering?
If you use AutoIcrement the first record will start with 1 and each record will increment from there. (default setting)
If you want to sort them by newest first do an ORDER BY ID DESC
I would suggest making a column called wallPostID then setting that to AutoIncrement and also your Primary Key
Date Formating:
If you are displaying this data in a gridView
Go to Edit Columns on your grid view
CLick on the Date field under "Selected Fields" on the bottom left
Under "BoundField properties" on the right Go to Data -> DataFormatString
{0:d} will display as 1/1/2010
This site has more info in string formatting
http://msdn.microsoft.com/en-us/library/fht0f5be.aspx
A datetime column would definitely work for something like this. Assuming you are using MS-SQL, you can also attach a default value to the column using a built-in function like GETDATE(). That way, you only have to input the data that matters and the database will take care of adding the datetime column.
For converting a datetime to a readable format try:
DateTime postDate;
string value = postDate.ToShortDateString();
You should always use an ID field that auto increments. Can also be used as your PK
I would suggest the DateTime field rather than the autoincrement simply because it will not only serve as an effective Sort field, it also preserves information that you may well want to display. If you want the most recent first you'll sort using the Date and a "DESC" modifier:
Select ... Order By [Date] DESC;
When you retrieve the data, you can retrieve it as a DateTime and modify it using C#. You can use "ToShortDateString()" as suggested by mdresser if you just wish to show the date or ToString("...") if you wish to show the time as well. You can also use SQL to convert it into a string before retrieving it:
convert(Varchar(10), #mydatetime, 101)
If you look in MSDN you'll see the various conversion codes (101 is the code used above) that can be used to translate the date in various ways.
UPDATE: You may want to use an autoincrementing field for your application for reasons other than your expressed need to sort wall entries. They are easy to use - just mark the field as an Identity if using SQL Server (other DBs are similar). As far as using them in your program, just think of the field as an Int field that you never have to set.
Now, why would you use a auto-incrementing field? Perhaps the most straightforward reason is so that they give you have an easy way to identify each record. For example, if you permit people to alter or delete their wall entries, the auto-incrementing field is ideal as it gives you a way to easily look up each record (each record will be assigned its own, unique value). You might put an "x" next to the record like StackOverflow does and make it a call back with the UID (auto-increment) value. Note that you should set up your primary key on the UID field if you'll be doing this.
Now, if you find them useful for this reason then you could also sort by the UID. I would still store the date so that you can provide Date and Time feedback as to when an entry was made on the wall but this would no longer be your indexed or sorted field.

Resources