如何将QQWry.Dat导出为access数据,导入mssql及查询纯真导入后的ip数据

  本文将说明如何一步一步将纯真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
+展开
-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 =(intnew 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;
        }
    }

}



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()


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> 

加支付宝好友偷能量挖...


原创文章,转载请注明出处:如何将QQWry.Dat导出为access数据,导入mssql及查询纯真导入后的ip数据

评论(1)Web开发网
阅读(222)喜欢(1)Asp.Net/C#/WCF