2010-07-28 9 views
6

SQL üzerinde çalışıyorum ve bu kodun düzgün bir şekilde yazıldığını veya daha iyi bir şekilde yapılıp yapılmadığını görmek için tavsiyenizi istiyorum. Bu komut dosyası oluşturun:SQL Komut Dosyası - Bir IP'nin listelenip listelenmediğini kontrol edin

  • bir tablo 4 sayı grubuna
  • kontrol etmesine izin vermek bir SPROC bir IP adresi tükürme izin Siyah

  • bir sproc Kote Edildiği IP'ler adresini saklamak için bir IP Siyah ise Listelenen veya değil Lütfen bana bildirin! Teşekkürler!

    -- Black Listed Table 
    CREATE TABLE UtlBlacklistedIPs 
         ( 
          octet1 TINYINT, 
          octet2 TINYINT, 
          octet3 TINYINT, 
          octet4 TINYINT 
         ); 
    

1 SPROC

-- Convert an IP address in 4 octet for db storing 
    CREATE PROCEDURE dbo.storeIPoctetsv1 
    @ip CHAR(15) 
    AS 
    BEGIN 
    SET NOCOUNT ON 
    INSERT UtlBlacklistedIPs(octet1, octet2, octet3, octet4) 
    SELECT 
    CONVERT(TINYINT, PARSENAME(@ip, 4)), 
    CONVERT(TINYINT, PARSENAME(@ip, 3)), 
    CONVERT(TINYINT, PARSENAME(@ip, 2)), 
    CONVERT(TINYINT, PARSENAME(@ip, 1)) 
    END 

2 SPROC

-- SPROC check if an IP address has been black listed 
CREATE PROCEDURE dbo.sprocCheckIp 
    @ip CHAR(15) 
    AS 
    BEGIN 
    SET NOCOUNT ON 
    DECLARE 
    @octet1 tinyint, 
    @octet2 tinyint, 
    @octet3 tinyint, 
    @octet4 tinyint; 

    SET @octet1 = CONVERT(tinyint, PARSENAME(@ip, 4)); 
    SET @octet2 = CONVERT(tinyint, PARSENAME(@ip, 3)); 
    SET @octet3 = CONVERT(tinyint, PARSENAME(@ip, 2)); 
    SET @octet4 = CONVERT(tinyint, PARSENAME(@ip, 1)); 

    IF EXISTS ( 
     SELECT octet1, octet2, octet3, octet4 
     FROM UtlBlacklistedIPs 
     WHERE 
     octet1 [email protected] 
     AND octet2 [email protected] 
     AND octet3 [email protected] 
     AND octet4 [email protected] 
    ) 
     BEGIN 
     PRINT 'Ip: '[email protected]+' is black listed' 
     END 

     ELSE 
     BEGIN  
     PRINT 'Ip: '[email protected]+' is NOT black listed' 
     END  
    END 

bazı değerler

-- Insert dummy values 
DECLARE @i INT 
SET @i = 0 
WHILE @i < 2000 
BEGIN 

    EXEC dbo.storeIPoctetsv1 @ip = '204.71.34.21' 
    EXEC dbo.storeIPoctetsv1 @ip = '12.38.145.32' 
    EXEC dbo.storeIPoctetsv1 @ip = '127.0.0.1' 

    SET @i = @i + 1 
END 

kullanımı SPROC

-- Use SPROc 
    EXEC dbo.sprocCheckIp '125.254.125.111' -- NOT black listed Ip 
    EXEC dbo.sprocCheckIp '204.71.34.21' -- black listed Ip 
+0

+1 'PARSENAME' –

+0

'un ilgi çekici kullanımı için bir ipv4 adresini int olarak kaydedin (çünkü işte bu olduğu gibi). 4 parçalı noktalı gösterim sadece bir temsildir. –

cevap

3

Veritabanının dışında bunu muhtemelen .NET'te kullanacağınızı farz ediyorum. Bu durumda, yeniden yapıya olur böyle:

  • sproc dört girdi olarak oktet ve 0 ya da 1 ile, herhangi bir IP kontrol etmek için, giriş olarak dört oktet ile
  • sproc siyah listelenen IP depolamak çıktı olarak (RETURN, değil PRINT)
  • Bunun yerine .NET'te IP adreslerinin bölünmesini yapın. SQL Server çok zayıf bir dize işlemeye sahiptir, bu yüzden bir Ip sınıfını, sizin için işleyen statik bir yöntem olan int[] ToOctets(string ip) ile yazmaktan çok daha iyisiniz. Bunu şöyle kullanırsınız: var octs = Ip.ToOctets("213.82.158.93")
  • Bir IP'nin kara listeye alınmış olup olmadığını kontrol ettiğinizde, ExecuteScalar'ı çağırırsınız (veya saklı yordamdan skaler değer elde etmek için kullandığınız yöntem, tercih ettiğiniz bağlaçla aranabilir)) sonuca ulaşmak için.
+0

Teşekkürler Tomas, tavsiyelerinizi takdir ediyorum! – GibboK

1

Thomas ile aynı fikirdeyim ancak bir sorum var: IP'yi neden 4 ayrı sütunda saklıyorsunuz? Eğer egzersizin bütün noktası "kara listeye alınmış IP adreslerini" takip etmekteyse, o zaman ne zaman IP adresinin bir parçasını incelemeniz gerekecekti - her zaman her şeye bakmıyor muydunuz? Böylece bölmeleri ayırmak/yeniden birleştirmek gereksiz görünüyor. Çok fazla fazla T-SQL yazmanıza da neden oluyor.

+0

4 octet kullanılarak kaydedilmiş minint kaydedilmiş db'de yer kaplıyorsunuz, bunun yerine ift'ini saklamak için eşsiz bir char (15) kullanıyorsunuz 15 bit veri türü ile bitecek – GibboK

+2

Testini buldum (referans olarak kullandığınızı düşünüyorum)) yaklaşık 10 yıl önce, küçük int, int & char (http://sqlserver2000.databases.aspfaq.com/how-should-i-store-an-ip-address-in-sql-server.html) karşılaştırması yaptım. merak etmek gerekirse - 2000 db olması, daha modern bir veritabanı (SQL-2005 veya 2008, vb.) ile devam etmek yerine char yerine varchar, int yerine smallint veya mevcut olan diğer iyileştirmelerden yararlanmaya değer 2000'den beri. – dave

İlgili konular