ADO.NET基本操作(CRUD、Procedure、Transaction)


模型沿用上篇博客所提到的學生、教師、課程,以詳細的代碼進行演示。

增刪改查

添加學生、教師、課程

using System.Data.SqlClient;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                string insertStudent = "insert into 學生表(studentname,gender,birthday) values('張三','" + (int)Gender.Male + "','" + DateTime.Parse("1989-6-1") + "')";
                SqlCommand cmd = new SqlCommand(insertStudent, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("添加學生成功");

                string insertTeacher = "insert into 教師表(teachername,gender,birthday) values('教師1','" + (int)Gender.Female + "','" + DateTime.Parse("1974-8-1") + "')";
                cmd = new SqlCommand(insertTeacher, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("添加教師成功");

                string[] insertSubjects = new string[]
                {
                    "insert into 課程表(subjectname) values('語文')",
                    "insert into 課程表(subjectname) values('數學')",
                    "insert into 課程表(subjectname) values('英語')",
                };

                for (int i = 0; i < insertSubjects.Length; i++)
                {
                    cmd = new SqlCommand(insertSubjects[i], conn);
                    cmd.ExecuteNonQuery();
                }

                Console.WriteLine("添加課程成功");
            }
        }
    }

    public enum Gender
    {
        Female, Male
    }
}

 

修改學生、教師

using System.Data.SqlClient;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                string modifyStudent = "update 學生表 set birthday='" + DateTime.Parse("1989-01-01") + "' where studentname = '張三'";
                SqlCommand cmd = new SqlCommand(modifyStudent, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("修改學生成功");

                string modifyTeacher = "update 教師表 set teachername = '教師' where teachername = '教師1'";
                cmd = new SqlCommand(modifyTeacher, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("修改教師成功");
            }
        }
    }
}

刪除學生、教師

using System.Data.SqlClient;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                string deleteStudent = "delete from 學生表 where studentname = '張三'";
                SqlCommand cmd = new SqlCommand(deleteStudent, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("刪除學生成功");

                string deleteTeacher = "delete from 教師表 where teachername = '教師'";
                cmd = new SqlCommand(deleteTeacher, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("刪除教師成功");
            }
        }
    }
}

添加教師授課信息

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                string teachername = "教師1", subjectname = "英語";
                string insert = @"declare @teacherid int,@subjectid int
set @teacherid = (select teacherid from 教師表 where teachername = '" + teachername + "')"
+ "set @subjectid = (select subjectid from 課程表 where subjectname = '" + subjectname + "')"
+ "insert into 教師課程表(teacherid, subjectid)"
+ "values(@teacherid, @subjectid)";
                SqlCommand cmd = new SqlCommand(insert, conn);
                cmd.ExecuteNonQuery();
                Console.WriteLine("添加教師課程成功");
            }
        }
    }

    public enum Gender
    {
        Female, Male
    }
}

可以看到,代碼中應用了嵌入T-SQL的方式,實現了給教師1添加英語教課的信息。

如果想查看教師教哪些課程,可以使用如下代碼:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                string query = @"select b.teachername,c.subjectname from 教師課程表 a 
inner join 教師表 b on a.teacherid = b.teacherid
inner join 課程表 c on a.subjectid = c.subjectid";
                SqlCommand cmd = new SqlCommand(query, conn);
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                sda.Fill(ds);

                if (ds != null && ds.Tables.Count > 0)
                {
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        Console.WriteLine("{0}授課課程名:{1}",dr["teachername"],dr["subjectname"]);
                    }
                }
            }
        }
    }
}

添加學生選課信息

原理與添加教師授課信息一樣,代碼不再重復。不過這里稍微講述一下原理。

ADO.NET執行的就是SQL,這個SQL可以是T-SQL,也可以是普通的SQL語句。添加教師授課信息執行的就是T-SQL。實際上,我們在實際開發當中,一般都會先在SQL Server

Management Studio開發工具中執行一下T-SQL,執行通過后再復制到ADO.NET程序中。

