2011-04-06 3 views
5

come tutti noi sappiamo, l'entità framework non può contenere dati geografici. Quindi la mia idea era di specificare la longitudine e la latitudine come decimali nel mio modello. Dopo aver eseguito lo script SQL per creare le tabelle, inizierei un altro script per aggiungere una colonna di geografia. Quindi vorrei aggiornare questa colonna su ogni INSERT o UPDATE (su longitudine e latitudine) da un trigger. Il seguente trigger è ok o è qualcosa di brutto? Te lo chiedo perché non ho molta familiarità con il trigger, ma funziona per ora.Trigger per INSERT e UPDATE sulla stessa tabella

 

CREATE TRIGGER Update_Geography 
ON [People] 
FOR INSERT, UPDATE 
AS 
BEGIN 
    DECLARE @longitude DECIMAL(8, 5), @latitude DECIMAL(8, 5) 

    SET @longitude = (SELECT ins.Location_Longitude FROM inserted ins) 
    SET @latitude = (SELECT ins.Location_Latitude FROM inserted ins) 

    IF (@longitude != 0 AND @latitude != 0) 
    BEGIN 
     UPDATE [People] 
     SET 
      Location_Geography = geography::STGeomFromText('POINT(' + CONVERT(VARCHAR(100),@longitude) + ' ' + CONVERT(VARCHAR(100),@latitude) + ')',4326) 
     WHERE 
      Id = (SELECT ins.Id FROM inserted ins) 
    END 
END 
 

Sarebbe felice se qualcuno potesse aiutarmi.

saluti

Edit:

copione sembra che:

 

ALTER TABLE [People] ADD Location_Geography AS (
    CONVERT(GEOGRAPHY, CASE 
     WHEN Location_Latitude 0 AND Location_Longitude 0 THEN 
      geography::STGeomFromText('POINT(' + CONVERT(VARCHAR, Location_Longitude) + ' ' + CONVERT(VARCHAR, Location_Latitude) + ')',4326) 
     ELSE 
      NULL 
    END 
    ) 
) 
 

opere, ma non può interrogare quella colonna:/ Thx

+1

il trigger causerà l'integrità dei dati problemi se qualsiasi processo aggiorna o inserisce una serie di record. Non scrivere mai un trigger assumendo che sia inserito solo un record. – HLGEM

+0

come modificarlo? – john

+0

Vota per questo elemento Connect: http://connect.microsoft.com/SQLServer/feedback/details/378126/how-to-persist-a-calculated-geometry-or-geography-column –

risposta

5

Prova una colonna PERSISTED COMPUTERIZZATA : http://msdn.microsoft.com/en-us/library/ms191250.aspx (potrebbe essere necessario un cast esterno)

Location_Geography AS (
    CASE 
     WHEN Location_Latitude <> 0 AND Location_Longitude <> 0 THEN 
      geography::STGeomFromText('POINT(' + CONVERT(VARCHAR(100),Location_Longitude) + ' ' + CONVERT(VARCHAR(100),Location_Latitude) + ')',4326) 
     ELSE 
     NULL 
    END 
) 

Questo evita di dover fare un trigger con praticamente lo stesso effetto complessivo.

Trigger: http://msdn.microsoft.com/en-us/library/ms191524.aspx

il trigger potrebbe probabilmente essere modificato come:

CREATE TRIGGER Update_Geography 
ON [People] 
FOR INSERT, UPDATE 
AS 
BEGIN 
     UPDATE [People] 
     SET 
      Location_Geography = geography::STGeomFromText('POINT(' + CONVERT(VARCHAR(100),Location_Longitude) + ' ' + CONVERT(VARCHAR(100),Location_Latitude) + ')',4326) 
     WHERE (UPDATE(Location_Longitude) OR UPDATE(Location_Latitude)) 
      AND Id IN (SELECT ins.Id FROM inserted ins) 
    END 
END 

Ecco un esempio che mostra entrambe le colonne manuali e calc'ed:

IF EXISTS (SELECT * 
      FROM sys.objects 
      WHERE object_id = OBJECT_ID(N'[dbo].[SO5572806]') 
        AND type IN (N'U')) 
    DROP TABLE [dbo].[SO5572806] 
GO 

CREATE TABLE SO5572806 
    (
    lo DECIMAL(8, 5) NOT NULL 
    ,la DECIMAL(8, 5) NOT NULL 
    ,man GEOGRAPHY NULL 
    ,calc AS (CONVERT(GEOGRAPHY, CASE WHEN la <> 0 
             AND lo <> 0 
            THEN GEOGRAPHY::STGeomFromText('POINT(' 
                   + CONVERT(VARCHAR, lo) 
                   + ' ' 
                   + CONVERT(VARCHAR, la) 
                   + ')', 4326) 
            ELSE NULL 
           END)) 
    ) 
GO 

INSERT INTO dbo.SO5572806 
     (lo, la) 
VALUES (0, 0), 
     (-90, 30) 

UPDATE dbo.SO5572806 
SET  man = GEOGRAPHY::STGeomFromText('POINT(' + CONVERT(VARCHAR, lo) + ' ' 
             + CONVERT(VARCHAR, la) + ')', 4326) 
WHERE lo <> 0 
     AND la <> 0 

SELECT * 
FROM dbo.SO5572806 
+0

ma cosa succede se la longitudine e la latitudine i cambiamenti? – john

+0

@john Una colonna calcolata persistente verrà ricalcolata ogni volta che una riga viene aggiornata, proprio come un trigger: dai un'occhiata al link della documentazione online. Un trigger può essere più intelligente e non calcolare le cose controllando per vedere se alcune colonne sono cambiate, ma un trigger deve anche assicurarsi che funzioni su tutta la pseudo tabella inserita e non assumendo solo una singola riga. L'unica cosa che potrebbe essere necessario controllare è che la funzione geometrica è deterministica. 'CAST/CONVERT'' VARCHAR' a 'DATETIME' per esempio non è deterministico A MENO CHE sia specificato un formato fisso. –

+0

@cade okay. poi. grazie :) – john