Custom sort in SQL Server

2020-08-03 04:32发布

问题:

I have a table where the results are sorted using an "ORDER" column, eg:

Doc_Id    Doc_Value   Doc_Order
1         aaa         1
12        xxx         5
2         bbb         12
3         ccc         24

My issue is to initially set up this order column as efficiently and reusably as possible.

My initial take was to set up a scalar function that could be used as a default value when a new entry is added to the table:

ALTER FUNCTION [dbo].[Documents_Initial_Order] 
( )
RETURNS int
AS
BEGIN

RETURN (SELECT ISNULL(MAX(DOC_ORDER),0) + 1 FROM dbo.Documents)

When a user wants to permute 2 documents, I can then easily switch the 2 orders.

It works nicely, but I now have a second table I need to set up the same way, and I am quite sure there is a nicer way to do it. Any idea?

回答1:

It sounds like you want an identity column that you can then override once it gets it initial value. One solution would be to have two columns, once call "InitialOrder", that is an auto-increment identity column, and then a second column called doc_order that initially is set to the same value as the InitialOrder field (perhaps even as part of the insert trigger or a stored procedure if you are doing inserts that way), but give the user the ability to edit that column.

It does require an extra few bytes per record, but solves your problem, and if its of any value at all, you would have both the inital document order and the user-reset order available.

Also, I am not sure if your doc_order needs to be unique or not, but if not, you can then sort return values by doc_order and InitialOrder to ensure a consistent return sequence.



回答2:

Based on your comment, I think you have a very workable solution. You could make it a little more userfriendly by specifying it as a default:

alter table documents
  add constraint constraint_name 
  default (dbo.documents_initial_order()) for doc_order

As an alternative, you could create an update trigger that copies the identity field to the doc_order field after an insert:

create trigger Doc_Trigger
on Documents
for insert
as
update d
set d.doc_order = d.doc_id 
from Documents d
inner join inserted i on i.doc_id = d.doc_id

Example defining doc_id as an identity column:

create table Documents (
    doc_id int identity primary key,
    doc_order int,
    doc_value ntext
)


回答3:

If there is no need to have any control over what that DOC_ORDER value might be, try using an identity column.