declare @studentid int,@subjectid int
set @studentid = (select studentid from 學生表 where studentname = '張三')
set @subjectid = (select subjectid from 課程表 where subjectname = '數學')
insert into 學生課程表(subjectid, studentid) values(@subjectid,@studentid)

存儲過程

存儲過程的優點至少有下面兩點:

1、  安全性高

相比C#后台代碼被反編譯,甚至瀏覽器端完全暴露的JS代碼來說,數據庫存儲過程代碼在數據庫中,不容易被SQL注入(除非本身存儲過程代碼寫的有問題),安全性高。

2、  執行效率高

首先節約了網絡傳輸的時間(傳輸的是存儲過程名,而不是長長的SQL語句)。其次存儲過程代碼都是經過數據庫預編譯的,節約了數據庫編譯SQL代碼的時間,直接執行存儲過程。

示例:通過存儲過程來添加課程信息

if exists (select * from sysobjects where name = 'add_subjects')
drop procedure add_subjects
go
create procedure add_subjects
@subjectname varchar(20),--輸入參數
@flag int output --輸出參數
as
begin
    insert into 課程表(subjectname) values(@subjectname);
    select @flag=@@ROWCOUNT --輸出參數的值
    return @flag--存儲過程返回值
end

需要說明的是,這個存儲過程add_subjects有兩個參數,分別為輸入參數subjectname、輸出參數flag。最后存儲過程還有一個return @flag,也就是存儲過程本身有一個返回值。

然后在C#代碼中調用這個存儲過程:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                SqlCommand cmd = new SqlCommand("add_subjects", conn);

                SqlParameter[] parameters = new SqlParameter[]
                {
                    new SqlParameter() { ParameterName="@subjectname", Value="歷史", Size=20, Direction = ParameterDirection.Input },
                    new SqlParameter() { ParameterName="@flag", Size = 4, Direction = ParameterDirection.Output }
                };
                cmd.Parameters.AddRange(parameters);
                cmd.CommandType = CommandType.StoredProcedure;
                int effectRows = cmd.ExecuteNonQuery();
                if (effectRows > 0)
                    Console.WriteLine("課程添加成功,輸出參數結果:" + parameters[1].Value);
            }
        }
    }
}

Parameters[1].Value對應存儲過程輸出參數@flag的值,effectRows對應存儲過程的返回值。

事務

如果在執行數據庫SQL操作時,不能保證多條SQL語句要么一起執行,要么不一起執行,就會造成數據不一致的情況。典型的例子就是銀行轉賬,A轉賬給B,如果A少了100元錢,但這時程序發生了錯誤,導致B並沒有收到100元錢,顯然這時候就需要一種機制保證這個轉賬的操作是一個整體。數據庫提出了事務這一概念來解決這一問題。

示例:一次性添加多門課程以及教師的信息

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString = "server=.;database=school;uid=sa;pwd=123456;";
                conn.Open();

                using (SqlCommand cmd = new SqlCommand() { Connection = conn })
                {
                    using (SqlTransaction trans = conn.BeginTransaction())
                    {
                        cmd.Transaction = trans;
                        try
                        {
                            string[] strs = new string[]
                            {
                                "insert into 課程表(subjectname) values('C#')",
                                "insert into 課程表(subjectname) values('.NET')",
                                "insert into 課程表(subjectname) values('ADO.NET')",
                                "insert into 教師表(teachername,gender,birthday) values('教師2','"+(int)Gender.Male+"','"+DateTime.Parse("1978-4-12")+"')",
                            };
                            foreach (string str in strs)
                            {
                                cmd.CommandText = str;
                                cmd.ExecuteNonQuery();
                            }
                            trans.Commit();
                            Console.WriteLine("事務執行成功");
                        }
                        catch (Exception ex)
                        {
                            trans.Rollback();
                            Console.WriteLine("事務執行失敗,錯誤信息:" + ex.Message);
                        }
                    }
                }
            }
        }
    }
    public enum Gender { Female, Male }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM