Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
Подскажите, плиз, что я делаю не так? :(
21 ноя 20, 13:30    [22236379]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
SerPaNik
fkthat
Я вообще что-то не вкурил. Если ключ по всем полям (допустим их два) и у меня есть запись {"foo", "bar"}, то нужно при добавлении записи {"foo", "bar"} ту запись {"foo", "bar"}, которая уже есть удалить, что ли? Смысл какой?

Смысл в изменении. Если есть записи:
brandarticlea_branda_article
MITSUBISHI125MITSUBISHIMD312639
BOSCH0 092 S40 260BOSCH0092S40260
BOSCH0 092 S40 260VARTA5704120633132
BOSCH0 242 129 515CHAMPIONOE201/T10
BOSCH125MITSUBISHIMD312639

И я хочу изменить значения в поле brand с MITSUBISHI на BOSCH, то возникнет ошибка. Ибо изменяемая первая строка будет после изменения идентична последней. В таком случае я хотел, чтобы первая строка была просто удалена ибо результат изменения уже есть в базе...
Как-то так.


Не пойму я ваших заморочек!
Почему просто перед апдейтом не попытаться удалить строку, которую пытаетесь переделать?
В вашем случае все равно её больше не будет в базе. Так?

Потом проверить, а есть-ли уже новая строка в таблице. Если есть, то ничего не делать, если нет, то добавить.
В вашем случае это
Удаляем
brandarticlea_branda_article
MITSUBISHI125MITSUBISHIMD312639


И смотрим наличие
brandarticlea_branda_article
BOSCH125MITSUBISHIMD312639


Сообщение было отредактировано: 21 ноя 20, 22:30
21 ноя 20, 22:29    [22236468]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
что-то типа
delete from [your_table]
where <old row conditions>

using [your_table] s
merge [your_table] t
on (s.xxx = t.xxx and .......)
when not matсhed
insert values (<new row values>) 
21 ноя 20, 22:46    [22236473]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
SQL2008, почему же заморочки? А если в результате переименования будет 4 одинаковых строки? Да и с Вашим подходом сначала удалить, а потом, если нет добавить как-то не шустро будет работать с таблицей в более четверти миллиарда строк... ИМХО.
Да и этот вопрос уже решен. Я уже заменил значения в 300 млн строк по двум полям. Я уже благодарил человека за неоценимо оказанную помощь.
Сейчас мне нужно сделать так, чтобы убрать различные символы, которые попали в названия (пробел, дефис, скобки и т.д.), но чтобы не возникало матюка по поводу дубликата ключа. Если в решении мы знали что и на что меняем, то здесь не совсем.
Я еще раз напомню, я специалист не по SQL. Именно поэтому решил обратиться в этом форуме к более знающим по этой теме людям...
21 ноя 20, 22:52    [22236474]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
SerPaNik
А если в результате переименования будет 4 одинаковых строки?

Как это так может получиться?
21 ноя 20, 22:55    [22236475]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
SerPaNik
Да и с Вашим подходом сначала удалить, а потом, если нет добавить как-то не шустро будет работать с таблицей в более четверти миллиарда строк... ИМХО.

А LEFT JOIN по 4 полям без WHERE прямо взлетит?
21 ноя 20, 23:01    [22236478]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
SQL2008, ниже может встретиться такая же строка...
О чем мы говорим, уже решено. Сам подход сначала удалять, а потом искать и сравнивать, ИМХО, не совсем правильный. Может ошибаюсь, может в SQL это принято. А так получается, что проходя каждую строку Вы ее сначала удаляете, а потом еще и ищете. Это разве не иррациональное решение?
А я спрашиваю по поводу уже другой задачи... Как удалить определенные символы, прекрасно удаляется (для моего случая) предложенный выше мне хорошим человеком вариант:
replace(translate(article,'{!''("@#-$%^&*)} ','################'),'#','')

Вот я и хочу использовать для решения своей уже второй задачи... Но не знаю как. :(
З.Ы. Да, по поводу нескольких строк я не прав. Соглашусь. Но суть не в этом. Я не хочу спорить, прекрасно осознавая, что не силен в SQL (иначе не обратился бы сюда).

Сообщение было отредактировано: 21 ноя 20, 23:07
21 ноя 20, 23:04    [22236479]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
fkthat
Member

Откуда:
Сообщений: 3894
SerPaNik
SQL2008, ниже может встретиться такая же строка...
О чем мы говорим, уже решено. Сам подход сначала удалять, а потом искать и сравнивать, ИМХО, не совсем правильный. Может ошибаюсь, может в SQL это принято. А так получается, что проходя каждую строку Вы ее сначала удаляете, а потом еще и ищете. Это разве не иррациональное решение?
А я спрашиваю по поводу уже другой задачи... Как удалить определенные символы, прекрасно удаляется (для моего случая) предложенный выше мне хорошим человеком вариант:
replace(translate(article,'{!''("@#-$%^&*)} ','################'),'#','')


Вот я и хочу использовать для решения своей уже второй задачи... Но не знаю как. :(
З.Ы. Да, по поводу нескольких строк я не прав. Соглашусь. Но суть не в этом. Я не хочу спорить, прекрасно осознавая, что не силен в SQL (иначе не обратился бы сюда).

Можно просто сначала удалить, а потом попытаться вставить - ключ просто не даст вставить, если такая же запись уже есть. Надо будет только ошибку нарушения constraint при этом обработать
21 ноя 20, 23:39    [22236482]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
fkthat
Можно просто сначала удалить, а потом попытаться вставить - ключ просто не даст вставить, если такая же запись уже есть. Надо будет только ошибку нарушения constraint при этом обработать

Я просто не знаю как здесь обрабатываются ошибки исключением, чтобы выполнение потом продолжилось.
Пробовал использовать try - catch, но у меня при ошибке попадает в исключение, выдается ошибка и процесс останавливается. В иных системах есть обработка исключений с возможностью продолжить код программы. Здесь я не знаю как это сделать и можно ли.
Я вообще думал, что опять можно применить Merge, мне эта конструкция нравится, но я не достаточно хорошо ее изучил. :)
22 ноя 20, 00:22    [22236488]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
SerPaNik
Сам подход сначала удалять, а потом искать и сравнивать, ИМХО, не совсем правильный.

Правильный тот метод который работает быстро и без ошибок.
Все остальное софистика.
Если ваш способ вас устраивает, то используйте его.

Сообщение было отредактировано: 22 ноя 20, 09:46
22 ноя 20, 09:49    [22236506]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4378
SerPaNik
Здесь я не знаю как это сделать и можно ли.

Закоммитить ошибочную транзакцию не получится никоим образом!
Поэтому постарайтесь избегать исключений.

SerPaNik
можно применить Merge, мне эта конструкция нравится, но я не достаточно хорошо ее изучил. :)

Я бы вам посоветовал потратить немного времени, изучить и использовать именно штатные функции SQL.
Если вы работает с большими объемами, то именно их, оптимизированных на уровне движка, следует использовать для улучшение быстродействия.
Прошу извинить за банальные истины.
22 ноя 20, 09:57    [22236508]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik
Подскажите, плиз, что я делаю не так? :(

1.
SerPaNik
using (values (replace(translate(brand,'a!''"(@#-$%^&*)} ','a###############'),'#',''))) s(brand) on 1 = 1
Выделенное это по-вашему что?
2. Запросом в CTE вы просто соединили таблицу саму с собой. Что дальше с этим собираетесь делать?
3. Очищать данные нужно ранее в CTE, а не в using
22 ноя 20, 11:57    [22236523]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
invm
Выделенное это по-вашему что?
2. Запросом в CTE вы просто соединили таблицу саму с собой. Что дальше с этим собираетесь делать?
3. Очищать данные нужно ранее в CTE, а не в using

Пока только создал запрос, чтобы во втором столбце было Нулл, если необходимо изменение.
select a.article, b.article as brand__new from
  PartnerAnalogs_test a left join PartnerAnalogs_test b on 
  a.article = replace(translate(a.article,'{!''"(@#-$%^&*)} ','################'),'#','')  and b.a_brand = a.a_brand 
  and b.brand = a.brand and b.a_article = a.a_article
Но правильным ли я путем иду, не знаю. :(
22 ноя 20, 14:54    [22236557]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik,

Вы лучше напишите какие столбцы нужно очистить от мусора и что потом удалять.
22 ноя 20, 16:07    [22236575]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
invm
SerPaNik,
Вы лучше напишите какие столбцы нужно очистить от мусора и что потом удалять.
Если вкратце, то нужно очистить столбец article, но с учетом того, чтобы не возникала ошибка дублей ключа (который по всем 4 полям). Ваше решение мне помогло для замены в столбце значения на значение, но тогда мы знали что и на что меняется, а здесь нужно удалить определенные символы (например, кавычки, подчеркивания, скобки, дефисы, пробел и т.д.) из всех строк в этом поле.
Сама конструкция
replace(translate(article,'{_!''"(@#-$%^&*)} ','#################'),'#','')
удаляет ненужные символы. Как связать Ваш вариант с этой конструкцией я пока не могу понять. Может и другое решение есть, но я тоже его не знаю.

З.Ы. В Вашем варианте я хотел использовать еще один параметр, например, @Pole, чтобы в нем имя поля хранилось
SET @Pole = 'article'
, но не нашел как подставить значение из этого параметра, например, в строку
b.article = a.article b.@Pole=a.@Pole не прокатывает. :) Но это так, я уже хотел сделать более универсальный код...

Сообщение было отредактировано: 22 ноя 20, 18:12
22 ноя 20, 18:15    [22236612]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik,

Так чего с дублями-то делать, если нашли?
22 ноя 20, 19:55    [22236666]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
invm
SerPaNik,
Так чего с дублями-то делать, если нашли?

Удалять. Как и в Вашем решении. Именно с дублями и проблема. Так бы можно было UpDate использовать. А ключ, напомню, по всем четырем полям. Исходные данные не изменились, а вот задача изменилась. :)
22 ноя 20, 20:15    [22236683]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik,

Как-то так:
with t as
(
 select
  b.article_new, a.article,
  row_number() over (partition by b.article_new, a.brand, a.a_article, a.a_brand order by (select 1)) as rn
 from
  PartnerAnalogs_test a cross apply
  (select replace(translate(a.article,'{!''"(@#-$%^&*)} ','################'),'#','')) b(article_new)
 where
  a.article <> b.article_new
)
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched and rn > 1
 delete;
22 ноя 20, 22:12    [22236772]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
invm
SerPaNik,

Как-то так:
with t as
(
 select
  b.article_new, a.article,
  row_number() over (partition by b.article_new, a.brand, a.a_article, a.a_brand order by (select 1)) as rn
 from
  PartnerAnalogs_test a cross apply
  (select replace(translate(a.article,'{!''"(@#-$%^&*)} ','################'),'#','')) b(article_new)
 where
  a.article <> b.article_new
)
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched and rn > 1
 delete;

Что-то не воспринимает второй when matched почему-то... я так понимаю
Ошибка:
Msg 156, Level 15, State 1, Line 18
Incorrect syntax near the keyword 'delete'.
22 ноя 20, 22:29    [22236789]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
court
Member

Откуда:
Сообщений: 2162
SerPaNik
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched and rn > 1
 delete;
а так ?
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched -- and rn > 1
 delete;
22 ноя 20, 23:50    [22236818]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik
Что-то не воспринимает второй when matched почему-то... я так понимаю
with t as
(
 select
  b.article_new, a.article,
  row_number() over (partition by b.article_new, a.brand, a.a_article, a.a_brand order by (select 1)) as rn
 from
  PartnerAnalogs_test a cross apply
  (select replace(translate(a.article,'{!''"(@#-$%^&*)} ','################'),'#','')) b(article_new)
 where
  a.article <> b.article_new
)
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched and t.rn > 1 then
 delete;
23 ноя 20, 09:26    [22236944]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
invm
SerPaNik
Что-то не воспринимает второй when matched почему-то... я так понимаю
with t as
(
 select
  b.article_new, a.article,
  row_number() over (partition by b.article_new, a.brand, a.a_article, a.a_brand order by (select 1)) as rn
 from
  PartnerAnalogs_test a cross apply
  (select replace(translate(a.article,'{!''"(@#-$%^&*)} ','################'),'#','')) b(article_new)
 where
  a.article <> b.article_new
)
merge into t
using (values (1)) s(dummy) on 1 = 1
when matched and t.rn = 1 then
 update
  set article = t.article_new
when matched and t.rn > 1 then
 delete;
Я мог и сам догадаться, что then пропущен был. :) Создал тестовый набор для проверки и запустил, но выдало ошибку:
Msg 2627, Level 14, State 1, Line 12
Violation of PRIMARY KEY constraint 'PK_PartnerAnalogs_test'. Cannot insert duplicate key in object 'dbo.PartnerAnalogs_test'. The duplicate key value is  ...

