корпус переключателя coalesce mybatis

Я использую случай переключения coalesce mybatis в своем запросе, где я получаю ошибку, например

Ошибка запроса базы данных. Причина: java.sql.SQLException: ORA-01427: однострочный подзапрос возвращает более одной строки

это мой запрос

(select      
     (case when (coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null)
          then (select sysdate from dual) 
          else (coalesce(t1.col1,t2.col1, t1.col2, t1.col3)) 
     end  )  
from table1 t1
join table2 t2 
    on t1.id IN (t2.id))

заранее спасибо

2 ответа

Решение

Кажется, у вас много (), но в целом вы должны использовать оператор =, а не IN (t2.id) для соединения t2.id

select      
     case when coalesce(t1.col1,t2.col1, t1.col2, t1.col3) is null
          then  sysdate 
          else coalesce(t1.col1,t2.col1, t1.col2, t1.col3) 
     end    
from table1 t1
join table2 t2  on t1.id = t2.id

И, глядя на код, который вы разместили в образце, у вас есть выбор в качестве результата столбца, и этот выбор возвращает несколько строк (это вызывает ошибку). У вас также есть микс синтаксиса соединения, некоторые из которых основаны на явном синтаксисе соединения, некоторые на основе старого синтаксиса неявного соединения на основе имени таблицы, разделенной запятыми, и условия where. Вы должны попробовать использовать это

<select id="Trigger" parameterType="hashmap" resultType="java.util.HashMap" flushCache="true"> 

    SELECT 
        select case when coalesce(table1.col1, table2.col2,table1.col3, table1.col4) is null 
        then  sysdate 
        else coalesce(table1.col1, table2.col2,table1.col3, table1.col4) end as "ProgressDate"
        , table3.id as "ID" 
        from table1 
        INNER join table2 on table1.id = table2.id 
        INNER JOIN table3 ON table1.id = table3.id 
        INNER JOIN table4 table2.action = table4.action 
        WHERE table3.transaction = #{inputvaluepassed} 
        
</select> 

Запрос, который вы упомянули в вопросе, заменяет скалярный подзапрос, включенный в другой... основной запрос. Я отформатировал весь запрос (для удобства чтения), и он выглядит так:

SELECT 
  (
    select case when coalesce(table1.col1, table2.col2,table1.col3,
                                table1.col4) is null 
                then (select sysdate from dual) 
                else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
           end
    from table1 
    join table2 on table1.id = table2.id
  ) as "ProgressDate", 
  table3.id as "ID" 
FROM table3, table1, table2, table4 
WHERE table3.transaction = #{inputvaluepassed} 
  AND table1.id = table3.id 
  AND table2.id=table1.id and table2.action = table4.action

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

Вам нужно будет каким-то образом создать не более одной строки: возможно, путем агрегирования строк (используя GROUP BY), возможно, выбрав только одну строку из набора результатов (используя LIMIT); Есть и другие варианты. Если мы выберем ограничить количество строк до 1, ваш запрос может выглядеть так:

SELECT 
  (
    select case when coalesce(table1.col1, table2.col2,table1.col3,
                                table1.col4) is null 
                then (select sysdate from dual) 
                else coalesce(table1.col1, table2.col2,table1.col3, table1.col4)
           end
    from table1 
    join table2 on table1.id = table2.id
    limit 1 -- added this line
  ) as "ProgressDate", 
  table3.id as "ID" 
FROM table3, table1, table2, table4 
WHERE table3.transaction = #{inputvaluepassed} 
  AND table1.id = table3.id 
  AND table2.id=table1.id and table2.action = table4.action

Это всего лишь одно из возможных дешевых решений проблемы. Лучшее понимание того, как выбрать правильную строку из нескольких, может дать лучшее решение.

Другие вопросы по тегам