Auto increment counter if field length is greater than n Auto increment counter if field length is greater than n oracle oracle

Auto increment counter if field length is greater than n


Here is a solution that makes no prior assumptions about the length of comments. I added two strings, one short (less than 5 characters) and one longer than 10 characters, as well as one with NULL comment to make sure the row is not lost, to test the solution thoroughly.

I assume (empid, dt) is a unique combination (perhaps primary key) in the base table. By the way, I hope you are not actually using Date as a column name in your schema.

The solution does not contain the WITH clause; it begins at select empid... The ORDER BY clause may not be needed either.

with     test_data ( empid, empname, servicenumber, dt, comments ) as (       select 1, 'a',  123, to_date('23-03-1990', 'dd-mm-yyyy'), 'wednesday'   from dual union all       select 1, 'a', 1234, to_date('24-04-1990', 'dd-mm-yyyy'), 'Test12'      from dual union all       select 2, 'b',  234, to_date('24-05-2016', 'dd-mm-yyyy'), 'Todayis'     from dual union all       select 2, 'b',  235, to_date('25-05-2016', 'dd-mm-yyyy'), 'Joe'         from dual union all       select 3, 'c',  238, to_date('25-05-2016', 'dd-mm-yyyy'), ''            from dual union all       select 4, 'c', 2238, to_date('25-05-2016', 'dd-mm-yyyy'), 'longer string' from dual     )select empid, empname, servicenumber, dt, level as comno,       substr(comments, 5 * level - 4, 5) as commentsfrom   test_dataconnect by level <= 1 + length(comments) / 5     and   prior empid = empid     and   prior dt    = dt     and   prior sys_guid() is not nullorder by empid, dt;     EMPID E SERVICENUMBER DT              COMNO COMMENTS---------- - ------------- ---------- ---------- --------------------         1 a           123 1990-03-23          1 wedne         1 a           123 1990-03-23          2 sday         1 a          1234 1990-04-24          1 Test1         1 a          1234 1990-04-24          2 2         2 b           234 2016-05-24          1 Today         2 b           234 2016-05-24          2 is         2 b           235 2016-05-25          1 Joe         3 c           238 2016-05-25          1         4 c          2238 2016-05-25          1 longe         4 c          2238 2016-05-25          2 r str         4 c          2238 2016-05-25          3 ing

Added: If your data is of CLOB data type, it is better to use the dbms_lob version of substr. Also, if you must chop the data into 75 character segments, you must adjust several numbers. Here is the same solution, with these two changes and without the ORDER BY clause (not needed if this is used to migrate the data to another db product). NOTE: dbms_lob.substr() has the "amount" and the "offset" (second and third arguments) reversed compared to the usual substr() function; notice that when you compare the solutions.

select empid, empname, servicenumber, dt, level as comno,       dbms_lob.substr(comments, 75, 75 * level - 74) as commentsfrom   test_dataconnect by level <= 1 + length(comments) / 75     and   prior empid = empid     and   prior dt    = dt     and   prior sys_guid() is not null;


Here is one way to do this:

with n as (      select 1 as n from dual union all      select 2 from dual     )select EmpID, EmpName, ServiceNumber, Date, ComNo,       substr(comments, n.n * 5 - 4, 5) as Commentsfrom t join     n     on length(comments) >= n.n * 5 + 1;

Note: Your example only has comments up to 10 characters, so only the values 1 and 2 are needed for n. You can create additional rows by expanding n.


A brute force option would be to just UNION together the records resulting from splitting the comments by 5 characters at a time:

SELECT EmpID, EmpName, ServiceNumber, Date, 1, SUBSTR(Comments, 1, 5) AS CommentsFROM yourTableUNION ALLSELECT EmpID, EmpName, ServiceNumber, Date, 2, SUBSTR(Comments, 6, 5) AS CommentsFROM yourTableWHERE SUBSTR(Comments, 6, 5) <> ''  -- but don't show a record ifUNION ALL                           -- all characters already used...