Trong bài viết trước “Thống kê truy cập website trong asp.net sử dụng global.asax” tôi đã hướng dẫn bạn thống kê truy cập website qua text. Có bạn gửi yêu cầu viết bài thống kế truy cập website sử dụng database. Đáp ứng yêu cầu trong bài này tôi sẽ hướng dẫn các bạn xây dựng một bộ đếm thống kê truy cập website đầy đủ bằng asp.net – C# sử dụng SQL server.
Trong bài viết này tôi hướng dẫn bạn thống kê số truy cập Hôm nay, Hôm qua, Tuần này, … Đây là hình ảnh minh họa kết quả khi bạn thực hiện theo bài viết này:
Để làm được bạn cần tạo một bảng TB_ThongKe như sau:
CREATE TABLE [dbo].[TB_ThongKe]( [MaTB] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL, [ThoiGian] [datetime] NOT NULL, [SoTruyCap] [bigint] NOT NULL, )
Tiếp theo bạn cần viết một Store Procedure để thực hiện việc thông kê như sau:
CREATE PROCEDURE [dbo].[spThongKe_Edit] AS BEGIN DECLARE @SoTruyCapGanNhat bigint DECLARE @Count int SELECT @Count=Count(*) FROM TB_ThongKe ttk IF @Count IS NULL SET @Count=0 IF @Count=0 INSERT INTO TB_ThongKe(ThoiGian, SoTruyCap) VALUES (GetDate(),1) ELSE BEGIN DECLARE @ThoiGianGanNhat datetime SELECT @SoTruyCapGanNhat=ttk.SoTruyCap, @ThoiGianGanNhat=ttk.ThoiGian FROM TB_ThongKe ttk WHERE ttk.MaTB=(SELECT Max(ttk2.MaTB) FROM TB_ThongKe ttk2) IF @SoTruyCapGanNhat IS NULL SET @SoTruyCapGanNhat=0 IF @ThoiGianGanNhat IS NULL SET @ThoiGianGanNhat=getdate() -- Kiểm tra xem lần truy cập này có phải đã sang ngày mới không (Qua thời điểm 12h00) -- Nếu chưa sang ngày mới thì cập nhật lại SoTruyCap IF Day(@ThoiGianGanNhat)=Day(GETDATE()) BEGIN UPDATE TB_ThongKe SET SoTruyCap = @SoTruyCapGanNhat+1, ThoiGian = GetDate() WHERE MaTB=(SELECT Max(ttk2.MaTB) FROM TB_ThongKe ttk2) END -- Nếu đã sang ngày mới thì thêm mới bản ghi, SoTruyCap bắt đầu lại là 1 ELSE BEGIN INSERT INTO TB_ThongKe(ThoiGian, SoTruyCap) VALUES (GetDate(),1) END END -- Thống kê Hom nay, Hom qua, Tuan nay, Tuan Truoc, Thang nay, Thang Truoc DECLARE @HomNay INT SET @HomNay = datepart(dw, GetDate()) SELECT @SoTruyCapGanNhat=ttk.SoTruyCap, @ThoiGianGanNhat=ttk.ThoiGian FROM TB_ThongKe ttk WHERE ttk.MaTB=(SELECT Max(ttk2.MaTB) FROM TB_ThongKe ttk2) --Tính SoTruyCapHomQua DECLARE @SoTruyCapHomQua bigint SELECT @SoTruyCapHomQua=isnull(SoTruyCap,0) FROM TB_ThongKe WHERE CONVERT(nvarchar(20),ThoiGian,103)=CONVERT(nvarchar(20),GETDATE()-1,103) IF @SoTruyCapHomQua IS null SET @SoTruyCapHomQua=0 -- Tính Ngày đầu tuần này DECLARE @DauTuanNay datetime SET @DauTuanNay= DATEADD(wk, DATEDIFF(wk, 6, GetDate()), 6) -- Tính Ngày đầu của tuần trước Tính từ thời điểm 00:00:)) DECLARE @NgayDauTuanTruoc datetime SET @NgayDauTuanTruoc = Cast(CONVERT(nvarchar(30),DATEADD(dd, -(@HomNay+6), GetDate()),101) AS datetime) -- Tính ngày cuối tuần trước tính đến 24h ngày cuối tuần DECLARE @NgayCuoiTuanTruoc datetime SET @NgayCuoiTuanTruoc = Cast(CONVERT(nvarchar(30),DATEADD(dd, -@HomNay, GetDate()),101) +' 23:59:59' AS datetime) -- Tính số truy cập tuần này DECLARE @SoTruyCapTuanNay bigint SELECT @SoTruyCapTuanNay=isnull(Sum(SoTruyCap),0) FROM TB_ThongKe ttk WHERE ttk.ThoiGian BETWEEN @DauTuanNay AND getdate() -- Tính số truy cập tuần trước DECLARE @SoLanTruyCapTuanTruoc bigint SELECT @SoLanTruyCapTuanTruoc=isnull(sum(SoTruyCap),0) FROM TB_ThongKe ttk WHERE ttk.ThoiGian BETWEEN @NgayDauTuanTruoc AND @NgayCuoiTuanTruoc -- Tính số truy cập tháng này DECLARE @SoTruyCapThangNay bigint SELECT @SoTruyCapThangNay=isnull(Sum(SoTruyCap),0) FROM TB_ThongKe ttk WHERE MONTH(ttk.ThoiGian)=MONTH(GETDATE()) -- Tính số truy cập tháng trước DECLARE @SoTruyCapThangTruoc bigint SELECT @SoTruyCapThangTruoc=isnull(Sum(SoTruyCap),0) FROM TB_ThongKe ttk WHERE MONTH(ttk.ThoiGian)=MONTH(GETDATE())-1 -- Tính tổng số DECLARE @TongSo bigint SELECT @TongSo=isnull(Sum(SoTruyCap),0) FROM TB_ThongKe ttk SELECT @SoTruyCapGanNhat AS HomNay, @SoTruyCapHomQua AS HomQua, @SoTruyCapTuanNay AS TuanNay, @SoLanTruyCapTuanTruoc AS TuanTruoc, @SoTruyCapThangNay AS ThangNay, @SoTruyCapThangTruoc AS ThangTruoc, @TongSo AS TatCa END
Đọc Store trên có thể bạn sẽ hơi khó hiểu nếu bạn không thành thạo lập trình với SQL. Trước tiên bạn cần kiểm tra xem nếu chưa có dữ liệu thì thêm mới. Và nếu lượt truy cập tiếp theo là thời gian bắt đầu sang ngày tiếp theo bạn lại thực hiện thêm bản ghi vào bảng TB_ThongKe. các trường hợp khác đều cập nhật dữ liệu với bản ghi cuối của TB_ThongKe
Để thực hiện thống kê bạn cần viết công thức tính các số liệu của
– Hôm nay=Tổng số truy cập của ngày hiện tại (Lấy giờ hệ thống của Database Server)
– Hôm qua=Tổng số truy cập của ngày gần nhất khác hôm qua
– Tuần này: Tổng số truy cập của các ngày trong tuần hiện tại => bạn cần tính đầu tuần và cuối tuần này là ngày nào và tình tổng theo đều kiện BETWEEN (Bạn chú ý là cần lấy dữ liệu ngày đầu tuần bắt đầu từ 00:00:00 và đến 23:59:59 của ngày cuối tuần).
– Tuần trước: Tổng số truy cập của các ngày của tuần trước => bạn cần tính đầu tuần và cuối tuần trước là ngày nào và tình tổng theo đều kiện BETWEEN (Bạn chú ý là cần lấy dữ liệu ngày đầu tuần bắt đầu từ 00:00:00 và đến 23:59:59 của ngày cuối tuần).
– Các điều kiện tháng này, tháng trước, tổng số cũng tương tự
*** Qua đây bạn cũng biết cách xác định được ngày đầu và ngày cuỗi của Tuần này, tuần trước, … Tôi nghĩ là nó khá hay với ai thường lập trình trên SQL để tính toán dữ liệu liên quan đến ngày tháng
Bạn tạo trong App_Code class DataBindSQL.cs để thực hiện kết nối và trả về dữ liệu DataTable như sau:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using System.Data.SqlClient; public class DataBindSQL { public DataBindSQL() { } //Hàm thực thi và trả về DataTable public DataTable TableThongKe() { DataTable dtb = new DataTable(); // Khai báo chuỗi kết nối string ConnectionString = @"Server =.\SQL2005;Initial Catalog=QuanLyThuVien;User ID=sa;Password=sa"; SqlConnection Conn = new SqlConnection(ConnectionString); try { // Mở kết nối Conn.Open(); DataSet ds = new DataSet(); SqlCommand cmdUpd = new SqlCommand("spThongKe_Edit", Conn); cmdUpd.CommandType = CommandType.StoredProcedure; SqlDataAdapter da = new SqlDataAdapter(cmdUpd); // Đổ dữ liệu vào DataSet da.Fill(ds); dtb = ds.Tables[0]; } catch { } finally { if (Conn.State == ConnectionState.Open) Conn.Close(); Conn.Dispose(); } return dtb; } }
Tiếp theo bạn viết trong Global.asax nội dung như sau:
<%@ Application Language="C#" %> <%@ Import Namespace="System.IO" %> <%@ Import Namespace="System.Data" %> <script runat="server"> void Application_Start(object sender, EventArgs e) { // Code that runs on application startup Application["HomNay"] = 0; Application["HomQua"] = 0; Application["TuanNay"] = 0; Application["TuanTruoc"] = 0; Application["ThangNay"] = 0; Application["ThangTruoc"] =0; Application["TatCa"] = 0; Application["visitors_online"] = 0; } void Application_End(object sender, EventArgs e) { // Code that runs on application shutdown } void Application_Error(object sender, EventArgs e) { // Code that runs when an unhandled error occurs } void Session_Start(object sender, EventArgs e) { Session.Timeout = 150; Application.Lock(); Application["visitors_online"] = Convert.ToInt32(Application["visitors_online"]) + 1; Application.UnLock(); try { DataBindSQL mThongKe = new DataBindSQL(); DataTable dtb = mThongKe.TableThongKe(); if (dtb.Rows.Count > 0) { Application["HomNay"] = long.Parse("0" + dtb.Rows[0]["HomNay"]).ToString("#,###"); Application["HomQua"] = long.Parse("0" + dtb.Rows[0]["HomQua"]).ToString("#,###"); Application["TuanNay"] = long.Parse("0" + dtb.Rows[0]["TuanNay"]).ToString("#,###"); Application["TuanTruoc"] = long.Parse("0" + dtb.Rows[0]["TuanTruoc"]).ToString("#,###"); Application["ThangNay"] = long.Parse("0" + dtb.Rows[0]["ThangNay"]).ToString("#,###"); Application["ThangTruoc"] = long.Parse("0" + dtb.Rows[0]["ThangTruoc"]).ToString("#,###"); Application["TatCa"] = long.Parse("0" + dtb.Rows[0]["TatCa"]).ToString("#,###"); } dtb.Dispose(); mThongKe = null; } catch { } } void Session_End(object sender, EventArgs e) { Application.Lock(); Application["visitors_online"] = Convert.ToUInt32(Application["visitors_online"]) - 1; Application.UnLock(); } </script>
Vậy ở nơi bạn cần hiển thị thống kế bạn chỉ cần đưa các giá trị Application[“HomNay”], Application[“HomQua”] ,… Tương ứng. Bạn nên xây dựng một UserControl (ucThongKe.ascx) nội dung như sau
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ucThongKe.ascx.cs" Inherits="ucThongKe" %> <asp:Panel ID="Panel1" runat="server" Width="250px" GroupingText="Thống kê truy cáºp"> <table cellpadding="0" cellspacing="0" Width="250px" > <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/Import.png" /> Đang onlien:</td> <td style="width:50%"> <% =Application["visitors_online"].ToString()%></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/25.png" />Hôm nay:</td> <td style="width:50%"> <% =Application["HomNay"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/25.png" /> Hôm qua:</td> <td style="width:50%"> <% =Application["HomQua"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/AddUser.jpg" /> Tuần này:</td> <td style="width:50%"> <% =Application["TuanNay"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/AddUser.jpg" /> Tuần trước:</td> <td style="width:50%"> <% =Application["TuanTruoc"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/User.png" /> Tháng này:</td> <td style="width:50%"> <% =Application["ThangNay"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/User.png" /> Tháng trước:</td> <td style="width:50%"> <% =Application["ThangTruoc"].ToString() %></td> </tr> <tr> <td style="width:50%; padding-left:10px"> <img src="Common/Images/02.jpg" />Tất cả:</td> <td style="width:50%"> <% =Application["TatCa"].ToString()%></td> </tr> </table> </asp:Panel>
Khi đã viết xong UserControl trong trang asp.net bạn chỉ cần kéo thả control này vào và chạy.
Chúc các bạn thành công
Nguồn: h m c l i p . n e t