【问题标题】:Custom sort in SQL ServerSQL Server 中的自定义排序
【发布时间】:2009-05-11 13:40:33
【问题描述】:

我有一个表格,其中使用“ORDER”列对结果进行排序,例如:

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

我的问题是最初设置此订单列时尽可能高效且可重用。

我最初的想法是设置一个标量函数,当向表中添加新条目时可以将其用作默认值:

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

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

当用户想要置换 2 个文档时,我可以轻松地切换 2 个顺序。

它工作得很好,但我现在有第二张桌子我需要以相同的方式设置,我很确定有更好的方法来做到这一点。有什么想法吗?

【问题讨论】:

    标签: sql sql-server user-defined-functions


    【解决方案1】:

    根据您的评论,我认为您有一个非常可行的解决方案。您可以通过将其指定为默认值来使其更加用户友好:

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

    作为替代方案,您可以创建一个更新触发器,在插入后将标识字段复制到 doc_order 字段:

    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
    

    将 doc_id 定义为标识列的示例:

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

    【讨论】:

    • 好点,但我需要用户能够调整顺序(排列 2 个文档)。如果我使用身份,这样做会很痛苦。
    • 这里的 doc_order 不是 IDENTITY 列
    • Andomar 的解决方案是一个很好的解决方案。插入触发器会将 doc_order 初始化为 doc_id 值(doc_id 是标识列)。稍后,可以根据需要更新 doc_order。
    【解决方案2】:

    听起来你想要一个标识列,一旦它获得初始值,你就可以覆盖它。一种解决方案是有两列,一次调用“InitialOrder”,这是一个自动增量标识列,然后是第二列称为 doc_order,最初设置为与 InitialOrder 字段相同的值(甚至可能作为如果您以这种方式进行插入,则插入触发器或存储过程),但让用户能够编辑该列。

    它确实需要每条记录额外的几个字节,但可以解决您的问题,如果它有任何价值,您将同时获得初始文档顺序和用户重置顺序。

    另外,我不确定您的 doc_order 是否需要唯一,但如果不需要,您可以按 doc_order 和 InitialOrder 对返回值进行排序,以确保返回顺序一致。

    【讨论】:

    • (我最后用的方案差不多就是那个)
    【解决方案3】:

    如果不需要对 DOC_ORDER 值进行任何控制,请尝试使用标识列。

    【讨论】:

    • 好点,但我需要用户能够调整顺序(排列 2 个文档)。如果我使用身份,这样做会很痛苦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2019-12-06
    • 2010-12-24
    • 2014-04-29
    • 1970-01-01
    相关资源
    最近更新 更多