<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic PL/SQL Code Review: Set polyline M-values to cumulative length of line in Geodatabase Questions</title>
    <link>https://community.esri.com/t5/geodatabase-questions/pl-sql-code-review-set-polyline-m-values-to/m-p/1159398#M7617</link>
    <description>&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Bud_1-1648648214287.png" style="width: 999px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/37699i7C6B9674E42DC502/image-size/large?v=v2&amp;amp;px=999" role="button" title="Bud_1-1648648214287.png" alt="Bud_1-1648648214287.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I have a&lt;SPAN&gt;&amp;nbsp;multi-part&amp;nbsp;&lt;/SPAN&gt;polyline in an SDE.ST_GEOMETRY feature class (Oracle 18c EGDB).&lt;/P&gt;&lt;P&gt;I've written a PL/SQL function that replaces the geometry's M-values with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;cumulative length of the line&lt;/STRONG&gt;.&lt;BR /&gt;(My plan is to eventually create a database trigger that uses the function to update polyline geometries — when features get edited.)&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;Input:&lt;/SPAN&gt;
MULTILINESTRING M (( &lt;SPAN class=""&gt;0.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;5.0&lt;/SPAN&gt;&lt;FONT color="#000000"&gt;&lt;STRONG&gt; -&lt;SPAN class=""&gt;100000.0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;-&lt;SPAN class=""&gt;100000.0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;30.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;0.0&lt;/SPAN&gt; &lt;STRONG&gt;-&lt;SPAN class=""&gt;123&lt;/SPAN&gt;&lt;/STRONG&gt;),( &lt;SPAN class=""&gt;50.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;456&lt;/STRONG&gt;, &lt;SPAN class=""&gt;60.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;789&lt;/STRONG&gt;))
--&lt;SPAN class=""&gt;select&lt;/SPAN&gt; sde.st_astext(shape) &lt;SPAN class=""&gt;from&lt;/SPAN&gt; polylines&lt;/FONT&gt;

