এসকিউএল সার্ভারে আইপি ঠিকানা সঞ্চয় করার জন্য ডেটাটাইপ


113

এসকিউএল সার্ভারে আইপি ঠিকানা সঞ্চয় করার জন্য আমার কোন ডেটাটাইপ চয়ন করা উচিত?

ডান ডাটাটাইপ নির্বাচন করে আইপি ঠিকানার মাধ্যমে ফিল্টার করা কি এত সহজ হবে?



উত্তর:


130

আইপিভি 4 সংরক্ষণ করার প্রযুক্তিগতভাবে সঠিক উপায় বাইনারি (4), যেহেতু এটি আসলে (না, এমনকি কোনও আইএনটি 32 / আইএনটি (4) নয়), এমন সংখ্যামূলক পাঠ্য ফর্ম যা আমরা সবাই জানি এবং ভালোবাসি (255.255.255.255) ঠিক তাই এর বাইনারি সামগ্রীর প্রদর্শন রূপান্তর)।

আপনি যদি এইভাবে এটি করেন তবে আপনি পাঠ্য-প্রদর্শন বিন্যাসে এবং রূপান্তর করতে ফাংশন চাইবেন:

এখানে পাঠ্য প্রদর্শন ফর্মটিকে বাইনারি রূপান্তর করার উপায় এখানে রয়েছে:

CREATE FUNCTION dbo.fnBinaryIPv4(@ip AS VARCHAR(15)) RETURNS BINARY(4)
AS
BEGIN
    DECLARE @bin AS BINARY(4)

    SELECT @bin = CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))

    RETURN @bin
END
go

এবং এখানে বাইনারিটিকে পাঠ্য প্রদর্শন ফর্মটিতে কীভাবে রূপান্তর করা যায় তা এখানে:

