<\/HEAD>
ESRI enterprise technology のいずれかのコンポーネントを使用したことがあるなら、どこにでもある Global ID ユニーク識別子に出会ったことでしょう。 <\/P>
<\/P>
おそらくフィーチャクラスを右クリックして「Add Global ID's」を選択し、そのまま忘れてしまったのではないでしょうか。 <\/P>
<\/P>
この投稿は、他の何よりも ランダムな <\/STRONG>GUID に対する愚痴と怒りです。データをレプリケートしたり、切断された編集を行う場合は、確かに GUID カラムが必要です。 <\/P><\/P>私はそれらが本当に大嫌いです!私の Global ID カラムに対する問題は、ESRI の実装方法にあります。ユニークであるべきなのは当然ですが、それがランダムなのです。私は SDE\/SQL データを単に地図上に点を表示する以上の用途で使っています。そのデータには、地図上のその点に付随する非GISデータを管理する他のアプリケーションからリンクしています。いくつかのアプリケーションでは、その「GISテーブル」から多数のリレーションシップやテーブルがぶら下がっています。すべては Global ID カラムを巧みに使って非GISデータとGISデータを関連付けることで実現しています。もちろん他のものを使うこともできますが、そうするとこんな注目を集めるブログ投稿タイトルにはなりません。 <\/P><\/P>私の Global ID カラムに対する問題は、そのランダム性です。1万(私の場合は50万ポイントのものもあります)のポイントがあるフィーチャクラスを想像してください。それは1万個のランダムな GUID です。そのカラムを使ってテーブルにリンクしたり、ソートしたり、フィルターしたりします。Global ID カラムにクラスタ化(または非クラスタ化)インデックスを付けてみてください。そのランダムな GUID は確実に処理速度を遅くしますよね? <\/P><\/P>これがどう機能するか見てみましょう。右クリックして忘れると、SDE は Global ID フィールドに制約を追加します: <\/P><\/P>ALTER TABLE [dbo].[TEST] ADD DEFAULT ('{00000000-0000-0000-0000-000000000000}') FOR [GlobalID]<\/PRE><\/P>そのフィーチャクラスに新しいフィーチャが追加されるたびに、SQL newid (GUID 値) を取得して文字列に変換するストアドプロシージャが呼ばれます。 <\/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>しかし、もし GUID をランダムではなく連続的で、それでもユニークにできたらどうでしょう?そのようなものは存在し、インターネット検索では連続 GUID に賛成・反対で激しい議論が多く見つかります。ここでは触れません....<\/P><\/P>SP を SQL newSEQUENTIALID に変更しようとしてもうまくいきません...<\/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
The newsequentialid() built-in function can only be used in a DEFAULT expression for a column of type 'uniqueidentifier' in a CREATE TABLE or ALTER TABLE statement. It cannot be combined with other operators to form a complex scalar expression.<\/PRE>そこで私の回避策です:デルタテーブルとベーステーブルの間にトリガーを入れて、ランダム GUID を書き込む ESRI SP を無視します。代わりに insert トリガーと Global ID カラムのデフォルト変更でこれを実現します。 <\/P><\/P>まず: <\/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>次に: <\/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>新しいポイントをいくつか追加して<\/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>新しいポイント(08行目から12行目まで)が連続した ID を含んでいることに注目してください。ここで after update トリガーではなく instead of トリガーを使っている理由は、ベーステーブルに入る前にこれを実行したいためです。 <\/P><\/P>残念ながら、この「変更」はあまり堅牢ではなく、編集内容をベースへ移動しないバージョニングされたデータやバージョニングされていないデータ(Collector for ArcGIS 使用時など)には使えません。またここで触れていないのは、このデータを使う一部非GISアプリケーションで Global ID フィールドを使う非常に説得力のある理由です。これは「試行錯誤」カテゴリーとしておきましょう。ESRI は Global ID のデフォルト実装について非常によい理由があると思いますし、この投稿はきっと熱い議論やコメントを呼ぶでしょう。 <\/P><\/P>これとHey Neighbor? What's Your Value?<\/A> で紹介された after update\insert トリガーを組み合わせると、ほぼすべての属性が自動的に入力され、Global ID が順序付けられたきれいなフィーチャクラスになります。 <\/P><\/P>
<\/P>