&lt;SPAN class=""&gt;Output:&lt;/SPAN&gt;
MULTILINESTRING M ((&lt;SPAN class=""&gt;0&lt;/SPAN&gt; &lt;SPAN class=""&gt;5&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;11.18&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;30&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;33.54&lt;/SPAN&gt;&lt;/STRONG&gt;),(&lt;SPAN class=""&gt;50&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;33.54&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;60&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;43.54&lt;/SPAN&gt;&lt;/STRONG&gt;))
--&lt;SPAN class=""&gt;select&lt;/SPAN&gt; m_as_length(shape) &lt;SPAN class=""&gt;from&lt;/SPAN&gt; polylines&lt;/PRE&gt;&lt;HR /&gt;&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;FONT face="courier new,courier" color="#0000FF"&gt;m_as_length()&lt;/FONT&gt; function works as expected.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;BR /&gt;But I'm a PL/SQL novice, so I thought I'd ask:&amp;nbsp;&lt;U&gt;Can the script be improved?&lt;/U&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;with&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;function&lt;/SPAN&gt; pythagoras(x1 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, y1 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, x2 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, y2 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number) &lt;SPAN class=""&gt;return&lt;/SPAN&gt; number &lt;SPAN class=""&gt;is&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;begin&lt;/SPAN&gt;
      &lt;SPAN class=""&gt;return&lt;/SPAN&gt; round(&lt;SPAN class=""&gt;sqrt&lt;/SPAN&gt;( (x2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; x1) &lt;SPAN class=""&gt;*&lt;/SPAN&gt; (x2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; x1) &lt;SPAN class=""&gt;+&lt;/SPAN&gt; (y2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; y1) &lt;SPAN class=""&gt;*&lt;/SPAN&gt; (y2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; y1)), &lt;SPAN class=""&gt;2&lt;/SPAN&gt;);  &lt;SPAN class=""&gt;-- Power is a slow function&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;end&lt;/SPAN&gt;;
   
    &lt;SPAN class=""&gt;function&lt;/SPAN&gt; m_as_length(shape &lt;SPAN class=""&gt;in&lt;/SPAN&gt; sde.st_geometry) &lt;SPAN class=""&gt;return&lt;/SPAN&gt; varchar2
    &lt;SPAN class=""&gt;is&lt;/SPAN&gt;
        &lt;SPAN class=""&gt;result&lt;/SPAN&gt;              varchar2(&lt;SPAN class=""&gt;32767&lt;/SPAN&gt;);
        vertex_set          varchar2(&lt;SPAN class=""&gt;32767&lt;/SPAN&gt;);
        oldX                number;
        oldY                number;
        newX                number;
        newY                number;
        line_len            number :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;;
    &lt;SPAN class=""&gt;begin&lt;/SPAN&gt;       
        &lt;SPAN class=""&gt;for&lt;/SPAN&gt; vPartIndex &lt;SPAN class=""&gt;in&lt;/SPAN&gt; &lt;SPAN class=""&gt;1.&lt;/SPAN&gt;.sde.st_geometry_operators.st_numgeometries_f(shape)
        loop
            vertex_set      :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;null&lt;/SPAN&gt;;
            &lt;SPAN class=""&gt;for&lt;/SPAN&gt; vPointIndex &lt;SPAN class=""&gt;in&lt;/SPAN&gt; &lt;SPAN class=""&gt;1.&lt;/SPAN&gt;.sde.st_geometry_operators.st_numpoints_f(sde.st_geometry_operators.ST_GeometryN_f(shape,vPartIndex))
            loop
                newX        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_pointn_f(sde.st_geometry_operators.st_geometryn_f(shape,vPartIndex),vPointIndex));
                newY        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_pointn_f(sde.st_geometry_operators.st_geometryn_f(shape,vPartIndex),vPointIndex));
                if vPointIndex &lt;SPAN class=""&gt;&amp;lt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class=""&gt;1&lt;/SPAN&gt; &lt;SPAN class=""&gt;then&lt;/SPAN&gt;
                   line_len :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; line_len &lt;SPAN class=""&gt;+&lt;/SPAN&gt; pythagoras(oldX, oldY, newX, newY);
                &lt;SPAN class=""&gt;end&lt;/SPAN&gt; if;
                oldX        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; newX;
                oldY        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; newY;
                vertex_set  :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; vertex_set &lt;SPAN class=""&gt;||&lt;/SPAN&gt; newX &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;' '&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; newY &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;' '&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; line_len &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;', '&lt;/SPAN&gt;;
            &lt;SPAN class=""&gt;end&lt;/SPAN&gt; loop;
            &lt;SPAN class=""&gt;result&lt;/SPAN&gt;          :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;result&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;'('&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; rtrim((vertex_set),&lt;SPAN class=""&gt;', '&lt;/SPAN&gt;) &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;'),'&lt;/SPAN&gt;;
        &lt;SPAN class=""&gt;end&lt;/SPAN&gt; loop;
        &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;'MULTILINESTRING M ('&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; rtrim((&lt;SPAN class=""&gt;result&lt;/SPAN&gt;),&lt;SPAN class=""&gt;','&lt;/SPAN&gt;) &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;')'&lt;/SPAN&gt;;
    &lt;SPAN class=""&gt;end&lt;/SPAN&gt;;
&lt;SPAN class=""&gt;select&lt;/SPAN&gt;
    m_as_length(shape)
&lt;SPAN class=""&gt;from&lt;/SPAN&gt;
    polyline&lt;/PRE&gt;&lt;HR /&gt;&lt;P&gt;Related:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;&lt;P&gt;&lt;A href="https://gis.stackexchange.com/a/344451/62572" target="_blank" rel="noopener"&gt;Use SDE.ST_GEOMETRY functions in a custom function&lt;/A&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Explains why the function calls are so verbose:&amp;nbsp;&lt;SPAN&gt;&amp;nbsp;&lt;FONT face="courier new,courier" color="#0000FF"&gt;sde.st_geometry_operators.st_numgeometries_f&lt;/FONT&gt;.&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;ST_GEOMETRY functions:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-numgeometries.htm" target="_blank" rel="noopener"&gt;st_numgeometries&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-x.htm" target="_blank" rel="noopener"&gt;st_x&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-startpoint.htm" target="_blank" rel="noopener"&gt;st_startpoint&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-geometryn.htm" target="_blank" rel="noopener"&gt;st_geometryN&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-numpoints.htm" target="_blank" rel="noopener"&gt;st_numpoints&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-pointn.htm" target="_blank" rel="noopener"&gt;st_pointn&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;&lt;SPAN&gt;I'm aware that this sort of thing can be &lt;A href="https://community.esri.com/t5/arcgis-pro-questions/arcade-code-review-set-polyline-m-values-to/m-p/1157702/highlight/true#M53244" target="_self"&gt;achieved with Arcade&lt;/A&gt; in ArcGIS Pro 2.6+. Even still, I want to learn how to do this in PL/SQL, for professional development reasons, and to have a plan B, for scenarios where Arcade won't work (due to compatibility issues, etc.).&lt;/SPAN&gt;&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;&lt;FONT face="inherit"&gt;My FC is registered as versioned (with option to move edits to base). We don't use &lt;EM&gt;named&lt;/EM&gt; versions, we only use the default version (so that we can undo/redo edits while editing). So in this case, using database triggers on a versioned FC shouldn't be an issue -- especially since we're &lt;/FONT&gt;exclusively&lt;FONT face="inherit"&gt;&amp;nbsp;working in the base FC -- and are using the "with base" option. &lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 01 Apr 2022 13:29:05 GMT</pubDate>
    <dc:creator>Bud</dc:creator>
    <dc:date>2022-04-01T13:29:05Z</dc:date>
    <item>
      <title>PL/SQL Code Review: Set polyline M-values to cumulative length of line</title>
      <link>https://community.esri.com/t5/geodatabase-questions/pl-sql-code-review-set-polyline-m-values-to/m-p/1159398#M7617</link>
      <description>&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Bud_1-1648648214287.png" style="width: 999px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/37699i7C6B9674E42DC502/image-size/large?v=v2&amp;amp;px=999" role="button" title="Bud_1-1648648214287.png" alt="Bud_1-1648648214287.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I have a&lt;SPAN&gt;&amp;nbsp;multi-part&amp;nbsp;&lt;/SPAN&gt;polyline in an SDE.ST_GEOMETRY feature class (Oracle 18c EGDB).&lt;/P&gt;&lt;P&gt;I've written a PL/SQL function that replaces the geometry's M-values with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;cumulative length of the line&lt;/STRONG&gt;.&lt;BR /&gt;(My plan is to eventually create a database trigger that uses the function to update polyline geometries — when features get edited.)&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;Input:&lt;/SPAN&gt;
MULTILINESTRING M (( &lt;SPAN class=""&gt;0.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;5.0&lt;/SPAN&gt;&lt;FONT color="#000000"&gt;&lt;STRONG&gt; -&lt;SPAN class=""&gt;100000.0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;-&lt;SPAN class=""&gt;100000.0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;30.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;0.0&lt;/SPAN&gt; &lt;STRONG&gt;-&lt;SPAN class=""&gt;123&lt;/SPAN&gt;&lt;/STRONG&gt;),( &lt;SPAN class=""&gt;50.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;456&lt;/STRONG&gt;, &lt;SPAN class=""&gt;60.0&lt;/SPAN&gt; &lt;SPAN class=""&gt;10.0&lt;/SPAN&gt; &lt;STRONG&gt;789&lt;/STRONG&gt;))
--&lt;SPAN class=""&gt;select&lt;/SPAN&gt; sde.st_astext(shape) &lt;SPAN class=""&gt;from&lt;/SPAN&gt; polylines&lt;/FONT&gt;

&lt;SPAN class=""&gt;Output:&lt;/SPAN&gt;
MULTILINESTRING M ((&lt;SPAN class=""&gt;0&lt;/SPAN&gt; &lt;SPAN class=""&gt;5&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;0&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;11.18&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;30&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;33.54&lt;/SPAN&gt;&lt;/STRONG&gt;),(&lt;SPAN class=""&gt;50&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;33.54&lt;/SPAN&gt;&lt;/STRONG&gt;, &lt;SPAN class=""&gt;60&lt;/SPAN&gt; &lt;SPAN class=""&gt;10&lt;/SPAN&gt; &lt;STRONG&gt;&lt;SPAN class=""&gt;43.54&lt;/SPAN&gt;&lt;/STRONG&gt;))
--&lt;SPAN class=""&gt;select&lt;/SPAN&gt; m_as_length(shape) &lt;SPAN class=""&gt;from&lt;/SPAN&gt; polylines&lt;/PRE&gt;&lt;HR /&gt;&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;FONT face="courier new,courier" color="#0000FF"&gt;m_as_length()&lt;/FONT&gt; function works as expected.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;BR /&gt;But I'm a PL/SQL novice, so I thought I'd ask:&amp;nbsp;&lt;U&gt;Can the script be improved?&lt;/U&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;with&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;function&lt;/SPAN&gt; pythagoras(x1 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, y1 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, x2 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number, y2 &lt;SPAN class=""&gt;in&lt;/SPAN&gt; number) &lt;SPAN class=""&gt;return&lt;/SPAN&gt; number &lt;SPAN class=""&gt;is&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;begin&lt;/SPAN&gt;
      &lt;SPAN class=""&gt;return&lt;/SPAN&gt; round(&lt;SPAN class=""&gt;sqrt&lt;/SPAN&gt;( (x2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; x1) &lt;SPAN class=""&gt;*&lt;/SPAN&gt; (x2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; x1) &lt;SPAN class=""&gt;+&lt;/SPAN&gt; (y2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; y1) &lt;SPAN class=""&gt;*&lt;/SPAN&gt; (y2 &lt;SPAN class=""&gt;-&lt;/SPAN&gt; y1)), &lt;SPAN class=""&gt;2&lt;/SPAN&gt;);  &lt;SPAN class=""&gt;-- Power is a slow function&lt;/SPAN&gt;
    &lt;SPAN class=""&gt;end&lt;/SPAN&gt;;
   
    &lt;SPAN class=""&gt;function&lt;/SPAN&gt; m_as_length(shape &lt;SPAN class=""&gt;in&lt;/SPAN&gt; sde.st_geometry) &lt;SPAN class=""&gt;return&lt;/SPAN&gt; varchar2
    &lt;SPAN class=""&gt;is&lt;/SPAN&gt;
        &lt;SPAN class=""&gt;result&lt;/SPAN&gt;              varchar2(&lt;SPAN class=""&gt;32767&lt;/SPAN&gt;);
        vertex_set          varchar2(&lt;SPAN class=""&gt;32767&lt;/SPAN&gt;);
        oldX                number;
        oldY                number;
        newX                number;
        newY                number;
        line_len            number :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;0&lt;/SPAN&gt;;
    &lt;SPAN class=""&gt;begin&lt;/SPAN&gt;       
        &lt;SPAN class=""&gt;for&lt;/SPAN&gt; vPartIndex &lt;SPAN class=""&gt;in&lt;/SPAN&gt; &lt;SPAN class=""&gt;1.&lt;/SPAN&gt;.sde.st_geometry_operators.st_numgeometries_f(shape)
        loop
            vertex_set      :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;null&lt;/SPAN&gt;;
            &lt;SPAN class=""&gt;for&lt;/SPAN&gt; vPointIndex &lt;SPAN class=""&gt;in&lt;/SPAN&gt; &lt;SPAN class=""&gt;1.&lt;/SPAN&gt;.sde.st_geometry_operators.st_numpoints_f(sde.st_geometry_operators.ST_GeometryN_f(shape,vPartIndex))
            loop
                newX        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_pointn_f(sde.st_geometry_operators.st_geometryn_f(shape,vPartIndex),vPointIndex));
                newY        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_pointn_f(sde.st_geometry_operators.st_geometryn_f(shape,vPartIndex),vPointIndex));
                if vPointIndex &lt;SPAN class=""&gt;&amp;lt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class=""&gt;1&lt;/SPAN&gt; &lt;SPAN class=""&gt;then&lt;/SPAN&gt;
                   line_len :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; line_len &lt;SPAN class=""&gt;+&lt;/SPAN&gt; pythagoras(oldX, oldY, newX, newY);
                &lt;SPAN class=""&gt;end&lt;/SPAN&gt; if;
                oldX        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; newX;
                oldY        :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; newY;
                vertex_set  :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; vertex_set &lt;SPAN class=""&gt;||&lt;/SPAN&gt; newX &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;' '&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; newY &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;' '&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; line_len &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;', '&lt;/SPAN&gt;;
            &lt;SPAN class=""&gt;end&lt;/SPAN&gt; loop;
            &lt;SPAN class=""&gt;result&lt;/SPAN&gt;          :&lt;SPAN class=""&gt;=&lt;/SPAN&gt; &lt;SPAN class=""&gt;result&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;'('&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; rtrim((vertex_set),&lt;SPAN class=""&gt;', '&lt;/SPAN&gt;) &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;'),'&lt;/SPAN&gt;;
        &lt;SPAN class=""&gt;end&lt;/SPAN&gt; loop;
        &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;'MULTILINESTRING M ('&lt;/SPAN&gt; &lt;SPAN class=""&gt;||&lt;/SPAN&gt; rtrim((&lt;SPAN class=""&gt;result&lt;/SPAN&gt;),&lt;SPAN class=""&gt;','&lt;/SPAN&gt;) &lt;SPAN class=""&gt;||&lt;/SPAN&gt; &lt;SPAN class=""&gt;')'&lt;/SPAN&gt;;
    &lt;SPAN class=""&gt;end&lt;/SPAN&gt;;
