У меня есть ошибка ORA-01489: результат конкатенации строк слишком длинный при выполнении этого запроса в Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production, PL / SQL Release 11.2.0.4. 0 - Производство, CORE 11.2.0.4.0 Производство, TNS для Linux: Версия 11.2.0.4.0 - Производство, NLSRTL Версия 11.2.0.4.0 - Производство:
SELECT "USER_PRIMARY_UNIT","LOGIN","FIRST_NAME","LAST_NAME","UNIT_ROLE"
FROM (
SELECT user_primary_unit,login, first_name, last_name,
LTRIM(MAX(SYS_CONNECT_BY_PATH(rights,' / '))
KEEP (DENSE_RANK LAST ORDER BY curr),' / ') AS UNIT_ROLE
FROM
(SELECT login,
first_name,
last_name,
user_primary_unit,
rights,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) AS curr,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) -1 AS prev
FROM (select member0_.login, member0_.first_name first_name, unit2.unit_name user_primary_unit, member0_.last_name last_name,
CONCAT(CONCAT(unit.unit_name, ' - '), role3_.role_name) rights
from
IOT_DEVICES.t_member member0_
inner join IOT_DEVICES.t_user member0_1_ on member0_.member_id=member0_1_.user_id
inner join IOT_DEVICES.t_playable_role playedrole1_ on member0_.member_id=playedrole1_.user_id
inner join IOT_DEVICES.t_unit_role unitrole2_ on playedrole1_.unit_role_id=unitrole2_.unit_role_id
inner join IOT_DEVICES.t_role role3_ on unitrole2_.role_id=role3_.role_id
inner join IOT_DEVICES.t_unit unit on unitrole2_.unit_id=unit.unit_id
inner join IOT_DEVICES.t_unit unit2 on unit2.unit_id=member0_1_.primary_unit_id
where current_date between playedrole1_.start_date and playedrole1_.end_date
order by unit.unit_name
))
GROUP BY login, first_name, last_name, user_primary_unit
CONNECT BY prev = PRIOR curr AND login = PRIOR login
START WITH curr = 1
)
ORDER BY user_PRIMARY_UNIT, FIRST_NAME, LAST_NAME;
Проблема с этим запросом связана с использованием оператора CONCAT (||). Оператор Concat возвращает char1, объединенный с char2. Возвращаемая строка имеет тот же набор символов, что и char1. Итак, здесь оператор concat пытается вернуть varchar2, который имеет ограничение в 4000 символов и превышает его. Эта проблема также может возникнуть, когда мы пытаемся СВЯЗАТЬ VARCHAR2 с CLOB. Итак, здесь я хочу просто преобразовать его первую строку в CLOB и избежать этой ошибки. После преобразования первой строки в CLOB оператор CONCAT вернет строку типа CLOB.
Поэтому я добавляю TO_CLOB для преобразования типов, но затем возникает следующая ошибка:
ORA-00932: несогласованные типы данных: ожидалось - получено CLOB
SELECT "USER_PRIMARY_UNIT","LOGIN","FIRST_NAME","LAST_NAME","UNIT_ROLE"
FROM (
SELECT user_primary_unit,login, first_name, last_name,
LTRIM(MAX(SYS_CONNECT_BY_PATH(rights,' / '))
KEEP (DENSE_RANK LAST ORDER BY curr),' / ') AS UNIT_ROLE
FROM
(SELECT login,
first_name,
last_name,
user_primary_unit,
rights,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) AS curr,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) -1 AS prev
FROM (select member0_.login, member0_.first_name first_name, unit2.unit_name user_primary_unit, member0_.last_name last_name,
TO_CLOB(CONCAT(CONCAT(unit.unit_name, ' - '), role3_.role_name)) rights
from
IOT_DEVICES.t_member member0_
inner join IOT_DEVICES.t_user member0_1_ on member0_.member_id=member0_1_.user_id
inner join IOT_DEVICES.t_playable_role playedrole1_ on member0_.member_id=playedrole1_.user_id
inner join IOT_DEVICES.t_unit_role unitrole2_ on playedrole1_.unit_role_id=unitrole2_.unit_role_id
inner join IOT_DEVICES.t_role role3_ on unitrole2_.role_id=role3_.role_id
inner join IOT_DEVICES.t_unit unit on unitrole2_.unit_id=unit.unit_id
inner join IOT_DEVICES.t_unit unit2 on unit2.unit_id=member0_1_.primary_unit_id
where current_date between playedrole1_.start_date and playedrole1_.end_date
order by unit.unit_name
))
GROUP BY login, first_name, last_name, user_primary_unit
CONNECT BY prev = PRIOR curr AND login = PRIOR login
START WITH curr = 1
)
ORDER BY user_PRIMARY_UNIT, FIRST_NAME, LAST_NAME;
Я также попытался использовать определенную здесь иерархию пакетов, но затем я получил ORA- 00932: несовместимые типы данных: ожидалось - получил CLOB https://community.oracle.com/thread/965324?Start=0&tstart=0
SELECT "USER_PRIMARY_UNIT","LOGIN","FIRST_NAME","LAST_NAME","UNIT_ROLE"
FROM (
SELECT user_primary_unit,login, first_name, last_name,
LTRIM(MAX(hierarchy.branch(level,rights,' / '))
KEEP (DENSE_RANK LAST ORDER BY curr),' / ') AS UNIT_ROLE
FROM
(SELECT login,
first_name,
last_name,
user_primary_unit,
rights,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) AS curr,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) -1 AS prev
FROM (select member0_.login, member0_.first_name first_name, unit2.unit_name user_primary_unit, member0_.last_name last_name,
TO_CLOB(CONCAT(CONCAT(unit.unit_name, ' - '), role3_.role_name)) rights
from
IOT_DEVICES.t_member member0_
inner join IOT_DEVICES.t_user member0_1_ on member0_.member_id=member0_1_.user_id
inner join IOT_DEVICES.t_playable_role playedrole1_ on member0_.member_id=playedrole1_.user_id
inner join IOT_DEVICES.t_unit_role unitrole2_ on playedrole1_.unit_role_id=unitrole2_.unit_role_id
inner join IOT_DEVICES.t_role role3_ on unitrole2_.role_id=role3_.role_id
inner join IOT_DEVICES.t_unit unit on unitrole2_.unit_id=unit.unit_id
inner join IOT_DEVICES.t_unit unit2 on unit2.unit_id=member0_1_.primary_unit_id
where current_date between playedrole1_.start_date and playedrole1_.end_date
order by unit.unit_name
))
GROUP BY login, first_name, last_name, user_primary_unit
CONNECT BY prev = PRIOR curr AND login = PRIOR login
START WITH curr = 1
)
ORDER BY user_PRIMARY_UNIT, FIRST_NAME, LAST_NAME;
Затем я тоже попробовал с sys.stragg, но получил ORA-00978: вложенная групповая функция без GROUP BY.
SELECT "USER_PRIMARY_UNIT","LOGIN","FIRST_NAME","LAST_NAME","UNIT_ROLE"
FROM (
SELECT user_primary_unit,login, first_name, last_name,
LTRIM(MAX(SYS_CONNECT_BY_PATH(rights,' / '))
KEEP (DENSE_RANK LAST ORDER BY curr),' / ') AS UNIT_ROLE
FROM
(SELECT login,
first_name,
last_name,
user_primary_unit,
rights,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) AS curr,
ROW_NUMBER() OVER (PARTITION BY login ORDER BY rights) -1 AS prev
FROM (select member0_.login, member0_.first_name first_name, unit2.unit_name user_primary_unit, member0_.last_name last_name,
sys.stragg(sys.stragg(unit.unit_name || ' - ' || role3_.role_name)) rights
from
IOT_DEVICES.t_member member0_
inner join IOT_DEVICES.t_user member0_1_ on member0_.member_id=member0_1_.user_id
inner join IOT_DEVICES.t_playable_role playedrole1_ on member0_.member_id=playedrole1_.user_id
inner join IOT_DEVICES.t_unit_role unitrole2_ on playedrole1_.unit_role_id=unitrole2_.unit_role_id
inner join IOT_DEVICES.t_role role3_ on unitrole2_.role_id=role3_.role_id
inner join IOT_DEVICES.t_unit unit on unitrole2_.unit_id=unit.unit_id
inner join IOT_DEVICES.t_unit unit2 on unit2.unit_id=member0_1_.primary_unit_id
where current_date between playedrole1_.start_date and playedrole1_.end_date
order by unit.unit_name
))
GROUP BY login, first_name, last_name, user_primary_unit
CONNECT BY prev = PRIOR curr AND login = PRIOR login
START WITH curr = 1
)
ORDER BY user_PRIMARY_UNIT, FIRST_NAME, LAST_NAME;