Trabalhando com dados geográficos no SQL Server

Por mais que não seja muito comum a utilização de dados geográficos dentro do SQL Server o tipo de dados GEOGRAPHY está disponível desde a versão 2008 no SQL Server.

Para quem ainda não utilizou este recurso vou mostrar um rápido exemplo desde a criação da tabela, inserção de dados e a utilização de uma função específica para calcular a distância entre dois pontos em linha reta.

Vamos primeiramente criar a tabela.

Observem que estamos criando um campo coords do tipo GEOGRAPHY aonde irão ficar armazenadas as coordenadas propriamente ditas. O campo place será uma coluna computada utilizando a função STAsText() para retornar as coordenadas armazenadas em coords em um formato legível.


CREATE TABLE [pocGeography] (
id BIGINT IDENTITY,
name VARCHAR(1000),
coords GEOGRAPHY,
place AS coords.STAsText() );

Agora vamos para a inserção dos dados. Notem a utilização da função Point() que representa um ponto a partir das coordenadas [Latitude, Longitude] fornecidas e da função STGeomFromText() que transforma as coordenadas legíveis em um formato apto para armazenamento em um tipo de dados geográfico no SQL Server.


INSERT INTO [dbo].[pocGeography] ([name],[coords])
VALUES ('Sapiranga', geography::STGeomFromText('POINT(29.6353861 051.0069556)', 4326));
INSERT INTO [dbo].[pocGeography] ([name],[coords])
VALUES ('Porto Alegre', geography::STGeomFromText('POINT(30.0348417 051.2386778)', 4326));

Agora vamos utilizar a função STDistance() para calcular a distância entre dois pontos em linha reta.


DECLARE @src GEOGRAPHY;
DECLARE @dst GEOGRAPHY;
SET @src = (select coords from [dbo].[pocGeography] where id=2)
SET @dst = (select coords from [dbo].[pocGeography] where id=1)
--SELECT @src.STDistance(@dst)/1609.344 --Miles
SELECT @src.STDistance(@dst)/1000 --Kilometers

Resultado:

Screen Shot 2016-06-18 at 4.44.00 AM

Existem muitas outras funções, métodos e funcionalidades para trabalharmos com dados geográficos no SQL Server. Se quiserem conferir alguns métodos existentes deem uma olhada na documentação da MSDN no link abaixo:

https://msdn.microsoft.com/en-us/library/bb933802.aspx

É isso galera! Espero que tenham gostado!

Referências:

Atualizando uma coluna IDENTITY

Galera,

Recebi uma dúvida hoje: “É possível atualizar uma coluna IDENTITY de um registro específico?”
Respondendo: a atualização direta com a utilização do comando UPDATE não é permitida. Mas, se você realmente precisa realizar este procedimento por algum motivo específico, há uma solução de contorno bem simples.

Primeiro vamos criar o cenário para realizarmos o procedimento.

  • Criação da tabela:

Captura de Tela 2016-01-14 às 20.41.20

  • Adição de registros:

Captura de Tela 2016-01-14 às 20.41.25

  • Consulta:

Captura de Tela 2016-01-14 às 20.42.26

Agora vamos fazer uma tentativa de atualização da coluna id criada como IDENTITY na tabela TesteIdentity:

Captura de Tela 2016-01-14 às 20.45.47
Como podemos ver, ocorreu o erro 8102 “Cannot update identity column ‘id'”, pois não é possível atualizarmos diretamente um campo com a propriedade IDENTITY.
Para resolvermos este problema vamos precisar apenas de dois passos:

  1. Deletar o registro que queremos atualizar (Não se esqueça de fazer backup da sua tabela);
  2. Inserir o registro novamente com o seu novo valor para a coluna ID utilizando a cláusula SET IDENTITY_INSERT [nomeTabela] ON.

Agora que já sabemos a solução, vamos tentar atualizar o mesmo registro do cenário criado anteriormente utilizando os passos acima.

  • Vamos excluir o registro com o valor de id = 1:

Captura de Tela 2016-01-14 às 20.46.24

  • E por último vamos inserir o registro com o seu novo valor para a coluna id utilizando a cláusula SET IDENTITY_INSERT [nomeTabela] ON:

Captura de Tela 2016-01-14 às 20.47.23

O resultado é a “atualização” do id = 1 para id = 20, conforme abaixo:

Captura de Tela 2016-01-15 às 01.43.38

  • Se esquecermos de utilizar a cláusula SET IDENTITY_INSERT [nomeTabela] ON, o SQL Server irá retornar o erro 544 “Cannot insert explicit value for identity column in table ‘TesteIdentity’ when IDENTITY_INSERT is set to OFF“:

Captura de Tela 2016-01-15 às 01.35.58

IMPORTANTE:

  • Nunca se esqueça de retornar a cláusula IDENTITY_INSERT para OFF, pois o SQL Server permite que apenas uma tabela por vez utilize esta opção. Caso esqueça de desligar esta propriedade para uma tabela e tente ativar para uma segunda tabela o SQL Server irá retornar o erro abaixo:Captura de Tela 2016-01-15 às 01.43.07
  • Se o valor inserido for maior que a IDENTITY atual da tabela, automaticamente o SQL Server irá alterar o IDENTITY para o valor inserido, como podemos ver na imagem abaixo ao inserir um novo valor após termos inserido o valor com a cláusula SET IDENTITY_INSERT ON:

Captura de Tela 2016-01-15 às 01.49.38

Captura de Tela 2016-01-15 às 01.50.01

  • Se for necessário visualizar ou alterar o valor atual da IDENTITY podemos utilizar o comando DBCC CHECKIDENT. No nosso caso vamos primeiramente conferir o valor atual da IDENTITY, alterá-lo para 30 e por último inserir um novo registro na tabela.

Conferindo o valor atual da IDENTITY. Notem que o valor atual é 21.

Captura de Tela 2016-01-15 às 02.01.38

Alterando o valor da IDENTITY para 30:

Captura de Tela 2016-01-15 às 02.02.06

Conferindo novamente o valor atual da IDENTITY. Notem que agora o valor atual foi alterado para 30, conforme comando executado anteriormente. O valor 21 que ainda permanece é referente ao valor máximo da coluna IDENTITY existente na tabela:

Captura de Tela 2016-01-15 às 02.02.20

Inserindo um novo registro na tabela TesteIdentity:

Captura de Tela 2016-01-15 às 02.02.43

Como podemos ver após alterarmos o valor da IDENTITY para 30, o próximo valor inserido foi o 31, conforme evidência abaixo:

Captura de Tela 2016-01-15 às 02.03.28

Por hoje é isso galera! Se tiverem dúvidas, críticas ou sugestões de assuntos podem enviar pelos comentários ou até mesmo por e-mail: felipe@lauffer.me

Obrigado!