ArcGIS Pro 2.9.5; Oracle 18c 10.7.1 EGDB
(will be upgraded to Pro 3.3.5; Oracle 19c 11.3 EGDB soon)
Background:
I have inherited an unregistered database view (non-spatial). The view has some joins.
select
--cast(rownum as number(38,0)) as rownum_,
cast(rownum as int) as rownum_,
sn.rdsec,
sn.ownership,
sn.name,
sn.from_,
sn.to_,
sn.boundary_rd,
sn.boundary_juris,
sn.sort,
sn.surf_mater,
sn.surf_width,
sn.shold_type,
sn.shold_width,
sn.row_,
sn.desrow,
sn.platw,
sn.environ,
sn.fenviron,
sn.tcyear1,
sn.tcaadt,
sn.aspd,
sn.replac_surf_width,
sn.class_op_grouped,
sn.recon_activity,
sde.st_length(sn.shape) as road_length,
rs.length_assumed_only,
sde.st_length(sn.shape) - rs.length_assumed_only as length_vs_assumed,
sn.numb_lanes,
sn.lane_km,
sn.strad_wavg,
sn.surface_condition_wavg,
sn.surf_year,
sn.base_year,
sn.gran_year,
sn.surf_age,
sn.base_age,
sn.gran_age,
sn.det_model_constr_type,
sn.next_forecast_activity,
sn.next_forecast_activity_descr,
sn.next_forecat_year,
sn.last_forecast_activity,
sn.last_forecast_activity_descr,
sn.last_forecat_year,
arw.replacement_cost
from
infrastr.strln_svw sn
left join
infrastr.ar_road_vw arw
on
sn.rdsec = arw.inventory_asset_id
left join
infrastr.am_excluded_roads_sd er
on
sn.rdsec = er.rdsec
left join
(
select
rdsec,
sum(evt_to - evt_from) as length_assumed_only
from
infrastr.road_assm_status
where
assm_status = 'A'
group by
rdsec
) rs
on
sn.rdsec = rs.rdsec
where
er.rdsec is null
and (sn.aspd <> 'UNIMPROVED' or sn.aspd is null)
and rs.length_assumed_only is not null
Regarding casting ROWNUM as an integer:
cast(rownum as int) as rownum_,
ArcGIS Pro is treating the ROWNUM_ column as a double:
So ROWNUM_ can't be used as the unique ID when dragging the view from Contents to the map:
However, if I were to cast ROWNUM as a number(38,0), then ArcGIS Pro would treat it as a long integer, which is good:
cast(rownum as number(38,0))
Question:
Why does Pro treat cast(rownum as int) as a double?
Which Pro? 3.2 introduced support for 64-bit integers. Up until then wide integers (except "NUMBER(38)") mapped to 64-bit float. [3.2.0 had issues with arcpy.ArcSDESQLExecute processing of 64-bit ints as 16-bit (massive overflow/underflow), but that was fixed by 3.2.1.]
The root of this issue is the lack of standard numeric types (short/int/long/real/float) in Oracle (everything is a "NUMBER"), forcing Esri to have to decide what type to map each NUMBER flavor to... Is NUMBER(10) a long integer, or a float (over 2.14e+10 INT_MAX)?
If Oracle implemented an "int" type, the "cast(rownum as int)" would work, but instead it maps it to a NUMBER which has resolution that overflows 32-bit storage (and isn't "NUMBER(38)"), so it falls back to double precision. I wonder if NUMBER(10) won't map to 64-bit integer once you get to Pro 3.3.x...
- V
PS: And be careful with casting rownum to a registered rowid column, because changing the ORDER BY would change the order (and so can the optimizer, at its whim). Since the point of a registered rowid column is to link queries to a specific row, with a WHERE clause, then the rownum values could differ on subsequent query.