Aggregation of chain - ORA-01489
Hi, I get ORA-01489 for the following query. Basically, I'm performing aggregation of chain:SELECT LTRIM (REPLACE (sys_connect_by_path (expression, ':'), ': ',' '), ',')
IN clob_variable
FROM (SELECT * FROM tb_metadata_detail WHERE performance_metadata_id = 2) TDG
WHERE connect_by_isleaf = 1
CONNECT BY performance_metadata_detail_id = BEFORE
performance_metadata_detail_id + 1
START WITH performance_metadata_detail_id = 1;
I heard to_clob can help. but where to put it?
still get ora-01489
try another approach:
select xmlagg (
xmlelement (e, expression || ',') order by performance_metadata_detail_id
).extract ('//text()').getclobval ()
from tb_metadata_detail
where performance_metadata_id = 2
Tags: Database
Similar Questions
-
"ORA - 01489:result of concatenation of string is too long" (the chain is small)
Hello
I am using the listagg as follows function but get ORA-01489: result of concatenating string is too long.
SELECT LOCATIONID, LISTAGG (TO_CHAR (WHICH |)) ',' || (POSITIONY), ',') ADR WITHIN GROUP (ORDER BY SEQUENCENUMBER)
OF POSITIONPOINTS
GROUP BY LOCATIONID
AFTER HAVING COUNT (SEQUENCENUMBER) = 20;
When I try to run this in Oracle Sql Developer, he shows the lines first in 1550, then reports the error ORA-01489. In total 2612 lines must be returned, all values in ADR having a length of approximately 440 characters. An example of one of the lines that developer Sql is back is:
22372682 410434.801,551142.885,410434.784,551142.875,410439.801,551141.922,410439.991,551141.795,410439.293,551138.303,410438.531,551137.668,410429.768,551134.302,410427.228,551133.159,410426.212,551132.143,410425.196,551129.667,410421.957,551114.3,410414.972,551081.28,410413.639,551076.136,410412.94,551073.66,410412.94,551072.326,410413.639,551071.628,410415.798,551070.612,410416.369,551069.469,410416.877,551068.834,410433.23,551061.795
There are a few LocationIDs in table PositionPoints that have more than 20 entries (max is 254), and for these lines, I want the concatenated string more than the maximum of 4000 characters. However, where count (sequencenumber) = 20, the length of the concatenated string would be less than 500. Oracle running concatenations even for places that I've excluded with my HAVING clause and an error on these?
I tried to run the query at the time Oracle Sql Developer and SQL Plus.
Would be grateful if someone could shed some light on this issue.
Thank youRonnie m says:
Oracle running concatenations even for places that I've excluded with my HAVING clause and an error on these?Yes, that's the explanation.
HAVING is not WHERE it is applied after the grouping is performed. -
Get ORA-01489: with tabular
Hello
I have a tabular presentation that has a couple of apex_item.select_list_from_lov in the source query, for example
SELECT Apex_item.hidden (1
NULL
)
|| apex_item.select_list_from_lov (4
NULL
, "LOV_POLICY".
, "style =" width: 170px "'"
|| ')"'
'NO '.
NULL
NULL
, "f04_".
|| LPAD (9900
+ LEVEL
4
, '0'
)
NULL
)
|| apex_item. Hidden (3
NULL
) policy_name
.....
I now get an ORA-01489: result of concatenating string is too long error. It was working fine but the LOV which depends on one of the points went to a hundred documents, or so I'm half guess that the apex_item function creates a static string more than 4,000 characters, and thus the error.
This has large implications for our application as long as there are several tabular forms that display data in this way (I assume that apex_item.select_list_from_query is no different) and it is likely that these selection lists will grow over time.
Someone has encountered this problem themselves and found a solution? We have an Ajax solution but this will involve rewritten considerable and we have little time.
Any suggestions greatly appreciated...Hello
Do something like the following:
1. create a LOV to SELECT NULL, NULL Ruy FROM DUAL and use this instead LOV_POLICY
2. on your APEX_ITEM, add in the parameter which allows additional values
3. under your existing area, create a new PL/SQL area that generates the actual values using something like:DECLARE vSEP VARCHAR2(1); BEGIN vSEP := ''; htp.p('<script type="text/javascript">'); htp.p('var sMaster = new Array('); FOR c IN (SELECT DNAME d, DEPTNO r FROM DEPT ORDER BY UPPER(DNAME)) LOOP htp.p(vSEP || 'new Array (' || c.r|| ',"' || c.d|| '")'); vSEP := ','; END LOOP; htp.p(')'); htp.p('</script>'); END;
4. create another region below which set it on have No model and the source of the value:
<script type="text/javascript"> function updateList(sChild) { var o; var sChildValue = sChild.value; sChild.options.length = 0; o = new Option('-Select-', ''); sChild.options.add(o); var k; for (k = 0; k < sMaster.length; k++) { o = new Option(sMaster[k][1], sMaster[k][0]); sChild.options.add(o); } sChild.value = sChildValue; if (sChild.selectedIndex == -1) { sChild.selectedIndex = 0; } } function updateLists() { var lists = document.getElementsByName("f04"); var k; var x; if (lists) { for (k = 0; k < lists.length; k++) { updateList(lists[k]); } } } updateLists(); </script>
Now, when the page loads, each selection list will show a null value and the actual value. In this report, will be generated a javascript array that contains the appropriate values for the lists. Following that will be the JavaScript that traverses the playlists selection and fills them with the content of the table.
The benefits of doing it this way are double - you work around issues with lengths of chain and the page will actually load a lot faster.
-
ORA-01489: result of concatenating string is too long
Hola a todos, Necesito ayuda, estoy creando UN a plano cual tiene el archivo a linea of 11500 characters largo, pero al building the question me envia el error (ORA-01489) descrito, alguien sabe como avoid than aparezca este error, the idea are what run script desde este an archivo .bat o .sh
the request are the following
set pagesize 0set linesize 11508
Go head
coil prueba_comex.txt;
Select rpad (nvl (A.SEGMENT1,' '), 100).RPAD(A.ORGANIZATION_ID,100) |
RPAD (' ', 2) |
RPAD (' ', 2) |
RPAD (' ', 18).
RPAD (' ', 47).
RPAD (nvl (A.PRIMARY_UOM_CODE,' '), 4) |
RPAD (' ', 10).
RPAD ('99999999', 8).
RPAD (' ', 8).
RPAD (' ', 8).
RPAD ('0', 47).
RPAD ('0', 47).
RPAD (' ', 30).
RPAD (' ', 14).
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 47).
RPAD (' ', 18).
RPAD (' ', 18).
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 47).
RPAD (' ', 47).
RPAD (' ', 47).
RPAD (' ', 47).
RPAD (' ', 47).
RPAD (nvl (A.DESCRIPTION,' '), 250).
RPAD (' ', 14).
RPAD (' ', 1) |
RPAD (NVL (A.WEIGHT_UOM_CODE, 'KG'), 4) |
RPAD ('KG', 4) |
RPAD (' ', 4) |
RPAD (' ', 4) |
RPAD (' ', 47).
RPAD (' ', 47).
RPAD (' ', 20).
RPAD (' ', 47).
RPAD (' ', 4) |
RPAD (' ', 1) |
RPAD (' ', 200).
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD ('P', 20).
RPAD('N',1) |
RPAD (' ', 1) |
RPAD (' ', 80).
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 1) |
RPAD (' ', 4) |
RPAD (' ', 240).
RPAD (' ', 240).
RPAD (' ', 240).
RPAD (NVL (B.LONG_DESCRIPTION, A.Description), 4000)
tables...
If you run SQL * Plus in your scripts, then you need to set:
long value 32000 longc 200
-
log in - help sql: error ORA-01489: string concatena result
Here's a sql query and I am cooking a decoding, but since there are several columns invloved when I try to run it I get the following error:
ORA-01489: result of concatenating string is too long
Any kind of help is appreciated, I need to get it going or I'm dead :(
Concerning
Rahul
SQL:
Select sys_connect_by_path(c.decode_prep,'-') decode_prep
from (select "DECODE (BIAPPS_11.'|)") substr (b.all_cols, InStr(b.all_cols,',',1,a.RN) + 1, InStr(b.all_cols,',',1,a.RN+1)-InStr(b.all_cols,',',1,a.RN)-1). «, » ||' RAHULKALRA.' | substr (b.all_cols, InStr(b.all_cols,',',1,a.RN) + 1, InStr(b.all_cols,',',1,a.RN+1)-InStr(b.all_cols,',',1,a.RN)-1) |', "1", "0")' decode_prep, rownum curr, prev rownum-1
from (select rownum rn
Double connect rownum < =.
(select (length('ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM ,CSCN_HIER1_CODE,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT ,AUX4_CHANGED_ON_DT,SRC_EFF_FROM_DT,SRC_EFF_TO_DT,EFFECTIVE_FROM_DT,EFFECTIVE_TO_DT,DELETE_FLG,CURRENT_FLG,W_INSERT_DT,W_UPDATE_DT,DATASOURCE_NUM_ID,ETL_PROC_WID,INTEGRATION_ID,SET_ID,TENANT_ID,X_CUSTOM')
- length(replace('ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM ,CSCN_HIER1_CODE,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT ,AUX4_CHANGED_ON_DT,SRC_EFF_FROM_DT,SRC_EFF_TO_DT,EFFECTIVE_FROM_DT,EFFECTIVE_TO_DT,DELETE_FLG,CURRENT_FLG,W_INSERT_DT,W_UPDATE_DT,DATASOURCE_NUM_ID,ETL_PROC_WID,INTEGRATION_ID,SET_ID,TENANT_ID,X_CUSTOM',',')))+1 total_cols
the double)), (select ',' |') ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM,CSCN_HIER1_CODE ,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT,AUX4_CHANGED_ON_DT SRC_EFF_FROM_DT , SRC_EFF_TO_DT, EFFECTIVE_FROM_DT, EFFECTIVE_TO_DT, DELETE_FLG, CURRENT_FLG, W_INSERT_DT, W_UPDATE_DT, DATASOURCE_NUM_ID, ETL_PROC_WID, INTEGRATION_ID, SET_ID, TENANT_ID, X_CUSTOM' | (',' double all_cols) b) c
Start by curr = 1
Connect prior curr = prev
length (sys_connect_by_path(c.decode_prep,'-')) desc order
---------------------------------------------------------------------------------------------
same as above sql only the difference is here I'm pulling the first record in the result set that top query returns:
Select ltrim (replace(decode_prep,'-','||'),'| ') decode_prep
of (sys_connect_by_path(c.decode_prep,'-') select decode_prep)
from (select "DECODE (BIAPPS_11.'|)") substr (b.all_cols, InStr(b.all_cols,',',1,a.RN) + 1, InStr(b.all_cols,',',1,a.RN+1)-InStr(b.all_cols,',',1,a.RN)-1). «, » ||' RAHULKALRA.' | substr (b.all_cols, InStr(b.all_cols,',',1,a.RN) + 1, InStr(b.all_cols,',',1,a.RN+1)-InStr(b.all_cols,',',1,a.RN)-1) |', "1", "0")' decode_prep, rownum curr, prev rownum-1
from (select rownum rn
Double connect rownum < =.
(select (length('ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM ,CSCN_HIER1_CODE,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT ,AUX4_CHANGED_ON_DT,SRC_EFF_FROM_DT,SRC_EFF_TO_DT,EFFECTIVE_FROM_DT,EFFECTIVE_TO_DT,DELETE_FLG,CURRENT_FLG,W_INSERT_DT,W_UPDATE_DT,DATASOURCE_NUM_ID,ETL_PROC_WID,INTEGRATION_ID,SET_ID,TENANT_ID,X_CUSTOM')
- length(replace('ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM ,CSCN_HIER1_CODE,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT ,AUX4_CHANGED_ON_DT,SRC_EFF_FROM_DT,SRC_EFF_TO_DT,EFFECTIVE_FROM_DT,EFFECTIVE_TO_DT,DELETE_FLG,CURRENT_FLG,W_INSERT_DT,W_UPDATE_DT,DATASOURCE_NUM_ID,ETL_PROC_WID,INTEGRATION_ID,SET_ID,TENANT_ID,X_CUSTOM',',')))+1 total_cols
the double)), (select ',' |') ROW_WID,COST_CENTER_NUM,COST_CENTER_NAME,COST_CENTER_DESC,CONTROL_AREA_NUM,CONTROL_AREA_NAME,CATEGORY_CODE,CATEGORY_NAME,CATEGORY_DESC,MANAGER_NAME,CURRENCY_CODE,CURRENCY_NAME,LANGUAGE_CODE,LANGUAGE_NAME,ST_ADDRESS1,ST_ADDRESS2,POST_OFFICE_BOX,CITY_NAME,STATE_CODE,STATE_NAME,REGION_CODE,REGION_NAME,COUNTRY_CODE,COUNTRY_NAME,POSTAL_CODE,PHONE_NUM,FAX_NUM,CSCN_HIER1_CODE ,CSCN_HIER1_NAME,CSCN_HIER2_CODE,CSCN_HIER2_NAME,CSCN_HIER3_CODE,CSCN_HIER3_NAME,CSCN_HIER4_CODE,CSCN_HIER4_NAME,CSCN_HIER5_CODE,CSCN_HIER5_NAME,CSCN_HIER6_CODE,CSCN_HIER6_NAME,ACTIVE_FLG,CREATED_BY_WID,CHANGED_BY_WID,CREATED_ON_DT,CHANGED_ON_DT,AUX1_CHANGED_ON_DT,AUX2_CHANGED_ON_DT,AUX3_CHANGED_ON_DT,AUX4_CHANGED_ON_DT SRC_EFF_FROM_DT , SRC_EFF_TO_DT, EFFECTIVE_FROM_DT, EFFECTIVE_TO_DT, DELETE_FLG, CURRENT_FLG, W_INSERT_DT, W_UPDATE_DT, DATASOURCE_NUM_ID, ETL_PROC_WID, INTEGRATION_ID, SET_ID, TENANT_ID, X_CUSTOM' | (',' double all_cols) b) c
Start by curr = 1
Connect prior curr = prev
length (sys_connect_by_path(c.decode_prep,'-')) desc order)
where rownum = 1
Published by: Mac_Freak_Rahul on November 28, 2012 01:31: in the first sql ')'
removed after desc in the last line so now this query begin and will throw an error.Mac_Freak_Rahul wrote:
@Blushadow:(1) first of all, I'm sorry for not posting my question according to the rules of the forum, next time I'll take care of that.
(2) Secondly, thanks for the solution, I have no exp with clob, but I can take a deeper look later.
(3) I just want to know if there are any other wayout, you mean the second concatenation of 4000 bytes sys_connect_by_path exhausts it might return this error?SYS_CONNECT_BY_PATH returns a VARCHAR2 data type. In SQL VARCHAR2 data type is limited to 4000 bytes, then Yes, you will get an error if the data that you generate is greater than 4000 bytes (and I say bytes rather than characters, because if your database uses a multibyte multi character set could be as little as 1000 characters)
I'm right now stable for a table who got 62 columns... I have tables that have 200 close passes: (, great, if you can throw some light on this, if your the best way and the only one to achieve?)
If you really need to concatenate strings together which exceeds 4000 bytes, then Yes you must use CLOB to store data. Oracle does not provide a native way to aggregate together in a CLOB datatype string, so why you need to write your own function.
PS: just a quick overview of my value, it will be by comparing schema1.table (s) with shema2.table (s) where table_name must be the same...
So why are you information concatenation together to achieve this goal?
-
ORA-01489 sys_connect_by_path and previous solution does not
Hi all.
Oracle version:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
"CORE 11.2.0.1.0 Production."
AMT for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
I need to get directions in a card and the associated amount long distances to another.
I have a query that gets the roads properly.map -- 9 F ----------E | \ | | \2 |6 | \ 11 | 14| C-------D | / \10 / | /9 \ /15 |/ \ / A-------B 7
The problem is when there is a lot of knots, I get an ORA-01489: result of concatenating string is too long.WITH distances AS ( SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION SELECT 'F' n1, 'E' n2, 9 d FROM DUAL ) SELECT 'A'||sys_connect_by_path(n2,'-') path, SUBSTR(sys_connect_by_path(d,'+'),2) sum_dist FROM distances START WITH n1='A' CONNECT BY NOCYCLE PRIOR n2=n1; A-B 7 A-B-C 7+10 A-B-C-D 7+10+11 A-B-C-D-E 7+10+11+6 A-B-C-F 7+10+2 A-B-C-F-E 7+10+2+9 A-B-D 7+15 A-B-D-E 7+15+6 A-C 9 A-C-D 9+11 A-C-D-E 9+11+6 A-C-F 9+2 A-C-F-E 9+2+9 A-F 14 A-F-E 14+9
I followed this link.
SYS_CONNECT_BY_PATH & to_CLOB
I built the package specified but apparently is combining elements.
If it is called only once.
But if I call it twice in the same query...WITH distances AS ( SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION SELECT 'F' n1, 'E' n2, 9 d FROM DUAL ) SELECT 'A'||'-'||hierarchy.branch(LEVEL,n2,'-') path FROM distances START WITH n1='A' CONNECT BY NOCYCLE PRIOR n2=n1; A-B A-B-C A-B-C-D A-B-C-D-E A-B-C-F A-B-C-F-E A-B-D A-B-D-E A-C A-C-D A-C-D-E A-C-F A-C-F-E A-F
As you can see, is to combine the node elements (A-10-11-E) - node distance - distance-WITH distances AS ( SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION SELECT 'F' n1, 'E' n2, 9 d FROM DUAL ) SELECT 'A'||SUBSTR(hierarchy.branch(LEVEL,n2,'-'),2) path, hierarchy.branch(LEVEL,d,'+') sum_dist FROM distances START WITH n1='A' CONNECT BY NOCYCLE PRIOR n2=n1; A 7 A-C 7+10 A-10-D 7+10+11 A-10-11-E 7+10+11+6 A-10-F 7+10+2 A-10-2-E 7+10+2+9 A-D 7+15 A-15-E 7+15+6 A 9 A-D 9+11 A-11-E 9+11+6 A-F 9+2 A-2-E 9+2+9
Do I have to create separate functions in the package, one per column?, or is there another way to solve this problem?, or better yet, another way to solve the original problem (ORA-01489)
Thank you very much.
Kind regards.
Package (by Solomon Yakobson) code:
Published by: sKr on 08-mar-2012 17:29CREATE OR REPLACE PACKAGE Hierarchy IS TYPE BranchTableVarchar2Type IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER; BranchTableVarchar2 BranchTableVarchar2Type; TYPE BranchTableClobType IS TABLE OF CLOB INDEX BY BINARY_INTEGER; BranchTableClob BranchTableClobType; FUNCTION Branch( p_Level IN NUMBER, p_Value IN VARCHAR2, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES(Branch,WNDS); FUNCTION Branch( p_Level IN NUMBER, p_Value IN CLOB, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN CLOB; PRAGMA RESTRICT_REFERENCES(Branch,WNDS); END Hierarchy; / CREATE OR REPLACE PACKAGE BODY Hierarchy IS ReturnValueVarchar2 VARCHAR2(4000); ReturnValueClob CLOB; FUNCTION Branch( p_Level IN NUMBER, p_Value IN VARCHAR2, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN VARCHAR2 IS BEGIN BranchTableVarchar2(p_Level) := p_Value; ReturnValueVarchar2 := p_Value; FOR I IN REVERSE 1..p_Level - 1 LOOP ReturnValueVarchar2 := BranchTableVarchar2(I)|| p_Delimiter || ReturnValueVarchar2; END LOOP; RETURN ReturnValueVarchar2; END Branch; FUNCTION Branch( p_Level IN NUMBER, p_Value IN CLOB, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN CLOB IS BEGIN BranchTableClob(p_Level) := p_Value; ReturnValueClob := p_Value; FOR I IN REVERSE 1..p_Level - 1 LOOP ReturnValueClob := BranchTableClob(I)|| p_Delimiter || ReturnValueClob; END LOOP; RETURN ReturnValueClob; END Branch; END Hierarchy; /
Added package codeHello
sKr wrote:
Hi all.Oracle version:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
"CORE 11.2.0.1.0 Production."
AMT for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - ProductionI need to get directions in a card and the associated amount long distances to another.
map -- 9 F ----------E | \ | | \2 |6 | \ 11 | 14| C-------D | / \10 / | /9 \ /15 |/ \ / A-------B 7
...
I wish we could mark questions as 'Useful' or 'Correct '. You get 10 points for sure.
Do I have to create separate functions in the package, one per column.
You need to separate the functions. A user-defined function should be enough, just like a built-in version of SYS_CONNECT_BY_PATH is sufficient. All that should be stored in their own country, he knows that he needs to keep a separate copy for each argument to which you call it with. The problem with the package, which had been initially posted, is that there is only a single BranchTableVarchar2 of internal variables. Instead of a variable, an array of similar variables and add an optional argument to the funtion branch to tell him which item in this table to use.
CREATE OR REPLACE PACKAGE Hierarchy IS TYPE BranchTableVarchar2Type IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER; BranchTableVarchar2 BranchTableVarchar2Type; TYPE VList IS TABLE OF BranchTableVarchar2Type -- *** NEW *** INDEX BY BINARY_INTEGER; -- *** NEW *** vl VList; -- *** NEW *** TYPE BranchTableClobType IS TABLE OF CLOB INDEX BY BINARY_INTEGER; BranchTableClob BranchTableClobType; FUNCTION Branch( p_Level IN NUMBER, p_Value IN VARCHAR2, p_Delimiter IN VARCHAR2 DEFAULT CHR(0), p_PathNum IN PLS_INTEGER DEFAULT 1 -- *** NEW *** ) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES(Branch,WNDS); FUNCTION Branch( p_Level IN NUMBER, p_Value IN CLOB, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN CLOB; PRAGMA RESTRICT_REFERENCES(Branch,WNDS); END Hierarchy; / SHOW ERRORS PROMPT ========== FK BODY ========== CREATE OR REPLACE PACKAGE BODY Hierarchy IS ReturnValueVarchar2 VARCHAR2(4000); ReturnValueClob CLOB; FUNCTION Branch( p_Level IN NUMBER, p_Value IN VARCHAR2, p_Delimiter IN VARCHAR2 DEFAULT CHR(0), p_PathNum IN PLS_INTEGER DEFAULT 1 -- *** NEW *** ) RETURN VARCHAR2 IS BEGIN vl (p_PathNum) (p_Level) := p_Value; -- *** CHANGED *** ReturnValueVarchar2 := p_Value; FOR I IN REVERSE 1..p_Level - 1 LOOP ReturnValueVarchar2 := vl (p_PathNum) (I) -- *** CHANGED *** || p_Delimiter || ReturnValueVarchar2; END LOOP; RETURN ReturnValueVarchar2; END Branch; FUNCTION Branch( p_Level IN NUMBER, p_Value IN CLOB, p_Delimiter IN VARCHAR2 DEFAULT CHR(0) ) RETURN CLOB IS BEGIN BranchTableClob(p_Level) := p_Value; ReturnValueClob := p_Value; FOR I IN REVERSE 1..p_Level - 1 LOOP ReturnValueClob := BranchTableClob(I)|| p_Delimiter || ReturnValueClob; END LOOP; RETURN ReturnValueClob; END Branch; END Hierarchy; / SHOW ERRORS
As you can see, I only changed the version of VARCHAR2. Let you change the CLOB as an exercise for you.
When you call branch, pass a unique number for each output column. If you do not explicitly give a default number is 0.
Here's your query modified to call it:SELECT 'A' || SUBSTR ( hierarchy.branch ( LEVEL , n2 , '-' ) , 2 ) AS path , hierarchy.branch ( LEVEL , d , '+' , 12 ) AS sum_dist FROM distances START WITH n1 = 'A' CONNECT BY NOCYCLE PRIOR n2 = n1 ;
Path, I called the branch with only 3 arguments, so that it uses vl (0) for internal storage for the path.
For sum_dist, I had to use a different integer. I couldn't decide if I should use 1 or 2, so I compromised and used 12. I could have used any integer, except 0.
Output:PATH SUM_DIST ------------------------------ ----------------------------- A 7 A-C 7+10 A-C-D 7+10+11 A-C-D-E 7+10+11+6 A-C-F 7+10+2 A-C-F-E 7+10+2+9 A-D 7+15 A-D-E 7+15+6 A 9 A-D 9+11 A-D-E 9+11+6 A-F 9+2 A-F-E 9+2+9 A 14 A-E 14+9
or is there another way to solve this problem?, or better yet, another way to solve the original problem (ORA-01489)
Given that you call a user-defined set, you might want to add other features to the package.
For starters, in addition to a function that returns a string like "7 + 10 + 11', it might be useful to have a string that maintains these numbers internally, but returns the value 7 + 10 + 11 = 28.
If you use this for problems when you want to find the less total path (or the highest total d, for that of importance, but for now, let's say you are only interested in the minimum), you might want a function that keeps track of the minimum total d met so far for each node. Whenever you find a different path to a node, the function can check if the total d is better than the previous best. If this isn't the case, it could return an indicator (kind of similar CONNECT_BY_ISCYCLE) which indicates not bore you with this path. -
Get the ORA-01489 "result of concatenating string is too long."
Hello world
Im having problems with updating of a specific field. I got this error after I run my Update statement.
* Cause: Result of concatenation of string exceeds the maximum size.
* Action: Make sure that the result is less than the maximum size.
Here is my script:
declare cursor material is SELECT tt.column2, m.name, m.MATERIAL_ID, tt.column3, tt.column4, tt.column5, tt.column6, tt.column7, tt.column8 FROM material m, tmp_text tt WHERE m.NAME like tt.column2 || '%' AND tt.column9 = 'SI'; begin for u in material loop update material set fields_xml = '<?xml version="1.0" encoding="UTF-8"?> <fields> <field type="text" name="Size EU" maxlength="200"/> <field type="text" name="Size UK" maxlength="200"/> <field type="text" name="Weight per size" maxlength="200"/> <field type="text" name="Shaft height" maxlength="200"/> <field type="textarea" name="Product Description Norwegian" maxlength="2000">' || u.column8 || '</field> <field type="textarea" name="Product Description Swedish" maxlength="2000">' || u.column7 || '</field> <field type="textarea" name="Product Description Danish" maxlength="2000">' || u.column4 || '</field> <field type="textarea" name="Product Description Finnish" maxlength="2000">' || u.column5 || '</field> <field type="textarea" name="Product Description German" maxlength="2000">' || u.column6 || '</field> <field type="textarea" name="Product Description English" maxlength="2000">' || u.column3 || '</field> <field type="text" name="Additional Information" maxlength="200"/> </fields>' where material_id = u.material_id; end loop; end;
That the script is that it will update the 'FIELD_XML' (CLOB) field in the table "material". I know that it exceeds the maximum size. Is there another way to do this?
I would like to know your opinion... Thank you guys.
Hello
You can try with CLOB variable declaration and concatenate the value you want in it.
For example:
declare cursor material is SELECT tt.column2, m.name, m.MATERIAL_ID, tt.column3, tt.column4, tt.column5, tt.column6, tt.column7, tt.column8 FROM material m, tmp_text tt WHERE m.NAME like tt.column2 || '%' AND tt.column9 = 'SI'; v_clob CLOB; begin for u in material loop v_clob := '
'; v_clob := v_clob || u.column8 || ' '; v_clob := v_clob || '' || u.column7 || ' '; v_clob := v_clob || '' || u.column4 || ' '; v_clob := v_clob || '' || u.column5 || ' '; v_clob := v_clob || '' || u.column6 || ' '; v_clob := v_clob || '' || u.column3 || ' '; v_clob := v_clob || 'Cheerz,
Stako
-
string aggregation 4000 +.
Hi all
I'm using Oracle 11.2.0.3. I used LISTAGG to generate CSV values for names, but some of my values are greater than 4000 characters, it is throwing ORA-01489: result of concatenating string is too long.
I tried to XMLAGG allowing to solve. However, this special character space. (e.g. & be escaped to & the equivalent of xml security)
for example
with t as
(SELECT ' has "PEOPLE ' as double fname)
Union of all the
SELECT ' BALL &' as double fname
Union of all the
Select "cat!" as double fname)
Select rtrim (xmlagg (xmlelement (e, fname,',').extract('//text () ') order of fname).) GetClobVal(), ',') AS NAME of t
RETURNS: Has ' PEOPLE, BALL, & CAT!
Has ' PEOPLE EXPECTED, BALL & CAT!
Is it possible to disable escape everything using XMLAGG?
Is there any other method recommended to use aggregation of chain for more than 4000 characters?
Thank you very much!
The following would be the correct way to do it in your version.
Unescaping/cast the result as a CLOB will be XMLCast:
with t as)
Select ' has "PEOPLE ' as fname Union double all the
Select ' BALL &' as fname Union double all the
Select "cat!" as double fname
)
Select rtrim)
(xmlcast)
XMLAGG)
XmlElement (e, fname |) ',')
order of the fname
)
as clob
)
, ','
) as name
t;
(in versions< 11.1,="" i="" would="" have="" used="" dbms_xmlgen.convert="" instead="" in="" order="" to="" unescape="" entity="">
-
Listagg function gives ORA-00979: not a GROUP BY expression error
Hello
I have an environment that supports the Listagg function. Suite works perfectly:
Select task_code, LISTAGG(ename||) e ('| role |') (',',') WITHIN GROUP (ORDER BY ename) as employees
team
where task_code = '01.07.05'
Task_code group
However, this is just a test request, the real is a little wider and I can't get the function works, I get ORA-00979: not a GROUP BY expression error.
Here's my query (the column names are in Dutch, but that shouldn't really be a problem):
SELECT distinct op_sod.sod_code, op_sod.sod_omschr_lang, op_ood.ood_code, op_ood.ood_omschr_lang, op_activiteit.act_code, op_activiteit.act_omschr_lang, op_taak.taak_code, op_taak.taak_omschr_lang, op_afdeling___master.afd_code, op_taak.belmo, op_taak_j.planning_la,
LISTAGG (op_ploeg.wn_naam |) ' ('| op_ploeg.rol |') (',',') WITHIN GROUP (ORDER BY op_ploeg.wn_naam) as employees.
"Write subtaak/mijlpaal toe."
op_teamplanning.subtaak_mijlpaal as subtaak_of_mijlpaal,
op_teamplanning.subtaak_omschr | -case when op_teamplanning.subtaak_mijlpaal = 'BELMO Mijlpaal' then ' (BRUNO mijlpaalnr: ' | nvl (op_teamplanning.nummer, 0) |) ')' other ' ' end
as subtaak_mijlpaal_omschrijving, op_teamplanning.deadline as date limit, op_teamplanning.status as status,
trim (both
case when op_teamplanning.vlag1 = 'Geen' and op_teamplanning.vlag2 = 'Geen' and op_teamplanning.vlag3 = 'Geen' and op_teamplanning.vlag4 = 'Geen'
and op_teamplanning.vlag5 = 'Geen' or op_teamplanning.vlag1 is null and op_teamplanning.vlag2 is null and op_teamplanning.vlag3 is null
op_teamplanning.vlag5 is null and op_teamplanning.vlag4 is null then 'Geen '.
Another pad (both case when op_teamplanning.vlag1 = 'Geen' then "else trim (both from op_teamplanning.vlag1) end) |
trim (both case when op_teamplanning.vlag2 = 'Geen' then "another ',' | trim (both from op_teamplanning.vlag2) end) |
trim (both case when op_teamplanning.vlag3 = 'Geen' then "another ',' | trim (both from op_teamplanning.vlag3) end) |
trim (both case when op_teamplanning.vlag4 = 'Geen' then "another ',' | trim (both from op_teamplanning.vlag4) end) |
trim (both case when op_teamplanning.vlag5 = 'Geen' then "another ',' | trim (both from op_teamplanning.vlag5) end) end) as Beleidsvlaggen,
op_teamplanning.naam_verantw as quotation, op_teamplanning.subtaak_id as subtaak_id, nvl (op_teamplanning.nummer, 0) as Nummer, nvl (op_teamplanning.regelgevingsagenda, 'Nee') as
Regelgeving, op_teamplan_subsubtaak.subsubtaak_submijlpaal as subsubtaak_submijlpaal, op_teamplan_subsubtaak.subsubtaak_id as subsubtaak_id, op_teamplan_subsubtaak.subsubtaak_omschr
like subsubtaak_omschr, op_teamplan_subsubtaak.deadline, sub_deadline, op_teamplan_subsubtaak.status as sub_status, op_teamplan_subsubtaak.naam_verantw as naam_verantw
Of...
WHERE THE...
Group of op_sod.sod_code, op_sod.sod_omschr_lang, op_ood.ood_code, op_ood.ood_omschr_lang, op_activiteit.act_code, op_activiteit.act_omschr_lang, op_taak.taak_code, op_taak.taak_omschr_lang, op_afdeling___master.afd_code, op_taak.belmo, op_taak_j.planning_la
Can someone tell me the reason for this error?
Thanks in advance!
Kind regards
NDG
NDG123 wrote:
I don't really understand your other question:
Is below for example, a group of expression?
op_teamplanning.subtaak_mijlpaal
After some additional research:
The group by mistake is not appear anymore when I delete all fields after the listagg field, that might be a clue to the solution.
It is not difficult to understand. You can have other columns not aggregated in your projection on the side of those listed in the group by expression.
The reason for ORA-01489 is that the resulting string will become long and exceeds 4000 bytes.
You will find several solution in this forum.
For example
-
Ideas for work around ORA-06502: character string buffer too small on the interactive report
Hello
It comes to Apex 4.2. We try to create an interactive report. The report is for something similar at a follow-up time. We try to concat a comments column as the sum of the hours. For example,.
Select TASK_NAME, sum (HOURS), to_char (XMLAGG (XMLELEMENT(E,E.COMMENTS ||) ' : ')). Extract ('//Text ()'). GETSTRINGVAL()) USER_COMMENTS of...
This query works fine if we seek only to a window of 1 week. The question that we live, when we expand the scope of the query to include data from 3 months, we hit ORA-06502 interactive report. If we remove this column from the interactive report, then the report works very well.
Anyone has any ideas on how we might be able to work around this problem? I'm guessing we're reached the limit of 32 k on the report. Ideally, we would show just the last X number of comments and then have a link to show all comments
Any help would be appreciated
Thank you
Mike
ListAGG raises an ORA-01489 for varchar2 > 4000 bytes
OP has an ORA - 06502--> IR is running within a limit of 4 k / 32 k.
quick fix: wrap USER_COMMENTS ListAGG in a substr (..., 1, 4000)
Longer solution, use a subquery to modify comments based on ROW_NUMBER() (IE after the nth line, change the null)
with -- simulating data t as (select task_id, sysdate - lv as date_entered ,round(dbms_random.value(1,24)) hours , '-*' || lv || '.' || task_id || '*-' as user_comments from ( select level as task_id from dual connect by level <=10 ), (select level lv from dual connect by level < 1000) ), -- modify data modified_data as ( select task_id, hours, date_entered ,case when row_number() over (partition by task_id order by date_entered desc) < 5 then user_comments else null end USER_COMMENTS from t) select task_id, sum(hours) total_hours, listagg( user_comments ) within group (order by date_entered desc) || case when count(*) >= 5 then '! MORE COMMENTS !' else null end as user_comments from modified_data group by task_id;
-
Aggregation of dynamic string more than 4000 bytes in length. Oracle 11g
Hello guys,.
We use Oracle 11 g
I have a problem with the concatenation of strings being too large. I looked around for a while
and suggested customized functions (which is difficult due to restrictions in our db environment)
or by using a clob data type. Now, I have not found a way how to use a clob with the method below.
The number of lines I need to merge varies with each group IDNum so it must be dynamic
-ORA-01489: result of concatenating string is too long
SELECT LISTAGG (MYBIGTEXT, ',') IN the GROUP (ORDER BY IDNum) from ourtablewithbigtext;
Thanks for the tips.You found a character in data that are not allowed in XML documents.
See {message identifier: = 4076401}
Try this:
SQL> alter session set events = '19119 trace name context off' / session SET altered. SQL> select xmlelement("test",chr(0)) from dual / Error starting at line 3 in command: select xmlelement("test",chr(0)) from dual Error report: SQL Error: ORA-31061: XDB error: special char to escaped char conversion failed. SQL> alter session set events = '19119 trace name context forever, level 0x100000' / session SET altered. SQL> select xmlelement("test",chr(0)) from dual / XMLELEMENT("TEST",CHR(0)) --------------------------------------------------------------------------------
? SQL> alter session set events = '19119 trace name context forever, level 0x200000' / session SET altered. SQL> select xmlelement("test",chr(0)) from dual / XMLELEMENT("TEST",CHR(0)) --------------------------------------------------------------------------------& #x0000; SQL> alter session set events = '19119 trace name context forever, level 0x400000' / session SET altered. SQL> select xmlelement("test",chr(0)) from dual / XMLELEMENT("TEST",CHR(0)) --------------------------------------------------------------------------------SQL> alter session set events = '19119 trace name context off' / session SET altered. -
LISTAGG function: "result of concatenating string is too long."
Hello
I use Oracle SQL developer 3.0.04 version. I tried using the LISTAGG function to group the data.
However, I get the error message,CREATE TABLE FINAL_LOG AS SELECT SESSION_DT, C_IP, CS_USER_AGENT, listagg(WEB_LINK, ' ') WITHIN GROUP(ORDER BY C_IP, CS_USER_AGENT) "WEB_LINKS" FROM webviews GROUP BY C_IP, CS_USER_AGENT, SESSION_DT ORDER BY SESSION_DT
SQL error: ORA-01489: result of concatenating string is too long
Is it possible to go around it, or are there other alternatives?Tim Hall has a page on the various techniques of aggregation of chain that guides you through an example of creating and using a user-defined aggregate.
On AskTom referenced by Tim page, there is an implementation of an aggregation function of string that returns a CLOB that you can use.
If you want to understand what makes the user-defined aggregate function, it may look a bit complex, especially if you have never looked at object types in PL/SQL. You don't need to understand all the details of the implementation if you use just the code, however, you can simply create the function and use it as you would with any other aggregate function.
Justin
-
I have a lot of data that I need to transform and "group of groups". Let me explain with an example:
Real-world data about 5 million lines.SQL> create table orig_data as 2 select distinct job, deptno 3 from scott.emp e 4 / Table created. SQL> select job 2 , deptno 3 from orig_data 4 order by 5 job 6 , deptno 7 / JOB DEPTNO --------- ---------- ANALYST 20 CLERK 10 CLERK 20 CLERK 30 MANAGER 10 MANAGER 20 MANAGER 30 PRESIDENT 10 SALESMAN 30 9 rows selected.
I have a working group (I use xmlagg here because I'm on version 11.1 and therefore no listagg ;-))):
I note here that the two jobs CLERK and MANAGER has the same set of deptnos.SQL> select od.job 2 , rtrim(xmlagg(xmlelement(d,od.deptno,',').extract('//text()') order by od.deptno),',') deptnos 3 from orig_data od 4 group by od.job 5 / JOB DEPTNOS --------- ------------------------------ ANALYST 20 CLERK 10,20,30 MANAGER 10,20,30 PRESIDENT 10 SALESMAN 30
So if I group by deptnos I get this result:
My requirement is to identify all of these unique groups of deptnos in my table of orig_data, give each group as a surrogate key in a parent table and then populate two tables of children with the deptnos of each group and the jobs that have this group of deptnos:SQL> select s2.deptnos 2 , rtrim(xmlagg(xmlelement(j,s2.job,',').extract('//text()') order by s2.job),',') jobs 3 from ( 4 select od.job 5 , rtrim(xmlagg(xmlelement(d,od.deptno,',').extract('//text()') order by od.deptno),',') deptnos 6 from orig_data od 7 group by od.job 8 ) s2 9 group by s2.deptnos 10 / DEPTNOS JOBS ------------------------------ ------------------------------ 10 PRESIDENT 10,20,30 CLERK,MANAGER 20 ANALYST 30 SALESMAN
For the substitution groupkey I can use a rownumber on my group by query deptnos:SQL> create table groups ( 2 groupkey number primary key 3 ) 4 / Table created. SQL> create table groups_depts ( 2 groupkey number references groups (groupkey) 3 , deptno number(2) 4 ) 5 / Table created. SQL> create table groups_jobs ( 2 groupkey number references groups (groupkey) 3 , job varchar2(9) 4 ) 5 / Table created.
This application, that I can use for a (slow) insert in my three tables in this simple way:SQL> select row_number() over (order by s2.deptnos) groupkey 2 , s2.deptnos 3 , rtrim(xmlagg(xmlelement(j,s2.job,',').extract('//text()') order by s2.job),',') jobs 4 from ( 5 select od.job 6 , rtrim(xmlagg(xmlelement(d,od.deptno,',').extract('//text()') order by od.deptno),',') deptnos 7 from orig_data od 8 group by od.job 9 ) s2 10 group by s2.deptnos 11 / GROUPKEY DEPTNOS JOBS ---------- ------------------------------ ------------------------------ 1 10 PRESIDENT 2 10,20,30 CLERK,MANAGER 3 20 ANALYST 4 30 SALESMAN
The tables now with these data:SQL> begin 2 for g in ( 3 select row_number() over (order by s2.deptnos) groupkey 4 , s2.deptnos 5 , rtrim(xmlagg(xmlelement(j,s2.job,',').extract('//text()') order by s2.job),',') jobs 6 from ( 7 select od.job 8 , rtrim(xmlagg(xmlelement(d,od.deptno,',').extract('//text()') order by od.deptno),',') deptnos 9 from orig_data od 10 group by od.job 11 ) s2 12 group by s2.deptnos 13 ) loop 14 insert into groups values (g.groupkey); 15 16 insert into groups_depts 17 select g.groupkey 18 , to_number(regexp_substr(str, '[^,]+', 1, level)) deptno 19 from ( 20 select rownum id 21 , g.deptnos str 22 from dual 23 ) 24 connect by instr(str, ',', 1, level-1) > 0 25 and id = prior id 26 and prior dbms_random.value is not null; 27 28 insert into groups_jobs 29 select g.groupkey 30 , regexp_substr(str, '[^,]+', 1, level) job 31 from ( 32 select rownum id 33 , g.jobs str 34 from dual 35 ) 36 connect by instr(str, ',', 1, level-1) > 0 37 and id = prior id 38 and prior dbms_random.value is not null; 39 40 end loop; 41 end; 42 / PL/SQL procedure successfully completed.
I can now these data the same result as before (just to test, I created the desired data):SQL> select * 2 from groups 3 order by groupkey 4 / GROUPKEY ---------- 1 2 3 4 SQL> select * 2 from groups_depts 3 order by groupkey, deptno 4 / GROUPKEY DEPTNO ---------- ---------- 1 10 2 10 2 20 2 30 3 20 4 30 6 rows selected. SQL> select * 2 from groups_jobs 3 order by groupkey, job 4 / GROUPKEY JOB ---------- --------- 1 PRESIDENT 2 CLERK 2 MANAGER 3 ANALYST 4 SALESMAN
So far so good. It works all the pretty much as desired - with the exception of a couple things:SQL> select g.groupkey 2 , d.deptnos 3 , j.jobs 4 from groups g 5 join ( 6 select groupkey 7 , rtrim(xmlagg(xmlelement(d,deptno,',').extract('//text()') order by deptno),',') deptnos 8 from groups_depts 9 group by groupkey 10 ) d 11 on d.groupkey = g.groupkey 12 join ( 13 select groupkey 14 , rtrim(xmlagg(xmlelement(j,job,',').extract('//text()') order by job),',') jobs 15 from groups_jobs 16 group by groupkey 17 ) j 18 on j.groupkey = g.groupkey 19 / GROUPKEY DEPTNOS JOBS ---------- ------------------------------ ------------------------------ 1 10 PRESIDENT 2 10,20,30 CLERK,MANAGER 3 20 ANALYST 4 30 SALESMAN
The insertion code very simple loop will be slow. OK, it's a work of unique conversion (in theory, but very few times at least), so that could probably be acceptable (except for my professional pride ;-).)
But it's worse, I have groups where the aggregation of string does not work - the chain should be about varchar2 (10000) which does not work in SQL in the group by :-(.
So I tried an attempt from the collections. First a collection of deptnos:
All very good - no problem here. But then a collection of jobs:SQL> create type deptno_tab_type as table of number(2) 2 / Type created. SQL> select od.job 2 , cast(collect(od.deptno order by od.deptno) as deptno_tab_type) deptnos 3 from orig_data od 4 group by od.job 5 / JOB DEPTNOS --------- ------------------------------ ANALYST DEPTNO_TAB_TYPE(20) CLERK DEPTNO_TAB_TYPE(10, 20, 30) MANAGER DEPTNO_TAB_TYPE(10, 20, 30) PRESIDENT DEPTNO_TAB_TYPE(10) SALESMAN DEPTNO_TAB_TYPE(30)
Now, it fails - I can't group by a collection data type...SQL> create type job_tab_type as table of varchar2(9) 2 / Type created. SQL> select s2.deptnos 2 , cast(collect(s2.job order by s2.job) as job_tab_type) jobs 3 from ( 4 select od.job 5 , cast(collect(od.deptno order by od.deptno) as deptno_tab_type) deptnos 6 from orig_data od 7 group by od.job 8 ) s2 9 group by s2.deptnos 10 / group by s2.deptnos * ERROR at line 9: ORA-00932: inkonsistente datatyper: forventede -, fik XAL_SUPERVISOR.DEPTNO_TAB_TYPE
I'm not asking anyone to write my code, but I know that there are sharper brains out there on the forums of ;-).
Someone would have an idea of something I could try that will allow me to create these "groups of groups" even for large aggregation of chain that technical groups can manage?
Thanks for any help, advice or tips ;-)The issue of "group-by-collection" can be resolved by creating a container object on which we define a method of CONTROL:
SQL> create type deptno_container as object ( 2 nt deptno_tab_type 3 , order member function match (o deptno_container) return integer 4 ); 5 / Type created SQL> create or replace type body deptno_container as 2 order member function match (o deptno_container) return integer is 3 begin 4 return case when nt = o.nt then 0 else 1 end; 5 end; 6 end; 7 / Type body created
Then an INSERT statement can do the job, after unnesting collections:
SQL> insert all 2 when rn0 = 1 then into groups (groupkey) values (gid) 3 when rn1 = 1 then into groups_jobs (groupkey, job) values(gid, job) 4 when rn2 = 1 then into groups_depts (groupkey, deptno) values(gid, deptno) 5 with all_groups as ( 6 select s2.deptnos 7 , cast(collect(s2.job order by s2.job) as job_tab_type) jobs 8 , row_number() over(order by null) gid 9 from ( 10 select od.job 11 , deptno_container( 12 cast(collect(od.deptno order by od.deptno) as deptno_tab_type) 13 ) deptnos 14 from orig_data od 15 group by od.job 16 ) s2 17 group by s2.deptnos 18 ) 19 select gid 20 , value(j) job 21 , value(d) deptno 22 , row_number() over(partition by gid order by null) rn0 23 , row_number() over(partition by gid, value(j) order by null) rn1 24 , row_number() over(partition by gid, value(d) order by null) rn2 25 from all_groups t 26 , table(t.jobs) j 27 , table(t.deptnos.nt) d 28 ; 15 rows inserted SQL> select * from groups; GROUPKEY ---------- 1 2 3 4 SQL> select * from groups_jobs; GROUPKEY JOB ---------- --------- 1 SALESMAN 2 PRESIDENT 3 CLERK 3 MANAGER 4 ANALYST SQL> select * from groups_depts; GROUPKEY DEPTNO ---------- ------ 1 30 2 10 3 10 3 30 3 20 4 20 6 rows selected
Works very well on the sample data, but how this approach is changing on much (much) more large data set is another story :)
-
Release of pl/sql of division.
Oracle Database 11 g Enterprise Edition Release 11.2.0.4.0 - 64 bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE Production 11.2.0.4.0
AMT for Solaris: 11.2.0.4.0 - Production Version
NLSRTL Version 11.2.0.4.0 - Production
I'm sure this has been asked before. But I don't know what it would be called to perform a search on this subject. So my apologies in advance.
How share the output of a query, so that "parent" and "child" columns.
I loaded out with the creation of triggers for all tables in a schema. So instead of going to table by table, try to copy the column names, I ran a pl/sql block to extract all all_tab_cols.
The VALUE SERVEROUTPUT ON SIZE 100000
SET FEEDBACK WE
tabnam all_tab_cols % ROWTYPE;
FOR tabnam IN (SELECT column_name of the table table_name )
FROM all_tab_columns
WHERE owner = 'WBBETTERS')
LOOP
DBMS_OUTPUT. Put_line ()tabnam. table-name || ',' || tabnam . column_name || ' = :NEW.' || tabnam . column_name );
END LOOP;
output of very small samples:
FY14_DSF_DATA, INTERVIEW_TIME_START =: NEW. INTERVIEW_TIME_START
FY14_DSF_DATA, LAST_UPDATE =: NEW. FY14_DSF_DATA, LAST_UPDATE
FY14_DSF_DATA, SITE_CN_FK =: NEW. FY14_DSF_DATA, SITE_CN_FK
FY14_DSF_DATA, AFOREST_CODE =: NEW. FY14_DSF_DATA, AFOREST_CODE
FY14_INDIVIDUAL_DATA, PURPOSE_SITE_WORKING =: NEW. PURPOSE_SITE_WORKING
FY14_INDIVIDUAL_DATA, FROM ONE DAY TO THE NEXT =: NEW. DURING THE NIGHT
FY14_INDIVIDUAL_DATA, NVEXPAND =: NEW. NVEXPAND
FY14_INDIVIDUAL_DATA, FORM =: NEW. FORM
What I wish TO see:
INTERVIEW_TIME_START = FY14_DSF_DATA: NEW. INTERVIEW_TIME_START
LAST_UPDATE =: NEW. FY14_DSF_DATA, LAST_UPDATE
SITE_CN_FK =: NEW. FY14_DSF_DATA, SITE_CN_FK
AFOREST_CODE =: NEW. FY14_DSF_DATA, AFOREST_CODE
PURPOSE_SITE_WORKING = FY14_INDIVIDUAL_DATA: NEW. PURPOSE_SITE_WORKING
FROM ONE DAY TO THE NEXT =: NEW. DURING THE NIGHT
NVEXPAND =: NEW. NVEXPAND
SHAPE =: NEW. FORM
This way I can just enter each section and put it in the context of trigger to build it.
If you know a better way, I'm open to that as well, but please answer even this issue I can see value in learning what it is.
Thank you.
Yes, LISTAGG is limited to 4000 bytes. You can use XMLAGG:
SELECT TABLE_NAME,
(XMLCAST)
XMLAGG)
XMLELEMENT)
e,
COLUMN_NAME | ': NEW.'. COLUMN_NAME,
CHR (10)
)
ORDER OF COLUMN_ID
)
AS CLOB
) COLUMN_NAME
FROM ALL_TAB_COLUMNS
WHERE OWNER = "WBBETTERS."
TABLE_NAME GROUP
/
For example:
SQL > SELECT TABLE_NAME,.
2 LISTAGG(COLUMN_NAME ||) ': NEW.'. COLUMN_NAME, CHR (10))
3 IN COLUMN_NAME GROUP (ORDER BY COLUMN_ID)
4 FROM ALL_TAB_COLUMNS
5. WHERE OWNER = 'SCOTT '.
6 AND TABLE_NAME = "CLM_TRANS_DTL."
TABLE_NAME GROUP 7
8.
SELECT TABLE_NAME,
*
ERROR on line 1:
ORA-01489: result of concatenating string is too longSQL > SET LONG 10000
SQL > SELECT TABLE_NAME,.
() 2 XMLCAST
XMLAGG 3)
4 XMLELEMENT)
5 e,
COLUMN_NAME 6 | ': NEW.'. COLUMN_NAME,
7 CHR(10)
8 )
9 ORDER OF COLUMN_ID
10 )
11 AS CLOB
(12) COLUMN_NAME
ALL_TAB_COLUMNS 13
14. WHERE OWNER = 'SCOTT '.
15 AND TABLE_NAME = "CLM_TRANS_DTL."
16 TABLE_NAME GROUP
17.TABLE_NAME COLUMN_NAME
---------- ----------------------------------------------------------------
CLM_TRANS_ CLM_TRANS_DTL_ID: NEW. CLM_TRANS_DTL_ID
DTL FILE_FEED_HDR_ID: NEW. FILE_FEED_HDR_ID
RCV_FILE_DTL_ID: NEW. RCV_FILE_DTL_ID
TRANS_ISSUE_STAT_CD: NEW. TRANS_ISSUE_STAT_CD
CLM_SYM_CD: NEW. CLM_SYM_CD
CLM_KEY: NEW. CLM_KEY
TRANS_SEQ_NUM: NEW. TRANS_SEQ_NUM
TPA_ID: NEW. TPA_ID
BENE_ST_ABBR: NEW. BENE_ST_ABBR
TPA_ADJR_FULL_NM: NEW. TPA_ADJR_FULL_NM
TPA_SUPER_FULL_NM: NEW. TPA_SUPER_FULL_NM...
TABLE_NAME COLUMN_NAME
---------- ----------------------------------------------------------------
TPA_OFF_NM: NEW. TPA_OFF_NM
SUBRO_POTNTL_IND: NEW. SUBRO_POTNTL_IND
BANK_ACCT_OWNR_CD: NEW. BANK_ACCT_OWNR_CD
TRANS_SUBM_CD: NEW. TRANS_SUBM_CD
REC_TYP_CD: NEW. REC_TYP_CD
TPA_CLM_SUBRO_RECOV_EXPNS_AMT: NEW. TPA_CLM_SUBRO_RECOV_EXPNS_AMT
TPA_CLM_SLVG_RECOV_EXPNS_AMT: NEW. TPA_CLM_SLVG_RECOV_EXPNS_AMT
TPA_CLM_REFND_RECOV_EXPNS_AMT: NEW. TPA_CLM_REFND_RECOV_EXPNS_AMT
TPA_CLM_STAT_CD: NEW. TPA_CLM_STAT_CD
DEFNS_ATTY_FIRM_NM: NEW. DEFNS_ATTY_FIRM_NM
DEFNS_ATTY_FIRM_STR_ADDR: NEW. DEFNS_ATTY_FIRM_STR_ADDRREC_INSRT_TMSP: NEW. REC_INSRT_TMSP
REC_INSRT_OPER_ID: NEW. REC_INSRT_OPER_ID
REC_START_DT: NEW. REC_START_DT
REC_END_DT: NEW. REC_END_DTSQL >
SY.
-
When I try to perform the following PROCEDURE, he throws me an error:
Error from line: 2 in command.
BEGIN
FACT_UPDATE;
END;
Error report-
ORA-01489: result of concatenating string is too long
ORA-06512: at "AFLOBIDW. FACT_UPDATE', line 22
ORA-06512: at line 2
01489 00000 - "result of concatenating string is too long."
* Cause: Result of concatenation of string exceeds the maximum size.
* Action: Make sure that the result is less than the maximum size.
---------------------------------------------------------------------------
I can't change the logic of the code since I'm trying to do Informatica at the back done and compare performance between Informatica and Oracle DB. Is there another solution for errors? I add only the SQL query that is part of the PROCEDURE for easy viewing. Please help me. Thank you!
SELECT "UPDATE XXAFL_MON_FACTS_F SET TASK_WID ='"
|| NVL (TO_CHAR (TASK_WID), 'NULL')
|', EXECUTION_PLAN_WID ='
|| NVL (TO_CHAR (EXECUTION_PLAN_WID), 'NULL')
|| ', DETAILS_WID ='
|| NVL (TO_CHAR (DETAILS_WID), 'NULL')
|', SOURCE_WID ='
|| NVL (TO_CHAR (SOURCE_WID), 'NULL')
|', TARGET_WID = '
|| NVL (TO_CHAR (TARGET_WID), 'NULL')
|| ', RUN_STATUS_WID ='
|| NVL (TO_CHAR (RUN_STATUS_WID), 'NULL')
|', SEQ_NUM ='
|| NVL (TO_CHAR (SEQ_NUM), 'NULL')
|', NAME = "'
|| NVL (TO_CHAR (NAME), 'NULL')
|| ' ', NO_POSITION = "'
|| NVL (TO_CHAR (INSTANCE_NUM), 'NULL')
||'' ', INSTANCE_NAME = "'
|| NVL (TO_CHAR (INSTANCE_NAME), 'NULL')
|| ' ', TYPE_CD = "'
|| NVL (TO_CHAR (TYPE_CD), 'NULL')
||'' ', STATUS_CD = "'
|| NVL (TO_CHAR (STATUS_CD), 'NULL')
||'' ', START_TS ='
|| DECODE (START_TS, ",' to_date(''e))
|| To_char (START_TS, "mm/dd/yyyy hh)
||'' ((', "dd/mm/yyyy hh")')
|| ', END_TS ='
|| DECODE (END_TS, ",' to_date(''e))
|| To_char (END_TS, "mm/dd/yyyy hh)
||'' ((', "dd/mm/yyyy hh")')
|', DURATION = '
|| NVL (TO_CHAR (DURATION), 'NULL')
|', STATUS_DESC = "'
|| NVL (TO_CHAR (STATUS_DESC), 'NULL')
|| ' ', DBCONN_NAME = "'
|| NVL (TO_CHAR (DBCONN_NAME), 'NULL')
||'' ', SUCESS_ROWS ='
|| NVL (TO_CHAR (SUCESS_ROWS), 'NULL')
|| ', FAILED_ROWS ='
|| NVL (TO_CHAR (FAILED_ROWS), 'NULL')
|', ERROR_CODE = '
|| NVL (TO_CHAR (ERROR_CODE), 'NULL')
|', NUM_RETRIES ='
|| NVL (TO_CHAR (NUM_RETRIES), 'NULL')
|| ', READ_THRUPUT ='
|| NVL (TO_CHAR (READ_THRUPUT), 'NULL')
|', LAST_UPD = '
|| DECODE (LAST_UPD, ",' to_date(''e))
|| To_char (LAST_UPD, "mm/dd/yyyy hh)
||'' ((', "dd/mm/yyyy hh")')
|', RUN_STEP_WID = "'
|| NVL (TO_CHAR (RUN_STEP_WID), 'NULL')
|| ' ', W_INSERT_DT = '
|| DECODE (W_INSERT_DT, ",' to_date(''e))
|| To_char (W_INSERT_DT, "mm/dd/yyyy hh)
||'' ((', "dd/mm/yyyy hh")')
|', W_UPDATE_DT = '
|| DECODE (W_UPDATE_DT, ",' to_date(''e))
|| To_char (W_UPDATE_DT, "mm/dd/yyyy hh)
||'' ((', "dd/mm/yyyy hh")')
|| ', START_DATE_WID ='
|| NVL (TO_CHAR (START_DATE_WID), 'NULL')
|', END_DATE_WID = '
|| NVL (TO_CHAR (END_DATE_WID), 'NULL')
|', START_TIME ='
|| NVL (TO_CHAR (START_TIME), 'NULL')
|', END_TIME ='
|| NVL (TO_CHAR (END_TIME), 'NULL')
||' WHERE INTEGRATION_ID = "'
|| INTEGRATION_ID
||''';' AS Column
OF XXAFL_MON_FACTS_F;
Hello
ORA-01489 is one of these error messages that really means what he says. The error message you posted pretty much sums up the situation.
What version of Oracle are you using? (You must still include this whenever you have a question. See the FAQ forum: Re: 2. How can I ask a question on the forums? )
From 12.1 of the Oracle, there is an option to allow VARCHAR2s in SQL to be as big as 32767octets. (The default is 4000).
Otherwise, if you can't change the code, either do not run. or ensure that the concerned channels are quite short so the error does not occur.
Maybe you are looking for
-
Portege R500 - USB key requires administrative rights
I have problem with Portege R500, when the user (from the power users group) Insert the new flash memory, XP requires administrative rights. For security reasons I can't give the user administrator rights. I haveI never have this problem on other por
-
Printer Canon MG2100 device does not print the side of photography
The only way that my Canon MG2100 will be printed is if I use the photo option. It will not print documents online or regular
-
Update of security for XP (KB2686509) would not move. Any helpout there?
I just installed 9 of 10 updates but KB2686509 update could not be installed. Anyone have any suggestions that will help me in this situation?
-
This is a toolbar of IObit.com, my system said it couldn't, t find the installation source. and my manage apps feature would not allow me access to the function 'delete '.
-
How to find & download driver AVWNOTel.dll for Avery Wizard
I downloaded the Avery Wizard, but when I try to open it says that AVWNOTel.dll is not missing