不要对SQL Server中函数的结果集进行排序

问题描述 投票:0回答:1

我在 SQL Server 中有一个名为

source
的表,其中
source_id
作为主键,
source_name

这是我的函数,它生成了错误的结果。

这是使用以下函数的插入语句:

insert into ppm_schema.dim_source (source_id, source_name)
values (ppm_schema.generatesourceid('clinical'), 'clinical');

insert into ppm_schema.dim_source (source_id, source_name)
values (ppm_schema.generatesourceid('qivia'), 'qivia');

insert into ppm_schema.dim_source (source_id, source_name)
values (ppm_schema.generatesourceid('ab'), 'ab');

insert into ppm_schema.dim_source (source_id, source_name)
values (ppm_schema.generatesourceid('b'), 'b');
create function ppm_schema.generatesourceid
    (@SourceName varchar(50))
returns varchar(50)
as
begin
    declare @count varchar(50);
    declare @ide varchar(50);
    declare @maxid varchar(50);
    declare @prefix varchar(20);
    declare @id varchar(20);

    with cte as
    (
        select top 1 
            count(*) + 1 as number
        from 
            ppm_schema.dim_source 
    )
    select @count = number from cte;

    select @prefix = left(@SourceName, 3);

    if len(@SourceName) >= 3
    begin
        select @ide = @prefix + right('000' + cast(@count as varchar(3)), 3)
    end
    else if len(@SourceName) >= 2
    begin
        select @ide = @prefix + 'x'+ right('000' + cast(@count as varchar(3)), 3)
    end
    else if len(@SourceName) >= 1
        select @ide = @prefix + 'xx' + right('000' + cast(@count as varchar(3)), 3)

    return @ide
end

该函数的结果:

来源_id 来源名称
abx003 ab
bxx004 b
cli001 临床
qiv002 奇维亚

我需要的结果是

来源_id 来源名称
cli001 临床
qiv001 奇维亚
abx003 ab
bxx004 b
sql-server function sorting auto-generate
1个回答
0
投票

评论中的担忧完全正确。

也就是说,在 select 语句中使用 order by 会将它们按照您列出的顺序排列。因为您的前缀始终为 3 个字符,所以您可以将右侧的所有内容拉到 3 以使用数字 (cli001) 进行排序。

select
    *
from ppm_schema.dim_source
order by RIGHT(source_id, LEN(source_id)-3)

结果

来源_id 来源名称
cli001 临床
qiv002 奇维亚
abx003 ab
bxx004 b

如果这就是您的函数所做的一切,您可以将其放入单个查询中。

create function ppm_schema.generatesourceid
    (@SourceName varchar(50))
returns varchar(50)
as
begin
    return (SELECT 
            LEFT(LEFT(@SourceName, 3) + 'xxx', 3) 
                + RIGHT('000' + CAST(COUNT(*) + 1 AS varchar(3)), 3)
        FROM dim_source)
end

超出了问题的范围:我所看到的生成的ID倾向于使用定序器、定序器表,或者至少是一个锁,然后直接插入。

© www.soinside.com 2019 - 2024. All rights reserved.