CREATE FUNCTION dbo.fnDisplayIPv4(@ip AS BINARY(4)) RETURNS VARCHAR(15)
AS
BEGIN
    DECLARE @str AS VARCHAR(15) 

    SELECT @str = CAST( CAST( SUBSTRING( @ip, 1, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
                + CAST( CAST( SUBSTRING( @ip, 2, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
                + CAST( CAST( SUBSTRING( @ip, 3, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
                + CAST( CAST( SUBSTRING( @ip, 4, 1) AS INTEGER) AS VARCHAR(3) );

    RETURN @str
END;
go

সেগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে এখানে একটি ডেমো রয়েছে:

SELECT dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

SELECT dbo.fnDisplayIPv4( 0xC04144C9 )
-- should return '192.65.68.201'
go

অবশেষে, অনুসন্ধানগুলি এবং তুলনা করার সময়, আপনি যদি আপনার সূচীগুলি উপার্জন করতে সক্ষম হতে চান তবে সর্বদা বাইনারি ফর্মটি ব্যবহার করুন।


হালনাগাদ:

আমি এসকিউএল সার্ভারে স্কেলার ইউডিএফগুলির অন্তর্নিহিত পারফরম্যান্স সমস্যাগুলি সমাধান করার জন্য একটি উপায় যুক্ত করতে চেয়েছিলাম, তবে এখনও কোনও ফাংশনের কোড-পুনরায় ব্যবহারটি আইটিভিএফ (ইনলাইন টেবিল-মূল্যযুক্ত ফাংশন) ব্যবহার করা। উপরের প্রথম ফাংশনটি (স্ট্রিং থেকে বাইনারি) আইটিভিএফ হিসাবে কীভাবে পুনরায় লেখা যায়:

CREATE FUNCTION dbo.itvfBinaryIPv4(@ip AS VARCHAR(15)) RETURNS TABLE
AS RETURN (
    SELECT CAST(
               CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
            +  CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
            +  CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
            +  CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))
                AS BINARY(4)) As bin
        )
go

উদাহরণস্বরূপ এটি এখানে:

SELECT bin FROM dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

আপনি কীভাবে এটি কোনও INSERT এ ব্যবহার করবেন তা এখানে

INSERT INTo myIpTable
SELECT {other_column_values,...},
       (SELECT bin FROM dbo.itvfBinaryIPv4('192.65.68.201'))

33
আমি মনে করি এটি কেবল একাডেমিক দিক থেকে সঠিক। পোস্টার যে উদ্দেশ্যে এবং ডোমেন সমস্যার সমাধানের চেষ্টা করছে তা না জেনে আমি সন্দেহ করি যে এটি অকারণে ডেটার সাথে ইন্টারঅ্যাক্ট করার জটিলতা তৈরি করবে এবং সম্ভাব্য কার্যক্ষমতা হ্রাস পাবে।
এরিক সাবাইন

21
আইপিভি 4 চারটি বাইটের অর্ডারযুক্ত ক্রম sequ যে IS এটা ডোমেন, এবং স্টোরেজ বিন্যাসে একটি বিন (4) যে। স্টোরেজ ফর্ম্যাটটি পারফরম্যান্সে হস্তক্ষেপ করবে না কারণ এটি সর্বোত্তম বিন্যাস। রূপান্তর ফাংশনটি (কারণ ইউএসএফের এসকিউএল সার্ভারে স্তন্যপান হয়) হতে পারে, যা লাইন দ্বারা বা ক্লায়েন্টে রূপান্তর করে সমাধান করা যেতে পারে। অবশেষে, এই পদ্ধতির উল্লেখযোগ্য সুবিধা রয়েছে যে এটি সূচকযুক্ত পরিসীমা স্ক্যান (যেখানে ip BETWEEN fnBinaryIPv4 ('132.31.55.00') এবং fnBinaryIPv4 ('132.31.55.255')) ব্যবহার করে ক্লাস 1,2, বা 3 সাবনেটওয়ার্কগুলিতে ঠিকানা অনুসন্ধান করতে পারে
আরবেরিইং

1
@ আরবেরি ইউং আমি এটিকে পূর্ণসংখ্যা হিসাবে সঞ্চয় করব। বাইনারি হিসাবে সংরক্ষণ করার পারফরম্যান্স সুবিধা কী তা আপনি ব্যাখ্যা করতে পারেন?
পেসারিয়ার

3
@ পেসারিয়র: ১) উদাহরণের জন্য পূর্ববর্তী মন্তব্য দেখুন এবং ২) আমি দাবি করি নি যে বাইনারি পূর্ণসংখ্যার চেয়ে দ্রুত হবে। আমি দাবি করেছি যে ক) এটি সঠিক ফর্ম্যাট (এবং এটি) এবং খ) এটি ধীর হবে না।
আরবেরি ইয়ং

1
হ্যাঁ, আপনি ভুল, ড্যান যা বলছেন তা তা নয়। এছাড়াও, এটি কোনও আলোচনার ফোরাম নয় এবং এটি এটির পক্ষে উপযুক্ত নয়। স্ট্যাকওভারফ্লো একটি প্রশ্নোত্তর হ'ল আপনার যদি প্রশ্ন থাকে তবে দয়া করে এটি পোস্ট করুন।
RBarryYoung

23

আপনি বার্চার ব্যবহার করতে পারেন। আইপিভি 4 এর দৈর্ঘ্য অচল, তবে আইপিভি 6 এর উচ্চতর পরিবর্তনশীল হতে পারে।

যদি আপনি এটি বাইনারি হিসাবে সংরক্ষণ করার উপযুক্ত কারণ না পান তবে স্ট্রিং (পাঠ্য) প্রকারের সাথে আটকে থাকুন।


39
আইপিভি 6 এর দৈর্ঘ্য খুব স্থির - 128 বিট।
ব্রোম

4
আপনি ডেটা সম্পর্কে কথা না বললে কোনও মানুষ কখনই পড়তে পারে না বা বিপুল পরিমাণে ডেটা না ফেলে, এটি সেরা উত্তর।
অ্যারেন কাম্ব্রে

10
বাইনারি এবং স্ট্রিং না ব্যবহার করার একটি সহজ কারণ: বাইনারি সংস্করণ আইপি অ্যাড্রেসের সংখ্যার পরিসীমা চেক করার অনুমতি দেয় ! পাঠ্য সংস্করণ না। এটি অবশ্যই প্রয়োজনীয় ব্যবহারের উপর নির্ভর করে তবে বাইনারি সংখ্যাগুলি প্রকৃত অর্থ হওয়ায় আরও দরকারী।
কোডিং চলে গেছে

4
ভারচর ডিবিতে উল্লেখযোগ্যভাবে আরও স্থান নেয়। একটি 32-বিট আইপিভি 4 অ্যাড্রেস সংখ্যাতে সংরক্ষণ করতে 4 বাইট নেয় এবং একটি 128-বিট আইপিভি 6 অ্যাড্রেস সংখ্যায় সংরক্ষণ করতে 16 বাইট লাগে। এদিকে, আইপিভি 4 ঠিকানাটি স্ট্রিং হিসাবে সংরক্ষণ করতে 15 বাইট নেয় এবং একটি আইপিভি 6 ঠিকানা স্ট্রিং হিসাবে 39 বাইট পর্যন্ত নিতে পারে।
অ্যারন শুল্টজ

1
ভেরিবিনারি (16) যাওয়ার উপায়
jjxtra

17

এখানে আইপিভি 4 বা আইপিভি 6 বর্ণের ফর্ম্যাটে বাইনারি (16) এবং পিছনে রূপান্তর করতে কিছু কোড রয়েছে। এটি আমি মনে করতে পারি সবচেয়ে ছোট ফর্ম। এটি ভালভাবে সূচী করা উচিত এবং সাবনেটগুলিতে ফিল্টার করার তুলনামূলক সহজ উপায় সরবরাহ করা উচিত। এসকিউএল সার্ভার 2005 বা তার পরে প্রয়োজন। নিশ্চিত নয় এটি সম্পূর্ণ বুলেটপ্রুফ। আশাকরি এটা সাহায্য করবে.

-- SELECT dbo.fn_ConvertIpAddressToBinary('2002:1ff:6c2::1ff:6c2')
-- SELECT dbo.fn_ConvertIpAddressToBinary('10.4.46.2')
-- SELECT dbo.fn_ConvertIpAddressToBinary('bogus')

ALTER FUNCTION dbo.fn_ConvertIpAddressToBinary
(
     @ipAddress VARCHAR(39)
)
RETURNS BINARY(16) AS
BEGIN
DECLARE
     @bytes BINARY(16), @vbytes VARBINARY(16), @vbzone VARBINARY(2)
     , @colIndex TINYINT, @prevColIndex TINYINT, @parts TINYINT, @limit TINYINT
     , @delim CHAR(1), @token VARCHAR(4), @zone VARCHAR(4)

SELECT
     @delim = '.'
     , @prevColIndex = 0
     , @limit = 4
     , @vbytes = 0x
     , @parts = 0
     , @colIndex = CHARINDEX(@delim, @ipAddress)

IF @colIndex = 0
     BEGIN
           SELECT
                @delim = ':'
                , @limit = 8
                , @colIndex = CHARINDEX(@delim, @ipAddress)
           WHILE @colIndex > 0
                SELECT
                      @parts = @parts + 1
                      , @colIndex = CHARINDEX(@delim, @ipAddress, @colIndex + 1)
           SET @colIndex = CHARINDEX(@delim, @ipAddress)

           IF @colIndex = 0
                RETURN NULL     
     END

SET @ipAddress = @ipAddress + @delim

WHILE @colIndex > 0
     BEGIN
           SET @token = SUBSTRING(@ipAddress, @prevColIndex + 1, @Colindex - @prevColIndex - 1)

           IF @delim = ':'
                BEGIN
                      SET  @zone = RIGHT('0000' + @token, 4)

                      SELECT
                           @vbzone = CAST('' AS XML).value('xs:hexBinary(sql:variable("@zone"))', 'varbinary(2)')
                           , @vbytes = @vbytes + @vbzone

                      IF @token = ''
                           WHILE @parts + 1 < @limit
                                 SELECT
                                      @vbytes = @vbytes + @vbzone
                                      , @parts = @parts + 1
                END
           ELSE
                BEGIN
                      SET @zone = SUBSTRING('' + master.sys.fn_varbintohexstr(CAST(@token AS TINYINT)), 3, 2)

                      SELECT
                           @vbzone = CAST('' AS XML).value('xs:hexBinary(sql:variable("@zone"))', 'varbinary(1)')
                           , @vbytes = @vbytes + @vbzone
                END

           SELECT
                @prevColIndex = @colIndex
                , @colIndex = CHARINDEX(@delim, @ipAddress, @colIndex + 1) 
     END            

SET @bytes =
     CASE @delim
           WHEN ':' THEN @vbytes
           ELSE 0x000000000000000000000000 + @vbytes
     END 

RETURN @bytes

END
-- SELECT dbo.fn_ConvertBinaryToIpAddress(0x200201FF06C200000000000001FF06C2)
-- SELECT dbo.fn_ConvertBinaryToIpAddress(0x0000000000000000000000000A0118FF)

ALTER FUNCTION [dbo].[fn_ConvertBinaryToIpAddress]
(
     @bytes BINARY(16)
)
RETURNS VARCHAR(39) AS
BEGIN
DECLARE
     @part VARBINARY(2)
     , @colIndex TINYINT
     , @ipAddress VARCHAR(39)

SET @ipAddress = ''

IF SUBSTRING(@bytes, 1, 12) = 0x000000000000000000000000
     BEGIN
           SET @colIndex = 13
           WHILE @colIndex <= 16
                SELECT
                      @part = SUBSTRING(@bytes, @colIndex, 1)
                      , @ipAddress = @ipAddress
                           + CAST(CAST(@part AS TINYINT) AS VARCHAR(3))
                           + CASE @colIndex WHEN 16 THEN '' ELSE '.' END
                      , @colIndex = @colIndex + 1

           IF @ipAddress = '0.0.0.1'
                SET @ipAddress = '::1'
     END
ELSE
     BEGIN
           SET @colIndex = 1
           WHILE @colIndex <= 16
                BEGIN
                      SET @part = SUBSTRING(@bytes, @colIndex, 2)
                      SELECT
                           @ipAddress = @ipAddress
                                 + CAST('' as xml).value('xs:hexBinary(sql:variable("@part") )', 'varchar(4)')
                                 + CASE @colIndex WHEN 15 THEN '' ELSE ':' END
                           , @colIndex = @colIndex + 2
                END
     END

RETURN @ipAddress   

END 

এই উত্তরটি ডিবি-আইপি আইপি-র জন্য দেশের ডাটাবেসে নির্বিঘ্নে কাজ করেছে। একটি রাউন্ড ট্রিপ রূপান্তর কেবলমাত্র সামান্য পার্থক্য দেখিয়েছিল যেখানে 0 এর ipv6 (অগ্রণী এবং অনুসরণকারী) থেকে ছাঁটাই করা হয়েছিল।
ক্রোকুসেক

1
টোবাইনারি () এ, ক্যোয়ারী প্ল্যান এবং fn_varbintohexstr () ব্যবহারের সাথে কিছু সমস্যা হিট করুন যা ডিটারমিনিস্টিক হিসাবে চিহ্নিত নয়। অন্যের জন্য কেমন '।' বিভাগ: নির্বাচন করুন @ vbzone = রূপান্তর (ভের্বাইনারি (2), রূপান্তর (tinyint, @ টোকেন))? সমান মনে হয়। @ জোন বা এক্সএমএল ইঞ্জিনের দরকার নেই? XML ইঞ্জিনটি ':' থেকেও কোনওভাবে সরিয়ে ফেললে দুর্দান্ত স্পিডআপ বলে মনে হচ্ছে।
ক্রোকুসেক

কনক্যাট_উজ ('।', (আইপিএড্ডার এবং 0xFF000000) >> 24, (আইপিএড্ডার এবং 0xFF0000) >> 16, (আইপিএড্ডার এবং 0xFF00) >> 8, (আইপিএড্ডার এবং 0 এক্সএফএফ) একটি আইপি অ্যাড্রেসযুক্ত স্বাক্ষরযুক্ত দীর্ঘকে রূপান্তর করবে মানব পাঠযোগ্য ফর্ম।
থোকিং 2

@ theking2 - এটি এসকিউএল সার্ভারের ক্ষেত্রে প্রযোজ্য নয় কারণ >> সমর্থিত নয়
অ্যালেক্স

মনে রাখবেন যে এখানে একটি বাগ রয়েছে fn_ConvertIpAddressToBinary। দেখুন C.Plock এর উত্তর এবং খনি
অ্যালেক্স

10

আমি উভয়ই পরিচালনা করতে চাই IPv4এবং IPv6, আমি আইপি ঠিকানা উপস্থাপনাটিকে বাইট এবং বিপরীতে রূপান্তর করতে ব্যবহার করছি VARBINARY(16)এবং নিম্নলিখিত SQL CLRফাংশনগুলি text:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlBytes GetIPAddressBytesFromString (SqlString value)
{
    IPAddress IP;

    if (IPAddress.TryParse(value.Value, out IP))
    {
        return new SqlBytes(IP.GetAddressBytes());
    }
    else
    {
        return new SqlBytes();
    }
}


[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlString GetIPAddressStringFromBytes(SqlBytes value)
{
    string output;

    if (value.IsNull)
    {
        output = "";
    }
    else
    {
        IPAddress IP = new IPAddress(value.Value);
        output = IP.ToString();
    }

    return new SqlString(output);
}

8

.NET ব্যবহারকারী লোকেদের জন্য IPv4 / IPv6 স্ট্রিংটি পার্স করতে এবং এটি হিসাবে সংরক্ষণ করতে আইপিএড্রেস ক্লাস ব্যবহার করতে পারেন VARBINARY(16)byte[]স্ট্রিংতে রূপান্তর করতে একই শ্রেণি ব্যবহার করতে পারেন । VARBINARYএসকিউএল এ রূপান্তর করতে চাইলে :

--SELECT 
--  dbo.varbinaryToIpString(CAST(0x7F000001 AS VARBINARY(4))) IPv4,
--  dbo.varbinaryToIpString(CAST(0x20010DB885A3000000008A2E03707334 AS VARBINARY(16))) IPv6

--ALTER 
CREATE
FUNCTION dbo.varbinaryToIpString
(
    @varbinaryValue VARBINARY(16)
)
RETURNS VARCHAR(39)
AS
BEGIN
    IF @varbinaryValue IS NULL
        RETURN NULL
    IF DATALENGTH(@varbinaryValue) = 4
    BEGIN
        RETURN 
            CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 1, 1))) + '.' +
            CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 2, 1))) + '.' +
            CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 3, 1))) + '.' +
            CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 4, 1)))
    END
    IF DATALENGTH(@varbinaryValue) = 16
    BEGIN
        RETURN 
            sys.fn_varbintohexsubstring(0, @varbinaryValue,  1, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue,  3, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue,  5, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue,  7, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue,  9, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue, 11, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue, 13, 2) + ':' +
            sys.fn_varbintohexsubstring(0, @varbinaryValue, 15, 2)
    END

    RETURN 'Invalid'
