2013-06-11 4 views
3

Webguys хочет уникальных URL-адресов, основанных на наименовании продуктов Если у большего количества продуктов одинаковое имя, добавьте его после имени.Создание читабельного уникального ключа на основе полей

our.dom/красный носок

our.dom/красно-носок-1

Они не хотят идентификатор продукта или другой номер на все продукты, т.е.

our.dom/красно-носка-123481354

Я хранил это в поле, которое я называю seourl.

Я покрыл это, когда создаю новые продукты, триггер пытается добавить seourl, если он уже существует, увеличивайте число до тех пор, пока не будет найдено уникальное значение.

Но теперь я должен дать всему столу новые seourls. Если я просто

update tab set seourl=dbo.createurl(title) 

Я обязательно иметь collissions, и операция выполняется откат. Есть ли способ сделать заявление для фиксации обновлений, которые работают, и оставить без изменений?

Или я должен просто сделать RBAR, Row By Agonizing Row в цикле?

+0

Вы действительно должны иметь только магазин номер в отдельном поле. Теперь вам нужно будет использовать PADINDEX и т. Д., Чтобы разделить число и текстовое приложение. – Serge

+0

Не сделал бы. В этом случае мне придется делать «где имя +» - «+ serial = @url, я никогда не хочу разделиться. При создании нового seourl я пытаюсь ввести его. Если он уже существует, я пытаюсь использовать имя-1, 2, name-3 в цикле, пока я не найду неиспользованный. –

ответ

0

Адаптировать это к вашим потребностям:

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) 
+0

Извините, для меня это не имеет смысла ... –

+0

Вы даже запустили запрос? – Serge

+0

Теперь я сделал, но, как и ожидалось, он распадается, он не создайте уникальные ключи из неповторимых названий. –

0

Попробуйте это:

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()

Смежные вопросы