&lt;SPAN class=""&gt;select&lt;/SPAN&gt;
    m_as_length(shape)
&lt;SPAN class=""&gt;from&lt;/SPAN&gt;
    polyline&lt;/PRE&gt;&lt;HR /&gt;&lt;P&gt;Related:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;&lt;P&gt;&lt;A href="https://gis.stackexchange.com/a/344451/62572" target="_blank" rel="noopener"&gt;Use SDE.ST_GEOMETRY functions in a custom function&lt;/A&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Explains why the function calls are so verbose:&amp;nbsp;&lt;SPAN&gt;&amp;nbsp;&lt;FONT face="courier new,courier" color="#0000FF"&gt;sde.st_geometry_operators.st_numgeometries_f&lt;/FONT&gt;.&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;ST_GEOMETRY functions:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-numgeometries.htm" target="_blank" rel="noopener"&gt;st_numgeometries&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-x.htm" target="_blank" rel="noopener"&gt;st_x&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-startpoint.htm" target="_blank" rel="noopener"&gt;st_startpoint&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-geometryn.htm" target="_blank" rel="noopener"&gt;st_geometryN&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-numpoints.htm" target="_blank" rel="noopener"&gt;st_numpoints&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/using-sql-with-gdbs/st-pointn.htm" target="_blank" rel="noopener"&gt;st_pointn&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;&lt;SPAN&gt;I'm aware that this sort of thing can be &lt;A href="https://community.esri.com/t5/arcgis-pro-questions/arcade-code-review-set-polyline-m-values-to/m-p/1157702/highlight/true#M53244" target="_self"&gt;achieved with Arcade&lt;/A&gt; in ArcGIS Pro 2.6+. Even still, I want to learn how to do this in PL/SQL, for professional development reasons, and to have a plan B, for scenarios where Arcade won't work (due to compatibility issues, etc.).&lt;/SPAN&gt;&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;&lt;FONT face="inherit"&gt;My FC is registered as versioned (with option to move edits to base). We don't use &lt;EM&gt;named&lt;/EM&gt; versions, we only use the default version (so that we can undo/redo edits while editing). So in this case, using database triggers on a versioned FC shouldn't be an issue -- especially since we're &lt;/FONT&gt;exclusively&lt;FONT face="inherit"&gt;&amp;nbsp;working in the base FC -- and are using the "with base" option. &lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 01 Apr 2022 13:29:05 GMT</pubDate>
      <guid>https://community.esri.com/t5/geodatabase-questions/pl-sql-code-review-set-polyline-m-values-to/m-p/1159398#M7617</guid>
      <dc:creator>Bud</dc:creator>
      <dc:date>2022-04-01T13:29:05Z</dc:date>
    </item>
  </channel>
</rss>

