Cách Insert và tạo bảng dữ liệu "động" trong SQL Server

Như chúng ta đã biết đối với các hệ thống Logging thì dữ liệu luôn được cập nhật hàng tháng, hàng ngày vì vậy đòi hỏi CSDL phải tương thích có nghĩa là Log trong tháng nào thì hệ thống sẽ Insert vào tháng đó tương ứng tráng việc Insert nhiều trong cùng 1 bảng dẫn đến việc Select chậm khi trả về kết quả.

Vì vậy đối với Log của mỗi tháng chúng ta sẽ tạo ra các bảng vd:

Tháng 1 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_1_2010
Tháng 2 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_2_2010
...
Tháng 12 năm 2010 hệ thống sẽ tự động tạo ra bảng tbl_Month_12_2010

Như vậy làm sao để hệ thống có thể tự tạo ra các bảng tương ứng với năm và tháng như vậy ?

Giải pháp của tôi là sử dụng SQL Job trong SQL Server, cái này bắt buộc bạn phải có Full quyền Administrator trên Server Database

Các bước như sau:

B1: Trong SQL Server bạn kéo xuống dưới có phần SQL Server Agent bạn phải Start nó lên nếu nó đang Stop

Bạn click chuột phải vào Jobs chọn New Job

B2: Tại đây bạn được yêu cầu nhập Name: Tên của Job ở đây tôi chọn là CreateTableLogging và owner là sa

B3: Sau khi ấn OK bạn chọn tiếp phần Steps và bạn chọn New Step, tại đây bạn được yêu cầu nhập Step Name tôi chọn là StepCreateTable và Type là Transact-SQL script (T-SQL) có nghĩa là chạy câu lệnh SQL.

Bạn chọn tiếp Database là tên Database bạn muốn thực thi
Phần Command bạn gõ câu lệnh sau để tạo bảng động

DECLARE @strCreateTable AS VARCHAR(1000)
SET @strCreateTable = 'CREATE TABLE tbl_Month_'
SET @strCreateTable += Cast(MONTH(GETDATE()) as varchar)
SET @strCreateTable += '_'
SET @strCreateTable += Cast(YEAR(GETDATE()) as varchar)
SET @strCreateTable +='('
SET @strCreateTable +='ID int PRIMARY KEY IDENTITY,'
SET @strCreateTable +='Name nvarchar(50)'
SET @strCreateTable +=')'
--PRINT(@strCreateTable)
EXEC(@strCreateTable)

Sau đó nhấn OK

B4: Tiếp đến bạn chọn phần Schedules (để đặt lịch chạy cho Job) ban chọn New Schedule ở đây bạn được yêu cầu nhập Schedule Name cho Job tôi chọn là ScheduleCreateTable, Phần tần suất (Frequency) tôi chọn Occurs chạy vào ngày 15 hàng tháng (Monthly) lúc 12h đêm.

B5: sau đó bạn ấn OK để hoàn tất việc đặt lịch chạy cho Job và OK để hoàn tất Job
và đây là kết quả

B6: Để chắc là Job của bạn có chạy đúng hay không thì bạn Click chuột phải vào Job vừa tạo chọn Start Job at Step...

B7: Nếu nó báo thế này thì có nghĩa là Job của bạn đã chạy chính xác

B8: Kiểm tra

Như vậy mới hoàn thành xong phần tạo bảng bước tiếp chúng ta phải insert vào bảng đó thế nào

DECLARE @strValue AS NVARCHAR(50)
DECLARE @strSQL AS VARCHAR(1000)
SET @strValue = 'Justin___'
SET @strValue += Cast(GETDATE() as varchar)

