<\/HEAD>
Si has usado algún componente de la tecnología empresarial ESRI, te has encontrado con el ubicuo identificador único Global ID. <\/P>
<\/P>
Probablemente haciendo clic derecho en una clase de entidad y seleccionando "Agregar Global ID's" y olvidándote de ello. <\/P>
<\/P>
Esta publicación es más un desahogo y queja contra los GUID's aleatorios <\/STRONG> que cualquier otra cosa. Ciertamente necesitas una columna GUID si estás replicando datos o realizando ediciones desconectadas. <\/P><\/P>¡Simplemente los odio absolutamente! Mi problema con la columna Global ID es cómo ESRI la implementa. No solo es única (como debería ser), sino que es aleatoria. Uso datos SDE\/SQL para mucho más que mostrar puntos en un mapa. Vinculamos esos datos con otras aplicaciones, como aquellas que gestionan los datos no GIS que están adjuntos a ese punto en el mapa. En algunas aplicaciones tengo docenas de relaciones y tablas colgando de esa "tabla GIS". Todo logrado con un uso ingenioso de la columna Global ID como una forma de relacionar datos no GIS con los datos GIS. Claro, podría usar otra cosa, pero entonces no tendría un título tan llamativo para esta publicación del blog. <\/P><\/P>Mi problema con la columna Global ID es su aleatoriedad. Imagina una clase de entidad con 10,000 (tengo algunas con 500,000) puntos. Eso son 10,000 GUID's aleatorios. Ahora vincula esa tabla usando esa columna, o ordénala, o filtra. Pon un índice clustered (o no clustered) en la columna Global ID. Esos GUID's aleatorios ciertamente ralentizan las cosas, ¿verdad? <\/P><\/P>Veamos cómo funciona esto. Cuando haces ese clic derecho y olvidas, SDE añade una restricción al campo Global ID: <\/P><\/P>ALTER TABLE [dbo].[TEST] ADD DEFAULT ('{00000000-0000-0000-0000-000000000000}') FOR [GlobalID]<\/PRE><\/P>Cada nueva entidad añadida a esa clase de entidad llama a un procedimiento almacenado que toma un newid SQL (valor GUID) y lo convierte a cadena. <\/P><\/P>CREATE PROCEDURE [dbo].[next_globalid]
@guid NVARCHAR(38) OUTPUT
AS SET NOCOUNT ON
BEGIN
SELECT @guid = '{' + CAST (NEWID() AS NVARCHAR(38)) + '}'
END
GO<\/PRE><\/P>Pero ¿y si pudiéramos hacer que el GUID sea secuencial y no aleatorio, pero aún único? Tal cosa existe, y una búsqueda en internet te revelará un debate muy acalorado con muchas opiniones firmemente arraigadas a favor o en contra de los GUID secuenciales. No es tema aquí....<\/P><\/P>Intentar alterar el SP para que use por defecto el SQL newSEQUENTIALID no funciona...<\/P><\/P>CREATE PROCEDURE [dbo].[next_globalid]
@guid NVARCHAR(38) OUTPUT
AS SET NOCOUNT ON
BEGIN
SELECT @guid = '{' + CAST (NEWSEQUENTIALID() AS NVARCHAR(38)) + '}'
END
GO
La función incorporada newsequentialid() solo puede usarse en una expresión DEFAULT para una columna del tipo 'uniqueidentifier' en una sentencia CREATE TABLE o ALTER TABLE. No puede combinarse con otros operadores para formar una expresión escalar compleja.<\/PRE>Así que aquí está mi solución alternativa: poner un trigger entre la tabla delta y la base e ignorar el SP ESRI que escribe el GUID aleatorio. Podemos hacer esto con un trigger instead of insert y cambiando el valor por defecto de la columna Global ID. <\/P><\/P>Primero: <\/P><\/P>ALTER TABLE [dbo].[TEST] DROP CONSTRAINT [DF__TEST__GlobalID__65FFA925]
GO
ALTER TABLE [dbo].[TEST] ADD CONSTRAINT [DF__TEST__GlobalID__65FFA925] DEFAULT (newsequentialid()) FOR [GlobalID]
GO<\/PRE><\/P>Luego: <\/P><\/P>CREATE TRIGGER [dbo].[TEST_GLOBAL_ID]
ON [dbo].[TEST]
INSTEAD OF INSERT NOT FOR REPLICATION
AS BEGIN
SET NOCOUNT ON;
INSERT [TEST](
OBJECTID, SOMEFIELD, SHAPE, LON, LAT, QuadName, Watershed, County, State, PARKDISTRICT, ELEVATION, StreamName, RiverOrder
)
SELECT
OBJECTID, a.SOMEFIELD, a.SHAPE, a.LON, a.LAT, a.QuadName, a.Watershed, a.County, a.State, a.PARKDISTRICT, a.ELEVATION, a.StreamName, a.RiverOrder
From
(SELECT
OBJECTID, SOMEFIELD, SHAPE, LON, LAT, QuadName, Watershed, County, State, PARKDISTRICT, ELEVATION, StreamName, RiverOrder
FROM inserted)
AS a
;
end
GO<\/PRE>Añade un par de puntos nuevos y<\/P><\/P>SELECT
[GlobalID]
FROM [FISH].[dbo].[TEST]<\/PRE><\/P><\/P>GlobalID
C10EB116-8B14-45AB-924D-0C734E5AB5B6
61AE23FA-F02D-45C1-991D-571B77592014
0695789D-35A7-4BE4-B5F6-5EAF68D2A50B
5A20B628-6048-4D48-8380-AC005A0E70EC
CF52E6DE-5F60-456E-9DEF-C006D9BBD348
58F80A07-F8A8-4D62-BBB3-D012EA781F0C
5E7B9C91-2891-E411-B57C-E41F134196DA
BE30E498-2891-E411-B57C-E41F134196DA
BF30E498-2891-E411-B57C-E41F134196DA
C030E498-2891-E411-B57C-E41F134196DA
C130E498-2891-E411-B57C-E41F134196DA
38C5A6F2-60FF-4C39-BF37-F7AFCBDFDE90<\/PRE><\/P>Observa cómo mis nuevos puntos (empezando en la línea 08 y terminando en la 12) contienen ID secuenciales. Estoy usando un instead of en lugar de un after update trigger aquí porque quiero que esto ocurra ANTES de que llegue a la tabla base. <\/P><\/P>Desafortunadamente, esta "alteración" no es muy robusta y no puede usarse si tus datos están versionados SIN mover ediciones a base o si no están versionados en absoluto (como se necesita cuando se usa Collector for ArcGIS). Tampoco se discute aquí mi razón muy convincente para usar el campo Global ID en algunas de las aplicaciones no GIS que usan estos datos. Consideremos esto dentro de la categoría "experimentos". Estoy seguro de que ESRI tiene una muy buena razón para implementar el valor por defecto del Global ID como lo hace y esta publicación seguramente fomentará debates acalorados y comentarios. <\/P><\/P>Esto junto con el trigger after update\insert presentado en Hey Neighbor? What's Your Value?<\/A> resultará en una clase de entidad limpia y ordenada donde casi todos los atributos se llenan automáticamente y tus Global ID's están ordenados. <\/P><\/P>
<\/P>
Este es un blog personal y no recomienda ni respalda los métodos descritos arriba. La alteración de datos usando SQL fuera del stack de software ESRI no está soportada y no debe aplicarse a una base de datos productiva sin un entendimiento completo y un plan de recuperación ante desastres.<\/EM>
<\BODY>