【问题标题】:Creating readable, unique key based on fields基于字段创建可读的唯一键
【发布时间】:2013-06-11 12:00:48
【问题描述】:

webguys 想要基于产品名称的唯一 url 如果更多产品具有相同的名称,请在名称后添加一个数字。

our.dom/red-sock

our.dom/red-sock-1

他们确实想要所有产品上的产品 ID 或其他数字,即

our.dom/red-sock-123481354

我将它存储在我称为 seourl 的字段中。

我在创建新产品时已经涵盖了它,触发器尝试添加 seourl,如果它已经存在,则增加数字,直到找到唯一值。

但是我现在必须给整张桌子新的感觉。 如果我只是

update tab set seourl=dbo.createurl(title)

肯定有碰撞,操作回滚。 有没有办法让语句提交有效的更新,而其余的保持不变?

或者我必须只做一个 RBAR,Row By Agonizing Row 循环操作吗?

【问题讨论】:

  • 您确实应该将数字存储在单独的字段中。现在您必须使用 PADINDEX 等来拆分数字和文本。
  • 不会。在这种情况下,我将不得不执行“其中 name+'-'+serial = @url 我永远不想拆分。创建新的 seourl 时,我尝试输入它。如果它已经存在,我尝试 name-1, name- 2,name-3 循环,直到找到一个未使用的。

标签: sql-server-2008 rbar


【解决方案1】:

根据您的需要进行调整:

select
*
from (values('aaa'), ('aaa-12'), ('aaa-'), ('bbb-3')) as src (x)
cross apply (
    select isnull(nullif(patindex('%-[0-9]%', x) - 1, -1), LEN(x))
) as p(idx)
cross apply (
    select
        SUBSTRING(x, 1, idx)
        , SUBSTRING(x, idx + 1, LEN(x) - idx)
) as t(t, xx)

【讨论】:

  • 你有没有运行查询?
  • 现在我做到了,但正如预期的那样,它分裂了,它不会从非唯一标题创建唯一键。反之亦然。
  • 您不想更新您的资源吗?如果是这样,据我所知,您可以在保留 - 的同时更改 - 之前的任何内容。不是吗?
  • 再次阅读问题。标题是seourl,数字仅用于分隔具有相同标题/大小的项目。编号不是唯一的。
  • 请把你想要的几个旧+新url的完整例子放上来。
【解决方案2】:

试试这个:

declare @tmp table (
    id int not null identity
    , name varchar(100) -- you need name to be indexed
    , urlSuffix int -- store the number (ot you'll have to use PATINDEX, etc. as previously shown)!
    , url as name + ISNULL('_' + cast(NULLIF(urlSuffix, 0) as varchar(100)), '')

    , unique (name, id) -- (trick) index on name
)

insert @tmp (name, urlSuffix)
select
    src.name
    , ISNULL(T.urlSuffix, -1) + ROW_NUMBER() OVER (PARTITION BY src.name ORDER BY (select 1))
from (values
    ('x')
    , ('y')
    , ('y')
    , ('y')
    , ('z')
    , ('z')
) as src (name)
left join (
    select
        name
        , MAX(T.urlSuffix) as urlSuffix
    from @tmp AS T
    GROUP BY name
) as T on (
    T.name = src.name
)

insert @tmp (name, urlSuffix)
select
    src.name
    , ISNULL(T.urlSuffix, -1) + ROW_NUMBER() OVER (PARTITION BY src.name ORDER BY (select 1))
from (values
    ('a')
    , ('b')
    , ('b')
    , ('b')
    , ('z')
    , ('z')
) as src (name)
left join (
    select
        name
        , MAX(T.urlSuffix) as urlSuffix
    from @tmp AS T
    GROUP BY name
) as T on (
    T.name = src.name
)

select
    name, url
from @tmp
order by url

解决你的问题应该在于使用ROW_NUMBER()

【讨论】:

    猜你喜欢
    • 2023-02-16
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 2019-10-19
    • 2012-12-24
    • 2015-10-06
    相关资源
    最近更新 更多