Sql 如何读取IPv6地址,以完全扩展的表示法格式化,然后转换为二进制?
我正在使用SQLServer2005 我试图找出如何读取存储为字符串的IPv6地址,然后将其扩展为完整的8个八位字节表示法,并将每个八位字节转换为二进制,然后将所有二进制表示形式添加到一起,最终将地址转换为二进制 以下是完整的符号: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 与存储在数据库中相同的简短符号: 2001:0db8:85a3::8a2e:0370:7334 以下是另一个有效IPv6地址的示例: ::1 WikMedia在这里很好地阐述和解释了这些规则: 我不知道如何将IPv6地址扩展到完整的表示法,希望这里的人已经知道或者知道如何实现。我在谷歌上搜索了几个小时,但找不到SQL server 2005的任何解决方案 扩展地址后,我考虑根据:拆分每个八位字节,并使用此处概述的方法转换为二进制: 非常感谢任何帮助 样本表:Sql 如何读取IPv6地址,以完全扩展的表示法格式化,然后转换为二进制?,sql,sql-server,sql-server-2005,ipv6,Sql,Sql Server,Sql Server 2005,Ipv6,我正在使用SQLServer2005 我试图找出如何读取存储为字符串的IPv6地址,然后将其扩展为完整的8个八位字节表示法,并将每个八位字节转换为二进制,然后将所有二进制表示形式添加到一起,最终将地址转换为二进制 以下是完整的符号: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 与存储在数据库中相同的简短符号: 2001:0db8:85a3::8a2e:0370:7334 以下是另一个有效IPv6地址的示例: ::1 WikMedia在这里很好地阐述和解释了这些
select '2001:0db8:85a3:0000:0000:8a2e:0370:7334' address
into ipv6
union all
select '2001:db8:85a3::8a2e:0370:7334' union all
select '2001:0db8:85a3::' union all
select '::ff01:0db8:85a3' union all
select '::1' union all
select '002::' union all
select '::' union all
select '1:2:3:4:5:6:7:' union all
select ':A:2:3:4:5:6:7' union all
select 'F:2:3:4:5:6::8' union all
select '' union all -- invalid
select null; -- null test
with step1(address,full8) as(
select address,
replace(nullif(address,''),'::',replicate(':',9-len(address)+len(replace(address,':',''))))
from ipv6
), step2(address,full8,xml) as (
select address, full8,
cast('<x>'+replace(full8,':','</x><x>')+'</x>' as xml)
from step1
), step3(address,full8,xml,part,pos) as (
select address, full8,xml,
right('0000'+part.value('.','varchar(4)'),4),
part.value('for $s in . return count(../*[. << $s]) + 1', 'int') pos
from step2
cross apply xml.nodes('x') node(part)
), step4(address,hex) as (
select o.address, (select i.part+''
from step3 i
where i.address=o.address
order by i.pos
for xml path('')) hex
from step3 o
group by address
)
select address,
hex,
cast('' as xml).value(
'xs:hexBinary(sql:column("hex"))','binary(16)') bin
from step4
order by address;
| ADDRESS | HEX | BIN |
----------------------------------------------------------------------------------------------------------------------------------
| :: | 00000000000000000000000000000000 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| ::1 | 00000000000000000000000000000001 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
| ::ff01:0db8:85a3 | 00000000000000000000ff010db885a3 | 0,0,0,0,0,0,0,0,0,0,-1,1,13,-72,-123,-93 |
| :A:2:3:4:5:6:7 | 0000000A000200030004000500060007 | 0,0,0,10,0,2,0,3,0,4,0,5,0,6,0,7 |
| 002:: | 00020000000000000000000000000000 | 0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| 1:2:3:4:5:6:7: | 00010002000300040005000600070000 | 0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,0 |
| 2001:0db8:85a3:: | 20010db885a300000000000000000000 | 32,1,13,-72,-123,-93,0,0,0,0,0,0,0,0,0,0 |
| 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| 2001:db8:85a3::8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| F:2:3:4:5:6::8 | 000F0002000300040005000600000008 | 0,15,0,2,0,3,0,4,0,5,0,6,0,0,0,8 |
查询:
select '2001:0db8:85a3:0000:0000:8a2e:0370:7334' address
into ipv6
union all
select '2001:db8:85a3::8a2e:0370:7334' union all
select '2001:0db8:85a3::' union all
select '::ff01:0db8:85a3' union all
select '::1' union all
select '002::' union all
select '::' union all
select '1:2:3:4:5:6:7:' union all
select ':A:2:3:4:5:6:7' union all
select 'F:2:3:4:5:6::8' union all
select '' union all -- invalid
select null; -- null test
with step1(address,full8) as(
select address,
replace(nullif(address,''),'::',replicate(':',9-len(address)+len(replace(address,':',''))))
from ipv6
), step2(address,full8,xml) as (
select address, full8,
cast('<x>'+replace(full8,':','</x><x>')+'</x>' as xml)
from step1
), step3(address,full8,xml,part,pos) as (
select address, full8,xml,
right('0000'+part.value('.','varchar(4)'),4),
part.value('for $s in . return count(../*[. << $s]) + 1', 'int') pos
from step2
cross apply xml.nodes('x') node(part)
), step4(address,hex) as (
select o.address, (select i.part+''
from step3 i
where i.address=o.address
order by i.pos
for xml path('')) hex
from step3 o
group by address
)
select address,
hex,
cast('' as xml).value(
'xs:hexBinary(sql:column("hex"))','binary(16)') bin
from step4
order by address;
| ADDRESS | HEX | BIN |
----------------------------------------------------------------------------------------------------------------------------------
| :: | 00000000000000000000000000000000 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| ::1 | 00000000000000000000000000000001 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
| ::ff01:0db8:85a3 | 00000000000000000000ff010db885a3 | 0,0,0,0,0,0,0,0,0,0,-1,1,13,-72,-123,-93 |
| :A:2:3:4:5:6:7 | 0000000A000200030004000500060007 | 0,0,0,10,0,2,0,3,0,4,0,5,0,6,0,7 |
| 002:: | 00020000000000000000000000000000 | 0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| 1:2:3:4:5:6:7: | 00010002000300040005000600070000 | 0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,0 |
| 2001:0db8:85a3:: | 20010db885a300000000000000000000 | 32,1,13,-72,-123,-93,0,0,0,0,0,0,0,0,0,0 |
| 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| 2001:db8:85a3::8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| F:2:3:4:5:6::8 | 000F0002000300040005000600000008 | 0,15,0,2,0,3,0,4,0,5,0,6,0,0,0,8 |
注意:SQL FIDLE不能很好地显示二进制数据…
样本表:
select '2001:0db8:85a3:0000:0000:8a2e:0370:7334' address
into ipv6
union all
select '2001:db8:85a3::8a2e:0370:7334' union all
select '2001:0db8:85a3::' union all
select '::ff01:0db8:85a3' union all
select '::1' union all
select '002::' union all
select '::' union all
select '1:2:3:4:5:6:7:' union all
select ':A:2:3:4:5:6:7' union all
select 'F:2:3:4:5:6::8' union all
select '' union all -- invalid
select null; -- null test
with step1(address,full8) as(
select address,
replace(nullif(address,''),'::',replicate(':',9-len(address)+len(replace(address,':',''))))
from ipv6
), step2(address,full8,xml) as (
select address, full8,
cast('<x>'+replace(full8,':','</x><x>')+'</x>' as xml)
from step1
), step3(address,full8,xml,part,pos) as (
select address, full8,xml,
right('0000'+part.value('.','varchar(4)'),4),
part.value('for $s in . return count(../*[. << $s]) + 1', 'int') pos
from step2
cross apply xml.nodes('x') node(part)
), step4(address,hex) as (
select o.address, (select i.part+''
from step3 i
where i.address=o.address
order by i.pos
for xml path('')) hex
from step3 o
group by address
)
select address,
hex,
cast('' as xml).value(
'xs:hexBinary(sql:column("hex"))','binary(16)') bin
from step4
order by address;
| ADDRESS | HEX | BIN |
----------------------------------------------------------------------------------------------------------------------------------
| :: | 00000000000000000000000000000000 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| ::1 | 00000000000000000000000000000001 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
| ::ff01:0db8:85a3 | 00000000000000000000ff010db885a3 | 0,0,0,0,0,0,0,0,0,0,-1,1,13,-72,-123,-93 |
| :A:2:3:4:5:6:7 | 0000000A000200030004000500060007 | 0,0,0,10,0,2,0,3,0,4,0,5,0,6,0,7 |
| 002:: | 00020000000000000000000000000000 | 0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| 1:2:3:4:5:6:7: | 00010002000300040005000600070000 | 0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,0 |
| 2001:0db8:85a3:: | 20010db885a300000000000000000000 | 32,1,13,-72,-123,-93,0,0,0,0,0,0,0,0,0,0 |
| 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| 2001:db8:85a3::8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| F:2:3:4:5:6::8 | 000F0002000300040005000600000008 | 0,15,0,2,0,3,0,4,0,5,0,6,0,0,0,8 |
查询:
select '2001:0db8:85a3:0000:0000:8a2e:0370:7334' address
into ipv6
union all
select '2001:db8:85a3::8a2e:0370:7334' union all
select '2001:0db8:85a3::' union all
select '::ff01:0db8:85a3' union all
select '::1' union all
select '002::' union all
select '::' union all
select '1:2:3:4:5:6:7:' union all
select ':A:2:3:4:5:6:7' union all
select 'F:2:3:4:5:6::8' union all
select '' union all -- invalid
select null; -- null test
with step1(address,full8) as(
select address,
replace(nullif(address,''),'::',replicate(':',9-len(address)+len(replace(address,':',''))))
from ipv6
), step2(address,full8,xml) as (
select address, full8,
cast('<x>'+replace(full8,':','</x><x>')+'</x>' as xml)
from step1
), step3(address,full8,xml,part,pos) as (
select address, full8,xml,
right('0000'+part.value('.','varchar(4)'),4),
part.value('for $s in . return count(../*[. << $s]) + 1', 'int') pos
from step2
cross apply xml.nodes('x') node(part)
), step4(address,hex) as (
select o.address, (select i.part+''
from step3 i
where i.address=o.address
order by i.pos
for xml path('')) hex
from step3 o
group by address
)
select address,
hex,
cast('' as xml).value(
'xs:hexBinary(sql:column("hex"))','binary(16)') bin
from step4
order by address;
| ADDRESS | HEX | BIN |
----------------------------------------------------------------------------------------------------------------------------------
| :: | 00000000000000000000000000000000 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| ::1 | 00000000000000000000000000000001 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 |
| ::ff01:0db8:85a3 | 00000000000000000000ff010db885a3 | 0,0,0,0,0,0,0,0,0,0,-1,1,13,-72,-123,-93 |
| :A:2:3:4:5:6:7 | 0000000A000200030004000500060007 | 0,0,0,10,0,2,0,3,0,4,0,5,0,6,0,7 |
| 002:: | 00020000000000000000000000000000 | 0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| 1:2:3:4:5:6:7: | 00010002000300040005000600070000 | 0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,0 |
| 2001:0db8:85a3:: | 20010db885a300000000000000000000 | 32,1,13,-72,-123,-93,0,0,0,0,0,0,0,0,0,0 |
| 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| 2001:db8:85a3::8a2e:0370:7334 | 20010db885a3000000008a2e03707334 | 32,1,13,-72,-123,-93,0,0,0,0,-118,46,3,112,115,52 |
| F:2:3:4:5:6::8 | 000F0002000300040005000600000008 | 0,15,0,2,0,3,0,4,0,5,0,6,0,0,0,8 |
注意:SQL FIDLE不能很好地显示二进制数据…谢谢您的解决方案!有没有办法将其重写为内联表值函数?我想在一个已经相当复杂的视图查询中使用它,并且已经有一个CTE,所以我不确定如何将上面的CTE集成到我现有的视图查询中。谢谢您的解决方案!有没有办法将其重写为内联表值函数?我想在一个已经相当复杂的视图查询中使用它,并且已经有一个CTE,所以我不确定如何将上面的CTE集成到我所拥有的内容中。