Оператор обновления с помощью concat

#oracle #oracle11g #concatenation

#Oracle #oracle11g #конкатенация

Вопрос:

Я пытаюсь создать запрос на обновление, который объединяет 3 поля из таблицы в 1 поле в другой таблице

Первая таблица с именем table1

 ID       DESC
12       left:Middle:Right
 

Вторая таблица Таблица 2

 ID  FLD1    FLD2    FLD3
12  left    Middle  Right
 

Попытка обновить все поле desc в Table1 значениями table2, где table1.id = table2.id

 update table1 A SET A.DESC = (SELECT CONCAT(B.fld1, ':', B.fld2, ':', B.fld3) 
                              from table2 B 
                              where A.ID = B.ID) 
Where A.id = 12;
 

Тем не менее, я получаю сообщение об ошибке из приведенного выше запроса с сообщением «недопустимое количество аргументов» Есть идеи, что я делаю не так? или как я могу сделать это лучше?

Ответ №1:

CONCAT принимает только два параметра, что означает, что вы должны использовать вложенные CONCAT s.

Однако вы предпочли бы использовать оператор double pipe || , который не имеет такого ограничения. Итак:

 update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3   --> this
                              from table2 B 
                              where A.ID = B.ID) 
Where A.id = 12;
 

Чтобы обновить все совпадающие строки, вы могли

 update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3   --> this
                              from table2 B 
                              where A.ID = B.ID) 
Where exists (select null
              from table2 b
              where a.id = b.id);
 

или MERGE :

 merge into table1 a
  using table2 b
  on (b.id = a.id)
  when matched then update set a.desc = b.fld1 ||':'|| b.fld2 ||':'|| b.fld3;
 

Поскольку у вас есть дубликаты, DISTINCT может помочь, например

 update table1 a set 
  a.desc = (select distinct b.fld1 ||':'|| b.fld2 ||':'|| b.fld3
            from table2 b
            where a.id = b.id
           )
where exists ...
 

Если нет, то вам нужно будет посмотреть, что делать с этими дубликатами. Если возможно, используйте еще один столбец (столбцы) в WHERE предложении. Или, если вам действительно все равно, какая объединенная комбинация подходит, используйте агрегатные функции, такие как MIN или MAX , например

 update table1 a set 
  a.desc = (select max(b.fld1 ||':'|| b.fld2 ||':'|| b.fld3)
            from table2 b
            where a.id = b.id
           )
where exists ...
 

Комментарии:

1. хорошо, это устранило проблему с обновлением concat. однако, как я могу расширить это, чтобы обновить всю таблицу. вместо A.id = 12 … Я пытался A.id = B.id ; но это выдает ошибку. есть идеи, как сделать так, чтобы обновить все?

2. Я добавил еще несколько примеров; посмотрите, пожалуйста.

3. из обновления я получил следующее: «однорядный подзапрос возвращает более одной строки» … из слияния я получил следующую ошибку «не удается получить стабильный набор строк в исходных таблицах»…

4. Это потому, что существуют дубликаты; идентификаторы не являются уникальными . Попробуйте добавить DISTINCT, может быть, это поможет. Добавил и эти примеры.