END

7

sys.dm_exec_connectionsএসকিউএল সার্ভার 2005 এসপিএর পরে বারচার (48) ব্যবহার করে। আমার কাছে যথেষ্ট ভাল লাগছে বিশেষত যদি আপনি এটি নিজের মানের সাথে তুলনা করে ব্যবহার করতে চান।

বাস্তবে, আপনি কিছুক্ষণের জন্য আইপিভি 6 মূলধারার হিসাবে দেখতে পাবেন না, তাই আমি 4 টি টিনিনেন্ট রুটটি পছন্দ করব। এই বলে যে, আমি বর্ণচর (48) ব্যবহার করছি কারণ আমাকে ব্যবহার করতে হবে sys.dm_exec_connections...

তা না হলে। মার্ক রেডম্যানের উত্তরে পূর্ববর্তী এসও বিতর্ক প্রশ্নের উল্লেখ রয়েছে ।


4
বাস্তবানুগভাবে আমরা হবে দেখা হবে IPv6,
Pacerier

10
বাস্তবিকভাবে আমরা বছরের কিছুক্ষণের জন্য এখনও দেখতে পাব না, কয়েকটি বাইট সংরক্ষণ করতে পাশাপাশি 2-সংখ্যার খেজুরও ব্যবহার করতে পারি। অপেক্ষা কর.
এরিক জে।

