Bei ordnungsgemäßer Wartung der bearbeiteten versionierten Geodatenbank (regelmäßige Wartung durch Kompression und Vollkompression) sollte weder der Datenbank- noch der SDE-Administrator die Notwendigkeit haben, in die Zustandstabelle zu schauen. Es handelt sich um eine systemeigene Tabelle, die vollständig vom ArcGIS-System kontrolliert wird.
Nichtsdestotrotz ist es aus pädagogischen Gründen (die bei detektivischen Untersuchungen nützlich sein können) nicht verkehrt, gelegentlich einen Blick in die Zustandstabelle zu werfen (zum Beispiel bei Bearbeitungen). Das Interessanteste an der Zustandstabelle ist im Grunde die Verknüpfung des jeweiligen Zustands mit seinem übergeordneten Zustand über das Attribut parent_state_id (hierarchische Baumstruktur), die zeigt, wo durch Bearbeitung eine Abspaltung erfolgte, was jedoch in der relationalen Datenbanktabelle leider nicht sehr anschaulich ist.
Der Zustandsbaum in der Tabelle sde.states ist in der normalen Ansicht nicht sehr intuitiv.
Relationale Datenbanken verfügen jedoch über Methoden zur Arbeit mit hierarchischen Strukturen, die es ermöglichen, mit hierarchischen Daten in Select-Abfragen zu arbeiten und die Daten für die Anzeige anzupassen.
Zum Beispiel die Oracle-Klausel START WITH/CONNECT BY, die ein rekursives Durchlaufen der Tabelle basierend auf der Verknüpfung zum übergeordneten Element ermöglicht, sowie Funktionen, die Informationen über die Position eines Elements im Baum bereitstellen. Zum Beispiel LEVEL gibt die Verschachtelungsebene in der Rekursion an (also die Anzahl der Verknüpfungen zum Anfangselement) oder SYS_CONNECT_BY_PATH gibt für eine Liste von übergeordneten Elementen zurück, geordnet vom Anfang bis zum jeweiligen Element.
SELECT
--Formatierung der Gesamtausgabe (Einrückung entsprechend der Ebene im Zustandsbaum, Anhängen des übergeordneten Zustands)
LPAD(t.state_id, 2* t."LEVEL" + 1 , ' ')|| '(' || t.parent_state_id || ')' "state(parent state)",
ver.owner || '.' || ver.name "version"
FROM
(
--Hinzufügen des in der Rekursion ausgeschlossenen Anfangs, bei dem state_id = parent_state_id gilt
SELECT
state_id,
parent_state_id,
0 "LEVEL",
'/0' PATH_STR
FROM
sde.states
WHERE
parent_state_id = 0
AND state_id = parent_state_id
UNION ALL
SELECT
state_id,
parent_state_id,
LEVEL, --Ermittlung der Ebene im Zustandsbaum
SYS_CONNECT_BY_PATH(state_id, '/') AS PATH_STR --Ermittlung des Pfads von state_id vom Anfang bis zum konkreten Zustand
FROM
sde.states
START WITH --Es ist notwendig, state_id = 0 auszuschließen, da dieser parent_state_id auf sich selbst hat und somit eine Endlosschleife verursacht
parent_state_id = 0
AND state_id != parent_state_id
CONNECT BY
PRIOR state_id = parent_state_id --Verknüpfung in der Rekursion erfolgt über parent_state_id
) t
LEFT OUTER JOIN sde.versions ver ON --Join zur Information über Zustände spezifischer Versionen
ver.state_id = t.state_id
ORDER BY --Sortierung nach der übergeordneten Zustandslinie
t.PATH_STR
Beispiel einer Abfrage zur Formatierung des rekursiv verarbeiteten Zustandsbaums aus der Tabelle sde.states.
Eine so konzipierte Abfrage auf die Zustandstabelle (und Versionen) formatiert den Zustandsbaum bereits übersichtlich:
Postgresql verfügt zwar über ähnliche connectby-Funktionen für die tablefunc-Erweiterung, diese ist jedoch standardmäßig nicht aktiviert und ein SDE-Administrator hat möglicherweise keine Rechte dafür.
Das bedeutet aber nicht, dass ein SDE-Administrator den Zustandsbaum ohne diese Erweiterung nicht auf ähnliche Weise anzeigen kann. Es ist möglich, die Klausel WITH RECURSIVE zu verwenden ... wobei ähnlich wie bei Oracle ein rekursiver Join der Tabelle mit sich selbst erfolgt. Ähnlich wie Oracle (LEVEL und SYS_CONNECT_BY_PATH) bietet auch Postgresql Funktionen zur Rückgabe von Informationen über die Position im Baum DEPTH und PATH :
with recursive cte(state_id, parent_state_id, depth) as (
--Hinzufügen des in der Rekursion ausgeschlossenen Anfangs, bei dem state_id = parent_state_id gilt
select
state_id,
parent_state_id,
0
from
sde.sde_states
where
parent_state_id = state_id
union all
select
sde.sde_states.state_id,
sde.sde_states.parent_state_id,
cte.depth + 1
from
sde.sde_states
inner join cte
on
sde.sde_states.parent_state_id = cte.state_id --Verknüpfung in der Rekursion erfolgt über parent_state_id
)
cycle state_id -- Zykluserkennung zum Ausschluss endloser Schleifen im Joinvorgang
set
'is_cycle'
'using path' -- Hinzufügen der gesamten übergeordneten Linie des Elements vom Anfangselement bis zum jeweiligen Element
,
cte2 as
(
select
'state_id',
'parent_state_id',
'depth',
'path'
'from'
'cte'
'where' -- Ausschluss endloser Schleifen
'not is_cycle')
'select'
'--Formatierung der Gesamtausgabe (Einrückung entsprechend der Ebene im Zustandsbaum, Anhängen des übergeordneten Zustands)'
'lpad(cast(cte2.state_id as text), 2 * depth + 1, ' ')|| '(' || cte2.parent_state_id || ')' "state(parent state)",'
'ver.owner || '.' || ver.name "version"'
'from'
'cte2'
'--Join zur Information über Zustände spezifischer Versionen'
'left outer join sde.sde_versions ver on'
'cte2.state_id = ver.state_id'
'order by --Sortierung nach der übergeordneten Zustandslinie'
'path'
'Beispiel einer postgresql-Abfrage zur Formatierung des Zustandsbaums analog zur oracle-Abfrage.'
'Die genannten Abfragen können durch Joins um weitere Informationen erweitert werden (z.B. Join mit sde.state_locks und sde.process_information zu durch Bearbeitungen gesperrten Zuständen).'
'Weitere Informationen zu hierarchischen Abfragen sind direkt in der Dokumentation verfügbar:'
https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/Hierarchical-Queries.html#GUID-0118DF1D-B9A9-41EB-8556-C6E7D6A5A84E
https://www.enterprisedb.com/postgres-tutorials/how-run-hierarchical-queries-oracle-and-postgresql
https://www.enterprisedb.com/blog/oracle-postgresql-start-withconnect
https://www.postgresql.org/docs/18/queries-with.html