SET @strSQL = 'INSERT INTO tbl_Month_'
SET @strSQL += Cast(MONTH(GETDATE()) as varchar)
SET @strSQL += '_'
SET @strSQL += Cast(YEAR(GETDATE()) as varchar)
SET @strSQL += '([Name]) VALUES('''
SET @strSQL += @strValue
SET @strSQL += ''')'
--PRINT(@strSQL)
EXEC(@strSQL)

Trong bảng tbl_Month_xx_xxxx  này tôi có 2 trường là ID (tự tăng) và Name
sau đó tôi insert test các giá trị mà gán trong biến @strValue là "Justin___" + ngày hiện tại
sau khi insert xong dữ liệu của tôi sẽ là thế này

ID   Name
6    Justin___Dec 12 2009  9:25AM
7    Justin___Dec 12 2009  9:25AM
8    Justin___Dec 12 2009  9:25AM
9    Justin___Dec 12 2009  9:25AM

Kỹ thuật phân trang trong trang asp.net dùng Store

Trên website này có viết bài "Kỹ thuật phân trang bằng Store Procedure" nhưng nhiều bạn chưa áp dụng được nó để phân trang trong asp.net và có nhiều bạn hỏi cách làm. Bài này mình sẽ hướng dẫn các bạn sử dụng thuật toán của bài viết đó vào trang asp.net.

Trong bài viết "Kỹ thuật phân trang bằng Store Procedure" thì dữ liệu hiển thị sẽ được chia làm 2 phần, một phần là dữ liệu truy vấn, một phần là chuỗi html hiển thị phân trang. Vậy để sử dụng nó bạn cần đổ dữ liệu từ Store vào DataSet. Khi đó phần dữ liệu truy vấn sẽ là Table[0] và phần hiển thị phân trang là Table[1]. Vậy bạn cần viết hàm để thực hiện nó. Để thực hiện mình lấy database Northwind, truy vấn dữ liệu từ bảng Customrs. Với Stored Procedure spPhanTrangSQL bạn xem ở bài viết  "Kỹ thuật phân trang bằng Store Procedure"  còn Store truy vẫn dữ liệu mình viết như sau:

CREATE PROCEDURE [dbo].[spCustomers_PhanTrang]
@currPage int,
@recodperpage int,
@Pagesize int
AS
Begin
    Begin
    WITH s AS
    (
        SELECT ROW_NUMBER() 
            OVER(ORDER BY CustomerID, 
            CompanyName) AS RowNum, 
            CustomerID, 
            CompanyName, 
            ContactName, City 
        FROM Customers  
    )
    Select * From s 
    Where RowNum Between 
        (@currPage - 1)*@recodperpage+1 
            AND @currPage*@recodperpage
    END
    -- Tính tổng số bản ghi
    DECLARE @Tolal int
    SELECT @Tolal=Count(*) FROM Customers

    EXEC spPhanTrangSQL 
            @Tolal, 
            @currPage, 
            @Pagesize, 
            @recodperpage
END

Trong trang aspx bạn cần một Gridview và một Literal để hiển thị dữ liệu như sau:

<table cellpadding="0" cellspacing="0" width="620">
    <tr>
        <td style="width: 100%">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" BackColor="White"
        BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px" CellPadding="4" Width="620px">
        <RowStyle BackColor="White" ForeColor="#330099" />
        <Columns>
            <asp:BoundField DataField="RowNum" HeaderText="RowNum" SortExpression="RowNum" />
            <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" SortExpression="CustomerID" />
            <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
            <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
            <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
        </Columns>
        <FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
        <PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
        <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="#FFFFCC" />
    </asp:GridView>
        </td>
    </tr>
    <tr>
        <td style="width: 100%">
            <asp:Literal ID="ltlPhanTrang" runat="server"/></td>
    </tr>
</table>

Khi chạy dữ liệu được hiển thị như hình minh họa sau:

 

Giờ chúng ta sẽ viết  Các hàm cần thực hiện hiển thị dữ liệu:
1. Hàm thực thi một Store đổ dữ liệu vào DataSet

private static DataSet ThucThiStore_DataSet(
        string StoredProcedure, 
        params SqlParameter[] Parameters)
    {
    //Khai báo cuỗi kết nối
        string ConnectionString = 
        @"Server =.\SQL2005;Initial Catalog=Northwind;User ID=sa;Password=sa"; 
        SqlConnection Conn = new SqlConnection(ConnectionString);
        SqlCommand Command = new SqlCommand(StoredProcedure, Conn);
        if (Parameters != null)
        {
            Command.Parameters.Clear();
            Command.Parameters.AddRange(Parameters);
        }
        DataSet ds = new DataSet(); SqlDataAdapter da = 
            new SqlDataAdapter(StoredProcedure, Conn);
        Command.CommandType = CommandType.StoredProcedure;
        da.SelectCommand = Command;
        try
        {
    //Mở kết nối
            Conn.Open();
            da.Fill(ds);
        }
        finally
        {
    // Đóng kết nối
            if (Conn.State == ConnectionState.Open)
                Conn.Close();
            Conn.Dispose();
        }
        return ds;
    }

2. Hàm lấy dữ liệu từ Store trả về một DataSet

private DataSet StoreToDataSet(
        int currPage, 
        int recodperpage, 
        int Pagesize)
    {
        DataSet dts = new DataSet();
        SqlParameter[] arrParam = {
                new SqlParameter("@currPage", SqlDbType.Int),
                new SqlParameter("@recodperpage", SqlDbType.Int),
                new SqlParameter("@Pagesize", SqlDbType.Int)
                };
        arrParam[0].Value = currPage;
        arrParam[1].Value = recodperpage;
        arrParam[2].Value = Pagesize;
        return ThucThiStore_DataSet("spCustomers_PhanTrang", arrParam);
    }

3. Hàm nạp dữ liệu để hiển thị

private void NapDuLieu(int currPage, int recodperpage, int Pagesize)
   {
       DataSet ds = StoreToDataSet(currPage, recodperpage, Pagesize);
       DataTable dtbData = ds.Tables[0];
       DataTable dtbPhanTrang = ds.Tables[1];
       if (dtbData.Rows.Count > 0)
       {
           GridView1.DataSource = dtbData;
           GridView1.DataBind();
           if (dtbPhanTrang.Rows.Count > 0)
           {
               ltlPhanTrang.Text = dtbPhanTrang.Rows[0]["PhanTrang"] + "";
           }
       }
   }

Trong hàm này bạn thấy dữ liệu được chia làm 2 phần như đã nói ở trên và Phân dữ liệu truy vấn là Table[0] được bind vào Gridview1 còn phần dữ liệu phân trang là Table[1] (Chỉ là 1 bản ghi dữ liệu dang html được gán vào ltlPhanTrang).
 
Trong hàm Page_Load bạn cần khai báo 1 biến page và hiển thị dữ liệu như sau:

protected void Page_Load(object sender, EventArgs e)
    {
        int page = int.Parse("0" + Request.QueryString["page"]);
    if (page == 0) page = 1;
        if (!IsPostBack)
        {
            NapDuLieu(page, 10, 5);
        }
    }

Xem hàm Page_Load bạn thấy mình truyền giá trị 10 là số bản ghi hiển thị cho mỗi trang (rowperpage) và giá trị 5 là số trang hiển thị mỗi phân đoạn (@PageSize)
 
Bạn có thể download mã nguồn trang asp mình viết về tham khảo tại đây.

PhanTrangaspx.rar (1,92 kb)

Tham khảo thêm bài viết về phân trang trong Gridview

Chúc bạn thành công

Ví dụ về phân trang trong gridview

Trong bài này mình sẽ hướng dẫn các bạn viết phân trang đơn giản trong gridview. Với cách chọn trang hiển thị từ DropDownList. Trong ví dụ này hiển thị 10 bản ghi mỗi trang. Khi chọn trang từ DropDownList thì dữ liệu sẽ hiển thị theo trang được chọn. Bạn có thể xem demo tại đây

Dữ liệu minh họa mình lấy từ Access. Để làm phân trang như môt tả sau:

Để làm được điều đó bạn cần tạo gridview và tạo PageTemplate trong gridview.
Code trang asp.net như sau:

<%@ Page Language="C#" AutoEventWireup="true" 
CodeFile="Default.aspx.cs" Inherits="Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>hmweb.com.vn</title>
    <%--create by <a href="mailto:hungbv@hmweb.com.vn--%%3E%3C/head%3E%3Cbody%3E">hungbv@hmweb.com.vn--%>
</head>
<body>
</a>    <form id="form1" runat="server">
    <div style="text-align: center">
        <asp:Panel ID="Panel1" runat="server" 
        GroupingText="Ví dụ về phân trang Gridview"
            Width="610px">
        <asp:GridView id="CustomersGridView" 
        DataSourceID="AccessDataSource1"   
        autogeneratecolumns="False"
        allowpaging="True"
        ondatabound="CustomersGridView_DataBound"  
        runat="server" DataKeyNames="CustomerID" 
        BackColor="White" BorderColor="#CC9966" 
        BorderStyle="None" BorderWidth="1px" 
        CellPadding="4" Width="100%">
        <PagerStyle forecolor="#330099"
          backcolor="#FFFFCC" HorizontalAlign="Center"/>
        <PagerTemplate>
          <table width="100%">                    
            <tr>                        
              <td style="width:70%">

                <asp:Label id="MessageLabel"
                  forecolor="Blue"
                  text="Chọn trang:" 
                  runat="server"/>
                <asp:DropDownList id="PageDropDownList"
                  autopostback="true"
                  onselectedindexchanged = "PageDropDownList_SelectedIndexChanged" 
                  runat="server"/>
              </td>   
              <td style="width:70%; text-align:right">
                <asp:Label id="CurrentPageLabel"
                  forecolor="Blue"
                  runat="server"/>
              </td>
            </tr>                    
          </table>
        </PagerTemplate> 
          <Columns>
              <asp:BoundField DataField="CustomerID" 
              HeaderText="CustomerID" ReadOnly="True" 
              SortExpression="CustomerID" />
              <asp:BoundField DataField="CompanyName" 
              HeaderText="CompanyName" SortExpression="CompanyName" />
              <asp:BoundField DataField="Address" 
              HeaderText="Address" SortExpression="Address" />
              <asp:BoundField DataField="City" 
              HeaderText="City" SortExpression="City" />
          </Columns>
            <RowStyle BackColor="White" ForeColor="#330099" />
            <FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
            <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
            <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="#FFFFCC" />
      </asp:GridView>
        </asp:Panel>
        <asp:AccessDataSource ID="AccessDataSource1" 
        runat="server" DataFile="~/SP.mdb" 
        SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [Address], [City] FROM [Customers]">
        </asp:AccessDataSource>
    </div>
    </form>
</body>
</html>

Trong code behind bạn làm như sau:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void PageDropDownList_SelectedIndexChanged(Object sender, EventArgs e)
    {
        GridViewRow pagerRow = CustomersGridView.BottomPagerRow;
        DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
        // Thiết lập thuộc tính PageIndex Để hiển thị trang đuợc chọn.
        CustomersGridView.PageIndex = pageList.SelectedIndex;
    }

    protected void CustomersGridView_DataBound(Object sender, EventArgs e)
    {
        GridViewRow pagerRow = CustomersGridView.BottomPagerRow;
        DropDownList pageList = (DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
        Label pageLabel = (Label)pagerRow.Cells[0].FindControl("CurrentPageLabel");

        if (pageList != null)
        {
            for (int i = 0; i < CustomersGridView.PageCount; i++)
            {
                int pageNumber = i + 1;
                ListItem item = new ListItem(pageNumber.ToString());
                if (i == CustomersGridView.PageIndex)
                {
                    item.Selected = true;
                }
                pageList.Items.Add(item);
            }
        }

        if (pageLabel != null)
        {

            int currentPage = CustomersGridView.PageIndex + 1;
            // Cập nhật thông tin lable hiển thị trang
            pageLabel.Text = "Page " + currentPage.ToString() +
              " of " + CustomersGridView.PageCount.ToString();
        }
    }
}

Bạn có thể download mã nguồn về tham khảo

 

phantrang.rar (18,48 kb)

Kỹ thuật phân trang bằng Store Procedure

Bài này mình giới thiệu thuật toán trang bằng SQL với những tùy chọn hiển thị khác nhau.

Ở bài viết Phân trang trong SQL mình đã giới thiệu cách dùng Store để phân trang, Ở bài này mình sẽ giới thiệu thuật toán phân trang tối ưu hơn.
Giả sử bạn muốn trang web của bạn phân trang theo cách hiển thị như sau
Trang đầu Trang trước 2 3 [4] 5 6 Trang sau Trang cuối (Với số trang hiển thị =5 và đang hiển thị nội dung trang thứ 4, và mỗi trang 10 bản ghi)

1. Store trả về chuỗi hiển thị phân trang.
 Trước tiên bạn cần viết 1 hàm trả về chuỗi hiển thị phân trang. Hàm này có các biến truyền vào là:
@Total=Tổng số bản ghi truy vấn
@currPage=Trang hiện hàng
@PageSize=Số trang muốn hiển thị
@rowperpage = Số bản ghi trên 1 trang

Kết quả trả về của store này là chuỗi (html) hiển thị phân trang có dạng như sau:

EXEC [spPhanTrangSQL] 56,4,5, 10 (Demo với @Total=56, @currPage=4, @Pagesize=5, @rowperpage=10)
<a href="?page=1">Trang đầu</a> 
<a href="?page=3">Trang trước</a>
<a href="?page=2">2</a> 
<a href="?page=3">3</a> 
[4] 
<a href="?page=5">5</a> 
<a href="?page=6">6</a> 
<a href="?page=5">Trang sau</a> 
<a href="?page=6">Trang cuối</a>

 Store được viết như sau:

CREATE PROCEDURE [dbo].[spPhanTrangSQL]
@Total int,
@currPage int ,
@PageSize int,
@rowperpage int  
AS
BEGIN
DECLARE  @PageNumber int SET @PageNumber=1
DECLARE @i int
SET @i=1
DECLARE @TotalPage int
IF @Total%@rowperpage>0
SET @TotalPage=(@Total/@rowperpage)+1
ELSE
SET @TotalPage=@Total/@rowperpage 
DECLARE @Start int SET @Start=0
DECLARE @SQL nvarchar(4000)
SET @SQL=''
IF @currPage<=@TotalPage
BEGIN
    -- Xử lý trường hợp @currPage=1
    IF @currPage=1
    BEGIN
        SET @SQL=@SQL+ N'Trang '
        SET @PageNumber=@PageSize
        IF @PageNumber>@TotalPage SET @PageNumber=@TotalPage
        SET @Start=1
    END
    ELSE
    BEGIN
        SET @SQL=@SQL+ N' <a href="?page=1">Trang đầu</a>'
        SET @SQL=@SQL+ ' <a href="?page='+ 
            Cast((@currPage-1) AS nvarchar(4))+N'">Trang trước</a>'
        -- Xử lý trường hợp (@TotalPage-@currPage)<@PageSize/2
        IF(@TotalPage-@currPage)<@PageSize/2
           BEGIN
              SET @Start=(@TotalPage-@PageSize)+1
              IF @Start<0 SET @Start=1 
              SET @PageNumber = @TotalPage
           END
        ELSE
        BEGIN
            IF (@currPage-(@PageSize/2))=0
            BEGIN
                SET @Start=1
                SET @PageNumber=@currPage+(@PageSize/2)+1
                IF @TotalPage<@PageNumber
                    SET @PageNumber=@TotalPage
            END
            ELSE
               BEGIN
                  SET @Start=@currPage-(@PageSize/2)
                  IF @Start<0 SET @Start=1 
                  SET @PageNumber=@currPage+(@PageSize/2)
                  IF @TotalPage<@PageNumber
                      SET @PageNumber=@TotalPage
                  ELSE
                  IF @PageNumber <@PageSize 
                      SET @PageNumber=@PageSize
               END
        END
     END    

    SET @i=@Start
    WHILE @i<=@PageNumber
    BEGIN
        IF @i=@currPage
            SET @SQL=@SQL+'
             ['+Cast(Cast(@i AS int) AS nvarchar(4))+'] '
        ELSE
            SET @SQL=@SQL+'
             <a href="?page='+Cast(@i AS nvarchar(4))+'">'
                +Cast(@i AS nvarchar(4))+'</a> '
        SET @i=@i+1 
    END
    IF @currPage<@TotalPage
    BEGIN
        SET @SQL=@SQL+ N'
         <a href="?page='+Cast((@currPage+1) 
            AS nvarchar(4))+N'">Trang sau</a>'
         SET @SQL=@SQL+ N' 
             <a href="?page='+cast(@TotalPage AS nvarchar(6))+
              N'">Trang cuối</a>'
    END
    SELECT @SQL AS PhanTrang    
    -- PRINT @SQL
END
END

2. Store phân trang

Tiếp theo chúng ta sẻ dùng thủ tục trên vào việc phân trang dữ liệu. Thủ tục này  có các biến truyền vào:
@currpage=Trang hiện hành
@recodeperpage=Số bản ghi trên mỗi trang

@Pagesize=Số trang hiển thị phân trang
Thủ tục sẽ trả về dữ liệu là 2 bảng (Dùng dataset).

--CREATE BY webmaster@hmweb.com.vn
CREATE PROCEDURE [dbo].[spTB_TableName_PhanTrang]
@currPage int,
@recodperpage int,
@Pagesize int
AS
Begin
    Begin
    WITH s AS
    (
        SELECT ROW_NUMBER() 
            OVER(ORDER BY MaTruong,TenTruong) AS RowNum, 
            MaTruong, TenTruong
        FROM dbo.TB_TableName  
    )
    Select * From s 
    Where RowNum Between 
        (@currPage - 1)*@recodperpage+1 
            AND @currPage*@recodperpage
    END
    -- Tính tổng số bản ghi
    DECLARE @Tolal int
    SELECT @Tolal=Count(*) FROM TB_TableName

    EXEC spPhanTrangSQL @Tolal, @currPage,@Pagesize, 10
End

Sử dụng Store này bạn cần bind dữ liệu và Fill vào 1 DataSet, Sau đó thực hiện hiển thị dữ liệu phân trang. Bạn đọc bài viết Kỹ thuật phân trang bằng Store trong asp.net sẽ hướng dẫn bạn cách sử dụng Store trên

 

Hàm chuyển chuỗi có dấu (Unicode) thành không dấu

Bài này mình viết hàm chuyển một chuỗi ký tự có dấu (Unicode), chuyển thành chuỗi không dấu

Ứng dụng của hàm này bạn có thể tạo thêm một trường trong table của TB_BaiViet, để khi cần tạo liên kết  dạng http://blog.thuvienit.com/post/2010/11/19/Tao-mot-ham-ma-hoa-voi-T-SQL.aspx

CREATE FUNCTION [dbo].[fuChuyenCoDauThanhKhongDau]
(
      @strInput NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN    
    IF @strInput IS NULL RETURN @strInput
    IF @strInput = '' RETURN @strInput
    DECLARE @RT NVARCHAR(4000)
    DECLARE @SIGN_CHARS NCHAR(136)
    DECLARE @UNSIGN_CHARS NCHAR (136)
    SET @SIGN_CHARS = N'ăâđêôơưàảãạáằẳẵặắầẩẫậấèẻẽẹéềểễệế
                  ìỉĩịíòỏõọóồổỗộốờởỡợớùủũụúừửữựứỳỷỹỵý
                  ĂÂĐÊÔƠƯÀẢÃẠÁẰẲẴẶẮẦẨẪẬẤÈẺẼẸÉỀỂỄỆẾÌỈĨỊÍ
                  ÒỎÕỌÓỒỔỖỘỐỜỞỠỢỚÙỦŨỤÚỪỬỮỰỨỲỶỸỴÝ'
                  +NCHAR(272)+ NCHAR(208)
    SET @UNSIGN_CHARS = N'aadeoouaaaaaaaaaaaaaaaeeeeeeeeee
                  iiiiiooooooooooooooouuuuuuuuuuyyyyy
                  AADEOOUAAAAAAAAAAAAAAAEEEEEEEEEEIIIII
                  OOOOOOOOOOOOOOOUUUUUUUUUUYYYYYDD'
    DECLARE @COUNTER int
    DECLARE @COUNTER1 int
    SET @COUNTER = 1
    WHILE (@COUNTER <=LEN(@strInput))
    BEGIN  
      SET @COUNTER1 = 1
      --Tìm trong chuỗi mẫu
       WHILE (@COUNTER1 <=LEN(@SIGN_CHARS)+1)
       BEGIN
     IF UNICODE(SUBSTRING(@SIGN_CHARS, @COUNTER1,1))
            = UNICODE(SUBSTRING(@strInput,@COUNTER ,1) )
     BEGIN          
          IF @COUNTER=1
              SET @strInput = SUBSTRING(@UNSIGN_CHARS, @COUNTER1,1)
              + SUBSTRING(@strInput, @COUNTER+1,LEN(@strInput)-1)  
          ELSE
              SET @strInput = SUBSTRING(@strInput, 1, @COUNTER-1)
              +SUBSTRING(@UNSIGN_CHARS, @COUNTER1,1)
              + SUBSTRING(@strInput, @COUNTER+1,LEN(@strInput)- @COUNTER)
              BREAK
               END
             SET @COUNTER1 = @COUNTER1 +1
       END
      --Tìm tiếp
       SET @COUNTER = @COUNTER +1
    END
    SET @strInput = replace(@strInput,' ','-')
    RETURN @strInput
END

Ví dụ:

SELECT dbo.fuChuyenCoDauThanhKhongDau (N'Tạo một hàm mã hoá với T-SQL')

 --Sẽ trả về kết quả là

Tao-mot-ham-ma-hoa-voi-T-SQL