1

ধন্যবাদ আরবেরি আমি এক আইপি ব্লক বরাদ্দ সিস্টেম একসাথে রাখছি এবং বাইনারি হিসাবে সংরক্ষণ করার একমাত্র উপায়।

আমি ভার্চার ক্ষেত্রে আইপি ব্লকের সিআইডিআর উপস্থাপনা (উদাহরণ: 192.168.1.0/24) সংরক্ষণ করছি এবং ব্লকের শুরু এবং শেষের বাইনারি ফর্মটি ধরে রাখতে 2 গণনা করা ক্ষেত্র ব্যবহার করছি। সেখান থেকে, আমি প্রদত্ত ব্লকটি ইতিমধ্যে বরাদ্দ করা হয়েছে বা নির্ধারিত মুক্ত কিনা তা দেখার জন্য দ্রুত অনুসন্ধান চালাতে পারি।

আমি আপনার ফাংশনটি সংশোধন করে শেষ আইপি ঠিকানাটি গণনার জন্য করেছি:

CREATE FUNCTION dbo.fnDisplayIPv4End(@block AS VARCHAR(18)) RETURNS BINARY(4)
AS
BEGIN
    DECLARE @bin AS BINARY(4)
    DECLARE @ip AS VARCHAR(15)
    DECLARE @size AS INT

    SELECT @ip = Left(@block, Len(@block)-3)
    SELECT @size = Right(@block, 2)

    SELECT @bin = CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
                + CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))

    SELECT @bin = CAST(@bin + POWER(2, 32-@size) AS BINARY(4))
    RETURN @bin
END;
go

1

আমি সাধারণত একটি আইপিএড্রেস সূক্ষ্ম কাজ করে জন্য একটি সাধারণ প্লেইন VARCHAR ফিল্টারিং ব্যবহার করি।

আপনি যদি আইপি ঠিকানার পরিসরে ফিল্টার করতে চান তবে আমি এটিকে চারটি পূর্ণসংখ্যার মধ্যে বিভক্ত করব।


1
একটি পরিসীমা কি? সমস্ত সাবনেট 8 বাইট নয়। এই হোস্টটি নেটওয়ার্কটির জন্য IP ঠিকানার পরিসর কত: 50.50.50.50/20?
ব্র্যাডলি ক্রাইডার

2
পূর্ণসংখ্যা 0-255 এর মান সঞ্চয় করতে খুব বড়। পরিবর্তে একটি tinyint ব্যবহার করুন।
স্যান্ডরক

0

আমি স্যান্ডরকের কাজগুলি পছন্দ করি। তবে আমি dbo.fn_ConversIpAddressToBinary কোডে একটি ত্রুটি পেয়েছি । আপনি যখন @Delim এর সাথে কনক্যাট করেন তখন @ipAdress VARCHAR (39) এর আগত প্যারামিটারটি খুব কম থাকে small

SET @ipAddress = @ipAddress + @delim

