本文将说明如何一步一步将纯真ip数据库QQWry.Dat导入到access数据库中,又从access数据库中导入到mssql数据库,并实现ip地址的数字化,方便查询ip。由于导入mssql后的ip数据库还是很大,所以在此就不提供下载了。
下面为操作步骤
1)下载最新的纯真版ip数据库
QQ IP数据库 纯真版20090720
IP数据记录:370628条
下载地址
2)下载转换工具
QQ IP 纯真数据库access转换工具
3)使用1)中下载的ShowIP.exe将QQWry.Dat文件解压缩为文本文件。
4)使用2)压缩包中的QuPingIP.exe将上一步骤ShowIP.exe生成的文本文件转为为access数据库
5)导入mssql数据库
启动控制台,然后新建一个数据库或者选择一个数据库,右键选择“所有任务”--》“导入数据”--》“下一步”,选择“数据源”为“microsoft access”,然后再在下面选你的access数据库位置,然后一直点下“下一步”即可完成导入。
注意:此时导入的数据中的最后一条数据是不符合规则的,没有ip_begin也没有ip_end的值,因为生成的文本文件中最后一行是说明有多少条记录的。切记要删除此条数据,要不下面更新数据库时最后一批数据更新会一直出错
6)建立ip地址的数字化字段,方便查询
此时导入的表中有4个字段ip_begin,ip_end,ip_provence,ip_address。
在表中新建立一个自动增长的字段info_id,然后设置为主键,好把ip地址转换为数字。
再在表中建立两个字段ipb,ipe【numeric型】,分别存储ip_beign和ip_end转换为数字的值。
7)更新6)步骤的表,下面就以asp.net(C#)为例。由于数据量太大,所以使用了ajax分配更新的操作
ajax.js去这里下载
index.aspx
update.ashx
8)删除不必要的字段,建立主键和索引,加快检索速度
到此,已经完成了QQWry.Dat--》access--》mssql的导入了,剩下的就是删除ip_begin,ip_end和info_id这3个字段,因为没什么用了。
把ipb,ipe共同设置为主键。
9)最后,查询数据库。
获取用户的ip地址,转换为数字然后查询数据库,下面给出asp和asp.net(c#)的示例
test.asp
test.aspx
下面为操作步骤
1)下载最新的纯真版ip数据库
QQ IP数据库 纯真版20090720
IP数据记录:370628条
下载地址
2)下载转换工具
QQ IP 纯真数据库access转换工具
3)使用1)中下载的ShowIP.exe将QQWry.Dat文件解压缩为文本文件。
4)使用2)压缩包中的QuPingIP.exe将上一步骤ShowIP.exe生成的文本文件转为为access数据库
5)导入mssql数据库
启动控制台,然后新建一个数据库或者选择一个数据库,右键选择“所有任务”--》“导入数据”--》“下一步”,选择“数据源”为“microsoft access”,然后再在下面选你的access数据库位置,然后一直点下“下一步”即可完成导入。
注意:此时导入的数据中的最后一条数据是不符合规则的,没有ip_begin也没有ip_end的值,因为生成的文本文件中最后一行是说明有多少条记录的。切记要删除此条数据,要不下面更新数据库时最后一批数据更新会一直出错
6)建立ip地址的数字化字段,方便查询
此时导入的表中有4个字段ip_begin,ip_end,ip_provence,ip_address。
在表中新建立一个自动增长的字段info_id,然后设置为主键,好把ip地址转换为数字。
再在表中建立两个字段ipb,ipe【numeric型】,分别存储ip_beign和ip_end转换为数字的值。
7)更新6)步骤的表,下面就以asp.net(C#)为例。由于数据量太大,所以使用了ajax分配更新的操作
ajax.js去这里下载
index.aspx
-HTML
<%@ Page Language="C#"%>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
protected int TotalRows = 0;//总转换数量
protected void Page_Load(object sender, EventArgs e)
{
//注意修改驱动和你的数据库名称
SqlConnection cn = new SqlConnection("server=.;uid=sa;pwd=;database=ipdb");
cn.Open();
TotalRows =(int) new SqlCommand("select count(*) from ip", cn).ExecuteScalar();//获取总行数
cn.Close();
}
</script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>ajax动态批量转换动态</title>
<style type="text/css">
body{font-size:14px;}
#proMain{border:solid 1px black;width:400px;height:20px;}
#proMain div{height:100%;width:0%;background:red;color:white;overflow:hidden;line-height:20px;font-size:12px;text-align:center;}
span.r{color:Red;}
</style>
<script type="text/javascript" src="ajax.js"></script> <!--导入ajax类库-->
</head>
<body>
<h2>注意生成过程中不要刷新当前页面,否则会导致重新生成~~~~~</h2>
<input type="button" onclick="this.disabled=true;exec();" value="开始生成" id="btnStart"/><br ><br >
<div id="proMain"><div id="dvPro"></div></div><br >
<div id="dvMsg"></div>
<script type="text/javascript">
var total=parseInt('<%=TotalRows %>')//总行数=============使用动态脚本设置
,nowIndex=0//用来存储第几批数据
,maxRows=50000//每次处理的最大行数
,sleep=5//定义生成间隔时间,单位为秒
,timer;
function UpdatePro(sql){//更新进度条
var dv=Showbo.$('dvMsg'),pro=Showbo.$('dvPro'),info=document.createElement('div');
info.innerHTML='生成<span class="r">第'+(nowIndex*maxRows+1)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>完毕,等待'+sleep+'秒后重新启动生成程序...'+sql;
dv.appendChild(info);
var p=Math.floor(Showbo.round((nowIndex*maxRows+maxRows)/total,2)*100);
if(p>100)p=100;
pro.style.width=p+'%';//设置进度条
pro.innerHTML='完成'+p+'%';
}
function success(xhr){//成功回调函数
UpdatePro(xhr.responseText);
if(nowIndex*maxRows+maxRows<total){//还有数据,继续启动ajax
nowIndex++;//下一批
setTimeout("exec()",sleep*1000);
}
else{//生成完毕
var h3=document.createElement('h3');h3.innerHTML='生成完毕!总共花费时间:'+((new Date()-timer)/1000)+'s';
Showbo.$('dvMsg').appendChild(h3);
Showbo.$('btnStart').disabled=false;
}
}
function Error(xhr){//错误回调函数
var dv=Showbo.$('dvMsg'),pro=Showbo.$('dvPro'),info=document.createElement('div');
info.innerHTML='生成<span class="r">第'+(nowIndex*maxRows)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>时<b>发生错误</b>,等待'+sleep+'秒后重新启动生成程序...';
dv.appendChild(info);
setTimeout("exec(true)",sleep*1000);
}
function exec(reTry){
if(!timer)timer=new Date();
var dv=Showbo.$('dvMsg'),info=document.createElement('div');
info.innerHTML='<br/>'+(reTry?"正在重新":"正在")+'生成<span class="r">第'+(nowIndex*maxRows+1)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>,请等待......';
dv.appendChild(info);
Showbo.Ajax.send({url:'update.ashx',method:'post',params:'mr='+maxRows+'&ri='+nowIndex,success:success,failure:Error});
}
window.onload=function(){
Showbo.$('dvMsg').innerHTML='总行数为:<span class="r">'+total+'</span>,'
+'每次处理<span class="r">'+maxRows+'行</span>,共分为<span class="r">'
+Math.ceil(total/maxRows)+'批</span>次分别更新,预计使用时间为:<span class="r">'
+Math.ceil((Showbo.round(total/maxRows,2)+2)*sleep)+'s</span>';
}
</script>
</body>
</html>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
protected int TotalRows = 0;//总转换数量
protected void Page_Load(object sender, EventArgs e)
{
//注意修改驱动和你的数据库名称
SqlConnection cn = new SqlConnection("server=.;uid=sa;pwd=;database=ipdb");
cn.Open();
TotalRows =(int) new SqlCommand("select count(*) from ip", cn).ExecuteScalar();//获取总行数
cn.Close();
}
</script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>ajax动态批量转换动态</title>
<style type="text/css">
body{font-size:14px;}
#proMain{border:solid 1px black;width:400px;height:20px;}
#proMain div{height:100%;width:0%;background:red;color:white;overflow:hidden;line-height:20px;font-size:12px;text-align:center;}
span.r{color:Red;}
</style>
<script type="text/javascript" src="ajax.js"></script> <!--导入ajax类库-->
</head>
<body>
<h2>注意生成过程中不要刷新当前页面,否则会导致重新生成~~~~~</h2>
<input type="button" onclick="this.disabled=true;exec();" value="开始生成" id="btnStart"/><br ><br >
<div id="proMain"><div id="dvPro"></div></div><br >
<div id="dvMsg"></div>
<script type="text/javascript">
var total=parseInt('<%=TotalRows %>')//总行数=============使用动态脚本设置
,nowIndex=0//用来存储第几批数据
,maxRows=50000//每次处理的最大行数
,sleep=5//定义生成间隔时间,单位为秒
,timer;
function UpdatePro(sql){//更新进度条
var dv=Showbo.$('dvMsg'),pro=Showbo.$('dvPro'),info=document.createElement('div');
info.innerHTML='生成<span class="r">第'+(nowIndex*maxRows+1)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>完毕,等待'+sleep+'秒后重新启动生成程序...'+sql;
dv.appendChild(info);
var p=Math.floor(Showbo.round((nowIndex*maxRows+maxRows)/total,2)*100);
if(p>100)p=100;
pro.style.width=p+'%';//设置进度条
pro.innerHTML='完成'+p+'%';
}
function success(xhr){//成功回调函数
UpdatePro(xhr.responseText);
if(nowIndex*maxRows+maxRows<total){//还有数据,继续启动ajax
nowIndex++;//下一批
setTimeout("exec()",sleep*1000);
}
else{//生成完毕
var h3=document.createElement('h3');h3.innerHTML='生成完毕!总共花费时间:'+((new Date()-timer)/1000)+'s';
Showbo.$('dvMsg').appendChild(h3);
Showbo.$('btnStart').disabled=false;
}
}
function Error(xhr){//错误回调函数
var dv=Showbo.$('dvMsg'),pro=Showbo.$('dvPro'),info=document.createElement('div');
info.innerHTML='生成<span class="r">第'+(nowIndex*maxRows)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>时<b>发生错误</b>,等待'+sleep+'秒后重新启动生成程序...';
dv.appendChild(info);
setTimeout("exec(true)",sleep*1000);
}
function exec(reTry){
if(!timer)timer=new Date();
var dv=Showbo.$('dvMsg'),info=document.createElement('div');
info.innerHTML='<br/>'+(reTry?"正在重新":"正在")+'生成<span class="r">第'+(nowIndex*maxRows+1)+'行--第'+(nowIndex*maxRows+maxRows)+'行</span>,请等待......';
dv.appendChild(info);
Showbo.Ajax.send({url:'update.ashx',method:'post',params:'mr='+maxRows+'&ri='+nowIndex,success:success,failure:Error});
}
window.onload=function(){
Showbo.$('dvMsg').innerHTML='总行数为:<span class="r">'+total+'</span>,'
+'每次处理<span class="r">'+maxRows+'行</span>,共分为<span class="r">'
+Math.ceil(total/maxRows)+'批</span>次分别更新,预计使用时间为:<span class="r">'
+Math.ceil((Showbo.round(total/maxRows,2)+2)*sleep)+'s</span>';
}
</script>
</body>
</html>
update.ashx
-C#
<%@ WebHandler Language="C#" Class="update" %>
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
public class update : IHttpHandler {
private bool IsInt(string v)
{
if (v == null || v.Trim() == "") return false;
else return Regex.IsMatch(v, @"^\d+$", RegexOptions.Compiled);
}
public void ProcessRequest(HttpContext context)
{
context.Response.Charset = "utf-8";
context.Response.ContentType = "text/html";
HttpRequest Request = context.Request;
string rowIndex = Request.Form["ri"], mr = Request.Form["mr"], Sql = "";
int iRowIndex = 0, iMR = 10;//如果未传递每次生成多少行,则默认10行,如果处理的行号不为整数,默认从第0行开始
if (IsInt(mr)) iMR = int.Parse(mr);
if (IsInt(rowIndex)) iRowIndex = int.Parse(rowIndex);
Sql = "select top " + iMR + " * from(select top " + (iMR * iRowIndex + iMR)
+ " info_id,ip_begin,ip_end from ip order by info_id)tmp order by info_id desc";//注意这里取数据的方式
//==========注意修改驱动和你的数据库名称
SqlConnection cn = new SqlConnection("server=.;uid=sa;pwd=;database=ipdb");
cn.Open();
bool Ok = true;
//try
//{
SqlDataReader dr = new SqlCommand(Sql, cn).ExecuteReader();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
double ipb = 0, ipe = 0, pow = 256;
string[] tmp;
//更新数据的操作
while (dr.Read())//构造更新语句
{
tmp = dr[1].ToString().Split('.');//分离ip,并计算它的数字值,注意类型
ipb = double.Parse(tmp[0]) * Math.Pow(pow, 3) + double.Parse(tmp[1]) * Math.Pow(pow, 2) + double.Parse(tmp[2]) * pow + double.Parse(tmp[3]);
tmp = dr[2].ToString().Split('.');
ipe = double.Parse(tmp[0]) * Math.Pow(pow, 3) + double.Parse(tmp[1]) * Math.Pow(pow, 2) + double.Parse(tmp[2]) * pow + double.Parse(tmp[3]);
sb.Append("update ip set ipb=" + ipb + " , ipe=" + ipe + " where info_id=" + dr[0] + ";");
}
dr.Close();
//执行更新
new SqlCommand("set xact_abort on;begin tran ;" + sb.ToString() + " commit", cn).ExecuteNonQuery();
//}
//catch { Ok = false; }
cn.Close();
if (!Ok) throw new Exception("操作失败~~~");//抛出错误,让ajax重新执行当前操作
}
public bool IsReusable {
get {
return false;
}
}
}
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
public class update : IHttpHandler {
private bool IsInt(string v)
{
if (v == null || v.Trim() == "") return false;
else return Regex.IsMatch(v, @"^\d+$", RegexOptions.Compiled);
}
public void ProcessRequest(HttpContext context)
{
context.Response.Charset = "utf-8";
context.Response.ContentType = "text/html";
HttpRequest Request = context.Request;
string rowIndex = Request.Form["ri"], mr = Request.Form["mr"], Sql = "";
int iRowIndex = 0, iMR = 10;//如果未传递每次生成多少行,则默认10行,如果处理的行号不为整数,默认从第0行开始
if (IsInt(mr)) iMR = int.Parse(mr);
if (IsInt(rowIndex)) iRowIndex = int.Parse(rowIndex);
Sql = "select top " + iMR + " * from(select top " + (iMR * iRowIndex + iMR)
+ " info_id,ip_begin,ip_end from ip order by info_id)tmp order by info_id desc";//注意这里取数据的方式
//==========注意修改驱动和你的数据库名称
SqlConnection cn = new SqlConnection("server=.;uid=sa;pwd=;database=ipdb");
cn.Open();
bool Ok = true;
//try
//{
SqlDataReader dr = new SqlCommand(Sql, cn).ExecuteReader();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
double ipb = 0, ipe = 0, pow = 256;
string[] tmp;
//更新数据的操作
while (dr.Read())//构造更新语句
{
tmp = dr[1].ToString().Split('.');//分离ip,并计算它的数字值,注意类型
ipb = double.Parse(tmp[0]) * Math.Pow(pow, 3) + double.Parse(tmp[1]) * Math.Pow(pow, 2) + double.Parse(tmp[2]) * pow + double.Parse(tmp[3]);
tmp = dr[2].ToString().Split('.');
ipe = double.Parse(tmp[0]) * Math.Pow(pow, 3) + double.Parse(tmp[1]) * Math.Pow(pow, 2) + double.Parse(tmp[2]) * pow + double.Parse(tmp[3]);
sb.Append("update ip set ipb=" + ipb + " , ipe=" + ipe + " where info_id=" + dr[0] + ";");
}
dr.Close();
//执行更新
new SqlCommand("set xact_abort on;begin tran ;" + sb.ToString() + " commit", cn).ExecuteNonQuery();
//}
//catch { Ok = false; }
cn.Close();
if (!Ok) throw new Exception("操作失败~~~");//抛出错误,让ajax重新执行当前操作
}
public bool IsReusable {
get {
return false;
}
}
}
8)删除不必要的字段,建立主键和索引,加快检索速度
到此,已经完成了QQWry.Dat--》access--》mssql的导入了,剩下的就是删除ip_begin,ip_end和info_id这3个字段,因为没什么用了。
把ipb,ipe共同设置为主键。
9)最后,查询数据库。
获取用户的ip地址,转换为数字然后查询数据库,下面给出asp和asp.net(c#)的示例
test.asp
-VBScript
Function getIP()'获取用户ip地址
if Request.ServerVariables("HTTP_X_FORWARDED_FOR") = "" then
getIP=Request.ServerVariables("REMOTE_ADDR")
else
getIP=Request.ServerVariables("HTTP_X_FORWARDED_FOR")
end if
end function
Function getArea()'获取ip地址
on error resume next
dim inIP,inIPnum,inIPs
inIP = getIP()'获取ip地址
if inIP = "127.0.0.1" then getArea="本机地址":Exit Function
inIPs = split(inIP,".")
inIPnum = 256*256*256*inips(0) + 256*256*inips(1) + 256*inips(2) + inips(3)'转换ip地址为数字
set conn=server.createobject("adodb.connection")
conn.open "你的驱动"
set rsip=server.CreateObject("adodb.recordset")
sqlstr="select top 1 ip_provence,ip_address from ip where ipe>="&inipnum&" and ipb<=" & inipnum
rsip.open sqlstr,conn,1,3
if rsip.eof then
getArea="未知数据"
else
getArea=rsip(0) & rsip(1)
end if
rsip.close:set rsip=nothing
conn.close:set conn=nothing
End Function
response.write getArea()
if Request.ServerVariables("HTTP_X_FORWARDED_FOR") = "" then
getIP=Request.ServerVariables("REMOTE_ADDR")
else
getIP=Request.ServerVariables("HTTP_X_FORWARDED_FOR")
end if
end function
Function getArea()'获取ip地址
on error resume next
dim inIP,inIPnum,inIPs
inIP = getIP()'获取ip地址
if inIP = "127.0.0.1" then getArea="本机地址":Exit Function
inIPs = split(inIP,".")
inIPnum = 256*256*256*inips(0) + 256*256*inips(1) + 256*inips(2) + inips(3)'转换ip地址为数字
set conn=server.createobject("adodb.connection")
conn.open "你的驱动"
set rsip=server.CreateObject("adodb.recordset")
sqlstr="select top 1 ip_provence,ip_address from ip where ipe>="&inipnum&" and ipb<=" & inipnum
rsip.open sqlstr,conn,1,3
if rsip.eof then
getArea="未知数据"
else
getArea=rsip(0) & rsip(1)
end if
rsip.close:set rsip=nothing
conn.close:set conn=nothing
End Function
response.write getArea()
test.aspx
-HTML
<%@ Page Language="C#"%>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(getArea());
}
private string getIP()
{
string ip = Request.ServerVariables["http_x_forwarded_for"];
if (ip == null || ip.Trim() == "") ip = Request.ServerVariables["remote_addr"];
return ip;
}
private string getArea()
{
string Ip = getIP(),area="";
if (Ip == null || Ip.Trim() == "") return "未知ip地址";
string[] arr = Ip.Split('.');
double ipNum = 0, pow = 256;
ipNum = double.Parse(arr[0]) * Math.Pow(pow, 3) + double.Parse(arr[1]) * Math.Pow(pow, 2) + double.Parse(arr[2]) * pow + double.Parse(arr[3]);
SqlConnection cn = new SqlConnection("驱动");
cn.Open();
SqlDataReader dr = new SqlCommand("select top 1 ip_provence,ip_address from ip where ipe>="+ipNum+" and ipb<=" + ipNum, cn).ExecuteReader();
if (dr.Read()) area = dr[0].ToString() + dr[1].ToString();
else area = "未知地址";
dr.Close();
cn.Close();
return area;
}
</script>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(getArea());
}
private string getIP()
{
string ip = Request.ServerVariables["http_x_forwarded_for"];
if (ip == null || ip.Trim() == "") ip = Request.ServerVariables["remote_addr"];
return ip;
}
private string getArea()
{
string Ip = getIP(),area="";
if (Ip == null || Ip.Trim() == "") return "未知ip地址";
string[] arr = Ip.Split('.');
double ipNum = 0, pow = 256;
ipNum = double.Parse(arr[0]) * Math.Pow(pow, 3) + double.Parse(arr[1]) * Math.Pow(pow, 2) + double.Parse(arr[2]) * pow + double.Parse(arr[3]);
SqlConnection cn = new SqlConnection("驱动");
cn.Open();
SqlDataReader dr = new SqlCommand("select top 1 ip_provence,ip_address from ip where ipe>="+ipNum+" and ipb<=" + ipNum, cn).ExecuteReader();
if (dr.Read()) area = dr[0].ToString() + dr[1].ToString();
else area = "未知地址";
dr.Close();
cn.Close();
return area;
}
</script>