2011-04-06 16 views
5

como todos sabemos, el marco entidad no puede contener datos geográficos. Entonces mi idea era especificar la longitud y la latitud como decimales en mi modelo. Después de ejecutar el script SQL para crear las tablas, comenzaría otro script para agregar una columna de geografía. Entonces me gustaría actualizar esta columna en cada INSERT o UPDATE (en longitud y latitud) mediante un disparador. ¿Está bien el siguiente disparador o es algo malo? Lo estoy preguntando porque no estoy muy familiarizado con el disparador, pero funciona por ahora.Disparador para INSERTAR y ACTUALIZAR en la misma tabla

 

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 
 

sería feliz si alguien me podría ayudar.

Saludos

Editar:

guión parece que:

 

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 
    ) 
) 
 

obras, pero no puede consultar esa columna:/ Thx

+1

Su gatillo provocará integridad de los datos problemas si algún proceso alguna vez actualiza o inserta un lote de registros. Nunca escriba un disparador suponiendo que solo se insertará un registro. – HLGEM

+0

cómo modificarlo? – john

+0

Vote por este artículo de Connect: http://connect.microsoft.com/SQLServer/feedback/details/378126/how-to-persist-a-geometry-geography-or-geography-column –

Respuesta

5

Pruebe una columna PERSISTED COMPUTED : http://msdn.microsoft.com/en-us/library/ms191250.aspx (podría necesitar un modelo externo aquí)

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 
) 

Esto evita tener que hacer un disparador con prácticamente el mismo efecto general.

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

Su gatillo probablemente podría modificarse como:

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 

He aquí un ejemplo que muestra dos columnas manuales y 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

pero qué pasa si la longitud y la latitud cambios? – john

+0

@ john una columna calculada persistente se volverá a calcular cada vez que se actualice una fila, al igual que un desencadenador; eche un vistazo al enlace de Libros en línea. Un desencadenante puede ser más inteligente y no calcular las cosas al verificar si ciertas columnas cambiaron, pero un desencadenante también debe asegurarse de que está operando en toda la pseudo tabla insertada y no supone una sola fila. Lo único que podría necesitar verificar es que la función de geometría es determinista. 'CAST/CONVERT'' VARCHAR' a' DATETIME' por ejemplo no es determinista A MENOS QUE se especifique un formato fijo. –

+0

@cade bien. entonces. gracias :) – john

Cuestiones relacionadas