আপনি এটিকে 40 এ বাড়িয়ে দিতে পারেন Or বা এর চেয়েও ভাল নতুন কোনও ভেরিয়েবল ব্যবহার করুন যা অভ্যন্তরীণভাবে ব্যবহার করুন। এইভাবে আপনি শেষ সংখ্যক বড় সংখ্যায় হারাবেন না।

SELECT dbo.fn_ConvertIpAddressToBinary('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')

প্রকৃতপক্ষে একটি বাগ রয়েছে
অ্যালেক্স

0

নিম্নলিখিত প্রশ্নের উত্তর এম টার্নআউট এবং জেরি বার্চ্লারের এই প্রশ্নের উত্তরগুলির ভিত্তিতে তবে নিম্নলিখিত উন্নতিগুলির সাথে:

কোডটি এসকিউএল সার্ভার ২০১৪ এবং এসকিউএল সার্ভার ২০১ 2016 সালে পরীক্ষা করা হয়েছে (শেষে পরীক্ষার কেসগুলি দেখুন)

IPAddressVarbinaryToString

পরিবর্তিত 4 মান বাইট IPV4 প্রয়োজন এবং 16 বাইট মান IPV6 স্ট্রিং উপস্থাপনা। মনে রাখবেন যে এই ফাংশনটি ঠিকানাগুলি ছোট করে না।

ALTER FUNCTION dbo.IPAddressVarbinaryToString
(
    @varbinaryValue VARBINARY( 16 )
)
RETURNS VARCHAR(39)
AS
BEGIN
    IF @varbinaryValue IS NULL
        RETURN NULL;
    ELSE IF DATALENGTH( @varbinaryValue ) = 4
        RETURN 
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 1, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 2, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 3, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 4, 1 )));
    ELSE IF DATALENGTH( @varbinaryValue ) = 16
        RETURN 
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  1, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  3, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  5, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  7, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  9, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 11, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 13, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 15, 2 ), 2 );

    RETURN 'Invalid';
END

পরীক্ষার কেস:

SELECT dbo.IPAddressVarbinaryToString(0x00000000000000000000000000000000) -- 0000:0000:0000:0000:0000:0000:0000:0000 (no address shortening)
SELECT dbo.IPAddressVarbinaryToString(0x00010002000300400500060070000089) -- 0001:0002:0003:0040:0500:0600:7000:0089
SELECT dbo.IPAddressVarbinaryToString(0xC0A80148) -- 255.168.1.72
SELECT dbo.IPAddressVarbinaryToString(0x7F000001) -- 127.0.0.1 (no address shortening)
SELECT dbo.IPAddressVarbinaryToString(NULL) -- NULL

IPAddressStringToVarbinary

আইপিভি 4 এবং আইপিভি 6 স্ট্রিং উপস্থাপনা যথাক্রমে 4 বাইট এবং 16 বাইট বাইনারি মানগুলিতে রূপান্তর করে। নোট করুন যে এই ফাংশনটি শর্টহ্যান্ড ঠিকানার উপস্থাপনাগুলির (যেমন 127 ... 1 এবং 2001: db8 :: 1319: 370: 7348) সর্বাধিক (সাধারণভাবে ব্যবহৃত সমস্ত) পার্স করতে সক্ষম। থিন্স ফাংশনটি সর্বদা 16 বাইট বাইনারি মানগুলি ফাংশনের শেষে 0s কনক্যাটেনশনে নেতৃত্ব দেওয়ার জন্য বাধ্য করতে।

ALTER FUNCTION [dbo].[IPAddressStringToVarbinary]
(
    @IPAddress VARCHAR( 39 )
)
RETURNS VARBINARY(16) AS
BEGIN

IF @ipAddress IS NULL
    RETURN NULL;

DECLARE @bytes VARBINARY(16), @token VARCHAR(4),
    @vbytes VARBINARY(16) = 0x, @vbzone VARBINARY(2),
    @tIPAddress VARCHAR( 40 ),
    @colIndex TINYINT,
    @delim CHAR(1) = '.',
    @prevColIndex TINYINT = 0,
    @parts TINYINT = 0, @limit TINYINT = 4;

-- Get position if IPV4 delimiter
SET @colIndex = CHARINDEX( @delim, @ipAddress );

-- If not IPV4, then assume IPV6
IF @colIndex = 0
BEGIN
    SELECT @delim = ':', @limit = 8, @colIndex = CHARINDEX( @delim, @ipAddress );

    -- Get number of parts (delimiters)
    WHILE @colIndex > 0
        SELECT @parts += 1, @colIndex = CHARINDEX( @delim, @ipAddress, @colIndex + 1 );

    SET @colIndex = CHARINDEX( @delim, @ipAddress );

    IF @colIndex = 0
        RETURN NULL;
END

-- Add trailing delimiter (need new variable of larger size)
SET @tIPAddress = @IPAddress + @delim;

WHILE @colIndex > 0
BEGIN
    SET @token = SUBSTRING( @tIPAddress, @prevColIndex + 1, @Colindex - @prevColIndex - 1 );

    IF @delim = ':'
    BEGIN
        SELECT @vbzone = CONVERT( VARBINARY(2), RIGHT( '0000' + @token, 4 ), 2 ), @vbytes += @vbzone;

        -- Handles consecutive sections of zeros representation rule (i.e. ::)(https://en.wikipedia.org/wiki/IPv6#Address_representation)
        IF @token = ''
            WHILE @parts + 1 < @limit
                SELECT @vbytes += @vbzone, @parts += 1;
    END
    ELSE
    BEGIN
        SELECT @vbzone = CONVERT( VARBINARY(1), CONVERT( TINYINT, @token )), @vbytes += @vbzone
    END

    SELECT @prevColIndex = @colIndex, @colIndex = CHARINDEX( @delim, @tIPAddress, @colIndex + 1 ) 
END

SET @bytes =
    CASE @delim
        WHEN ':' THEN @vbytes
        ELSE /*0x000000000000000000000000 +*/ @vbytes -- Return IPV4 addresses as 4 byte binary (uncomment leading 0s section to force 16 byte binary)
    END 

RETURN @bytes

END

পরীক্ষার কেস

বৈধ মামলা

SELECT dbo.IPAddressStringToVarbinary( '0000:0000:0000:0000:0000:0000:0000:0001' ) -- 0x0000000000000000000000000001 (check bug fix)
SELECT dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' ) -- 0x00010002000300400500060070000089
SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' )     -- 0x20010DB885A308D31319000003707348 (check short hand)
SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319:0000:370:7348' ) -- 0x20010DB885A308D31319000003707348
SELECT dbo.IPAddressStringToVarbinary( '192.168.1.72' ) -- 0xC0A80148
SELECT dbo.IPAddressStringToVarbinary( '127...1' ) -- 0x7F000001 (check short hand)
SELECT dbo.IPAddressStringToVarbinary( NULL ) -- NULL
SELECT dbo.IPAddressStringToVarbinary( '' ) -- NULL
-- Check that conversions return original address
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' )) -- '0001:0002:0003:0040:0500:0600:7000:0089' 
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127...1' )) -- 127.0.0.1
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '192.168.1.72' )) -- 192.168.1.72
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' ))     -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1314:0000:370:7348' )) -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3::370:7348' )) -- 2001:0DB8:85A3:08D3:0000:0000:0370:7348
-- This is technically an invalid IPV6 (according to Wikipedia) but it parses correctly
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::370:7348' )) -- 2001:0DB8:0000:0000:1319:0000:0370:7348

অবৈধ মামলা

SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::7348' )) -- 2001:0DB8:0000:0000:0000:1319:0000:7348 (ambiguous address)
SELECT dbo.IPAddressStringToVarbinary( '127.1' ) -- 127.0.0.1 (not supported short-hand)
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127.1' )) -- 127.0.0.1 (not supported short-hand)
SELECT dbo.IPAddressStringToVarbinary( '0300.0000.0002.0353' ) -- octal byte values
SELECT dbo.IPAddressStringToVarbinary( '0xC0.0x00.0x02.0xEB' ) -- hex values
SELECT dbo.IPAddressStringToVarbinary( 'C0.00.02.EB' ) -- hex values

-2

আমি varchar(15)এখনও অবধি ব্যবহার করছি আমার জন্য কাজ করছে। Sertোকান, আপডেট করুন, নির্বাচন করুন। আমি সবেমাত্র একটি অ্যাপ্লিকেশন শুরু করেছি যার আইপি অ্যাড্রেস রয়েছে, যদিও আমি এখনও খুব বেশি দেব কাজ করে নি।

এখানে নির্বাচনী বিবৃতি দেওয়া হল:

select * From dbo.Server 
where  [IP] = ('132.46.151.181')
Go
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.