<\/HEAD>
Se você já usou qualquer componente da tecnologia empresarial ESRI, você já encontrou o onipresente identificador único Global ID. <\/P>
<\/P>
Provavelmente clicando com o botão direito em uma classe de feição e selecionando "Adicionar Global ID's" e esquecendo disso. <\/P>
<\/P>
Este post é mais um desabafo e reclamação contra random <\/STRONG>GUID's do que qualquer outra coisa. Você certamente precisa de uma coluna GUID se estiver replicando dados ou realizando edições desconectadas. <\/P><\/P>Eu simplesmente os odeio! Meu problema com a coluna Global ID é como a ESRI a implementa. Não só é única (como deveria ser), é random. Eu uso dados SDE\/SQL para muito mais do que mostrar pontos em um mapa. Nós vinculamos esses dados com outras aplicações, como aquelas que gerenciam os dados não-GIS que estão anexados àquele ponto no mapa. Em algumas aplicações eu tenho dezenas de relacionamentos e tabelas dependentes daquela "tabela GIS". Tudo realizado com o uso engenhoso da coluna Global ID como uma forma de relacionar dados não-GIS aos dados GIS. Claro, eu poderia usar outra coisa, mas aí eu não teria um título de post no blog tão chamativo. <\/P><\/P>Meu problema com a coluna Global ID é sua aleatoriedade. Imagine uma classe de feição com 10.000 (eu tenho algumas com 500.000) pontos. São 10.000 GUID's random. Agora vincule essa tabela usando essa coluna, ou ordene-a, ou filtre-a. Coloque um índice clustered (ou non-clustered) na coluna Global ID. Esses GUID's random realmente deixam as coisas lentas, não é? <\/P><\/P>Vamos ver como isso funciona. Quando você faz esse clique direito e esquece, o SDE adiciona uma restrição ao campo Global ID: <\/P><\/P>ALTER TABLE [dbo].[TEST] ADD DEFAULT ('{00000000-0000-0000-0000-000000000000}') FOR [GlobalID]<\/PRE><\/P>Cada nova feição adicionada a essa classe chama um procedimento armazenado que pega um newid SQL (valor GUID) e o converte para string. <\/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>Mas e se pudéssemos fazer o GUID sequencial e não random, mas ainda assim único? Tal coisa existe, e uma busca na internet revelará um debate acalorado com muitas opiniões firmemente enraizadas a favor ou contra GUID's sequenciais. Não é o caso aqui....<\/P><\/P>Tentar alterar o SP para usar por padrão o SQL newSEQUENTIALID não 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
A função built-in newsequentialid() só pode ser usada em uma expressão DEFAULT para uma coluna do tipo 'uniqueidentifier' em uma instrução CREATE TABLE ou ALTER TABLE. Ela não pode ser combinada com outros operadores para formar uma expressão escalar complexa.<\/PRE>Então aqui está minha solução alternativa: Coloque um gatilho entre a delta e a tabela base e ignore o SP da ESRI que escreve o GUID random. Podemos fazer isso com um gatilho instead of insert e mudando o default da coluna Global ID. <\/P><\/P>Primeiro: <\/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>Depois: <\/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>Adicione alguns novos pontos e<\/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>Note como meus novos pontos (começando na linha 08 e terminando na 12) contêm IDs sequenciais. Estou usando um instead of ao invés de um gatilho after update aqui porque quero que isso ocorra ANTES de atingir a tabela base. <\/P><\/P>Infelizmente essa "alteração" não é muito robusta e não pode ser usada se seus dados estiverem versionados SEM mover edições para base ou não versionados (como você precisa quando usa Collector for ArcGIS). Também não discutido aqui está minha razão muito convincente para usar o campo Global ID em algumas das aplicações não-GIS que usam esses dados. Vamos colocar isso na categoria "brincadeira". Tenho certeza que a ESRI tem uma razão muito boa para implementar o default do Global ID como fazem, e este post certamente fomentará algum debate acalorado e comentários. <\/P><\/P>Isto junto com o gatilho after update\insert apresentado em Hey Neighbor? What's Your Value?<\/A> resultará em uma classe de feição bonita e organizada onde quase todos os atributos são automaticamente preenchidos e seus Global ID's estão ordenados. <\/P><\/P>
<\/P>
Este é um blog pessoal e não recomenda, endossa ou apoia os métodos descritos acima. A alteração de dados usando SQL fora do stack de software ESRI obviamente não é suportada e não deve ser aplicada em um banco de dados de produção sem um entendimento completo e plano de recuperação de desastres.<\/EM>
\n<\/BODY>\n<\/HTML>