Я отдельно выполнил селект, чтобы получить таблицу Т. Почему-то для этого кода rn = 1 для всех трех записей. Матюк идет на этот артикул.
Есть еще поле a_article, которое потом тоже надо будет очистить от спецсимволов. Может поэтому так получается...

К сообщению приложен файл. Размер - 4Kb


Сообщение было отредактировано: 23 ноя 20, 13:44
23 ноя 20, 13:44    [22237161]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
SerPaNik
Member

Откуда:
Сообщений: 30
Обнаружил, что в таблице Т есть только одна запись с артикулом 8521468020, в таблице есть две записи, одна уже с таким артикулом, а вторая будет с ним после удаления знаков...

К сообщению приложен файл. Размер - 5Kb
23 ноя 20, 14:33    [22237215]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
invm
Member

Откуда: Москва
Сообщений: 9494
SerPaNik,

Думаете интересно гадать что за запрос и на каких данных вы выполняете?
Давайте скрипт создания таблицы и заполнения ее данными. И выполняемый запрос.
23 ноя 20, 16:09    [22237302]     Ответить | Цитировать Сообщить модератору
 Re: Составной ключ по всем полям. При Update, если будет дубль, то удалить исходную строку  [new]
fkthat
Member

Откуда:
Сообщений: 3894
SQL2008
SerPaNik
Здесь я не знаю как это сделать и можно ли.

Закоммитить ошибочную транзакцию не получится никоим образом!
Поэтому постарайтесь избегать исключений.

Можно использовать IGNORE_DUP_KEY - тогда попытка вставки с нарушением ключа будет просто проигнорирована.
23 ноя 20, 17:07    [22237348]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить