Ordenar campo texto como numérico.

02/05/2005

0

Tenho uma tabela que armazena endereços IP e preciso ordená-las pelos mesmos. Entretanto isso causa um grande problema, pois os valores ficam ordenados à partir do código alfabético do caracter e não do valore real, por exemplo:

172.16.0.10 <<======
172.16.0.100
172.16.0.101
172.16.0.102
172.16.0.11 <<======
172.16.0.110
172.16.0.111

Há alguma maneira de efetuar esta ordem de maneira coerente ? Tentei utilizar ORDER BY CAST(IP AS Numeric) mas não funciona devido aos pontos. Tentei também desmontar o IP utilizando SUBSTRING e CHARINDEX mas ficou muito complicado por causa tmb dos pontos.


Rc.salvador

Rc.salvador

Responder

Posts

02/05/2005

Gandalf.nho

Enquanto permanecer como texto ele irá ordenar alfabeticamente e não numericamente, a menos que todos os IPs tenham o mesmo tamanho e os pontos nos mesmos lugares (o que não dá)


Responder

27/11/2006

Tinorj

Uma solução seria armazenar cada numero separado e fazer um campo calculado exibindo o IP já concatenado com os pontos, mas não sei qual seria esse custo para sua situação.

Abaixo segue um exemplo.

use Northwind

GO

if exists (select * from dbo.sysobjects where id = object_id(N´[dbo].[IPs]´) and OBJECTPROPERTY(id, N´IsUserTable´) = 1)
drop table [dbo].[IPs]
GO

CREATE TABLE [dbo].[IPs] (
[PARTE1] [int] NULL ,
[PARTE2] [int] NULL ,
[PARTE3] [int] NULL ,
[PARTE4] [int] NULL ,
[IP] AS (CONVERT(varchar(3),[PARTE1]) + ´.´ + CONVERT(varchar(3),[PARTE2]) + ´.´ + CONVERT(varchar(3),[PARTE3]) + ´.´ + CONVERT(varchar(3),[PARTE4]))
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[IPs] ADD 
CONSTRAINT [DF_IPs_PARTE1] DEFAULT (0) FOR [PARTE1],
CONSTRAINT [DF_IPs_PARTE2] DEFAULT (0) FOR [PARTE2],
CONSTRAINT [DF_IPs_PARTE3] DEFAULT (0) FOR [PARTE3],
CONSTRAINT [DF_IPs_PARTE4] DEFAULT (0) FOR [PARTE4],
CONSTRAINT [CK_IP_PARTE1] CHECK ([PARTE1] >= 0 and [PARTE1] < 255),
CONSTRAINT [CK_IP_PARTE2] CHECK ([PARTE2] >= 0 and [PARTE2] < 255),
CONSTRAINT [CK_IP_PARTE3] CHECK ([PARTE3] >= 0 and [PARTE3] < 255),
CONSTRAINT [CK_IP_PARTE4] CHECK ([PARTE4] >= 0 and [PARTE4] < 255)
GO


GO

INSERT INTO IPs VALUES (172,16,0,10)
INSERT INTO IPs VALUES (172,16,0,100)
INSERT INTO IPs VALUES (172,16,0,101)
INSERT INTO IPs VALUES (172,16,0,102)
INSERT INTO IPs VALUES (172,16,0,11)
INSERT INTO IPs VALUES (172,16,0,110)
INSERT INTO IPs VALUES (172,16,0,111)

GO

SELECT IP FROM IPs
ORDER BY PARTE1, PARTE2, PARTE3, PARTE4  




Responder

03/12/2006

Psergio.p

Minha sugestão é a seguinte:

Criar uma UDF para retornar as partes do IP, veja abaixo o exemplo:

CREATE FUNCTION UDF_GETIP(@ENDERECO_IP VARCHAR(15),@PARTE INT)
RETURNS INT
AS
BEGIN
DECLARE @PARTE01 INT
DECLARE @PARTE02 INT
DECLARE @PARTE03 INT
DECLARE @PARTE04 INT
DECLARE @POSICAO INT

SET @POSICAO = CHARINDEX(´.´,@ENDERECO_IP)
SET @PARTE01 = SUBSTRING(@ENDERECO_IP,1,@POSICAO - 1)
SET @ENDERECO_IP = SUBSTRING(@ENDERECO_IP,@POSICAO + 1, LEN(@ENDERECO_IP))

SET @POSICAO = CHARINDEX(´.´,@ENDERECO_IP)
SET @PARTE02 = SUBSTRING(@ENDERECO_IP,1,@POSICAO - 1)
SET @ENDERECO_IP = SUBSTRING(@ENDERECO_IP,@POSICAO + 1, LEN(@ENDERECO_IP))

SET @POSICAO = CHARINDEX(´.´,@ENDERECO_IP)
SET @PARTE03 = SUBSTRING(@ENDERECO_IP,1,@POSICAO - 1)
SET @ENDERECO_IP = SUBSTRING(@ENDERECO_IP,@POSICAO + 1, LEN(@ENDERECO_IP))

SET @PARTE04 = SUBSTRING(@ENDERECO_IP,1,@POSICAO - 1)

IF @PARTE = 1 BEGIN
RETURN(@PARTE01)
END
IF @PARTE = 2 BEGIN
RETURN(@PARTE02)
END
IF @PARTE = 3 BEGIN
RETURN(@PARTE03)
END
IF @PARTE = 4 BEGIN
RETURN(@PARTE04)
END
RETURN 0
END



Depois veja como usar a função e order os valores:

SELECT IP FROM(
SELECT *,DBO.UDF_GETIP(IP,1) AS IP1,DBO.UDF_GETIP(IP,2) AS IP2,DBO.UDF_GETIP(IP,3) AS IP3,
DBO.UDF_GETIP(IP,4) AS IP4 FROM EnderecoIP) AS SQ
ORDER BY IP1,IP2,IP3,IP4



Espero que ajude, me dá um feedback depois!

[]
Paulo


Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar