آموزش سی شارپ-آموزش دستورات پایگاه داده

سلام با آموزش برنامه نویسی سی شارپ قسمت یازدهم در خدمت شما عزیزان هستیم, در قسمت قبلی با اتصال به SQL Server در C# آشنا شدیم. با ادامه آموزش سی شارپ همراه ما باشید.لينك قسمت اول : آموزش #Cاجرای دستورات پایگاه داده در سی شارپ (SqlCommand)همانطور که پیش از این در آموزش پایگاه داده در سی شارپ گفتیم برای اجرای دستورات پایگاه داده بایستی پس از اتصال به پایگاه داده دستور مربوطه را در قالب یک شی SqlCommand از طریق اتصال ایجاد شده توسط SqlConnection اجرا کنیم. در این بخش از آموزش ADO.NET در سی شارپ به بررسی روش انجام این کار خواهیم پرداخت.شی SqlCommand:این درس درباره ی SqlCommand object بوده و نشان می دهد که برای تبادل داده و تعامل با یک پایگاه داده چگونه از این شی استفاده می شود. اهداف این درس به شرح زیر می باشندشی Command چیست؟چگونه از متد ExecuteReader برای Query گرفتن از داده ها استفاده کنیم؟چگونه با استفاده از متد ExecuteNonQuery برای درج یا حذف داده ها استفاده کنیم؟چگونه از متد ExecuteScalar برای بازگرداندن یک مقدار واحد استفاده کنیم؟مقدمهشی SqlCommand به شما این امکان را می دهد تا شکل رفتار خود با پایگاه داده را مشخص نمایید. به عبارت دیگر مشخص کنید که چه نوع عملیاتی را می خواهید بر روی پایگاه داده انجام دهید. برای مثال، می توان عملیات delete، select، modify، و insert را بر روی رکوردهای داده در یک جدول پایگاه داده انجام داد. شی SqlCommand می تواند برای پشتیبانی از سناریوهای مدیریتِ داده هایی که در دسترس نیستند(disconnected data) مورد استفاده قرار گیرد، اما در این درس قصد بر این است که شی SqlCommand را به تنهایی مورد استفاده قرار دهیم. درس بعدی که در رابطه با SqlDataAdapter است، توضیح خواهد داد که چگونه یک Application را که از داده های Disconnected استفاده می کند، پیاده سازی نماییم. این درس همچنین چگونگی بازیابی یک مقدار واحد، مثل تعداد رکوردها در جدول را نشان می دهد. https://www.aparat.com/v/s6AOp ایجاد یک شی SqlCommandمشابه دیگر شی های سی شارپ، یک شی SqlCommand به صورت زیر، ساخته می شود:SqlCommand cmd = new SqlCommand(&quotselect CategoryName from Categories&quot, conn);کد بالا برای شی های SqlCommandرایج می باشد. این کد یک آرگومان رشته ای (String Parameter ) را دریافت کرده که در بردارنده ی فرمانی است که در صدد اجرای آن بوده و نیز حاویِ اشاره گر (reference) به SqlConnection می باشد. SqlCommand دارای تعدادی نسخه ی Overload شده است که در طول این دوره آموزشی، عنوان خواهد شد.کوئری Query گرفتن از داده ها (Querying Data)به هنگام استفاده از SQL، با دستور select دسته ای از داده ها برای مشاهده بازیابی می گردند. برای تکمیل این کار با یک شی SqlCommand، از متد ExcecuteReader که شی SqlDataReader را بازمی گرداند، استفاده نمایید. در درس آینده SqlDataReader را بحث خواهیم کرد. مثال پایین چگونگی استفاده از شی SqlCommand برای دستیابی به شی SqlDataReader را نشان می دهد.// 1. Instantiate a new command with a query and connectionSqlCommand cmd = new SqlCommand (&quotselect CategoryName from Categories&quot, conn); // 2. Call Execute reader to get query resultsSqlDataReader rdr = cmd.ExecuteReader();در مثال بالا یک نمونه از شی SqlCommand ساخته سپس "متن دستور SQL" و شی SqlConnection را به عنوان آرگومان به متد سازنده آن (Constructor) ارسال می کنیم. سپس با فراخوانی متد ExecuteReader از شی SqlCommand (که در بالا cmd نام گذاری کردیم) یک شی SqlDataReader به دست می آوریم.این کد بخشی از متد ReadData مربوط به لیست 1 است که در ادامه ی این مبحث و در بخش جمع بندی به آن خواهیم پرداخت.عملیات درج داده ها (Inserting Data)به منظور درج داده ها در پایگاه داده، از متدِ ExecuteNonQuery مربوط به شی SqlCommand استفاده نمایید. کد پیش رو نشان می دهد که چگونه داده ها را در یک پایگاه داده درج نماییم.// prepare command stringstring insertString = @&quotinsert into Categories (CategoryName, Description) Values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')" // 1. Instantiate a new command with a query and connectionSqlCommand cmd = new SqlCommand(insertString, conn); // 2. Call ExecuteNonQuery to send commandcmd.ExecuteNonQuery();روش نمونه سازی از SqlCommand اندکی با روشی که قبلا انجام دادیم تفاوت دارد، اما در اصل و پایه یکسان هستند. به جای استفاده از مقدار ثابت رشته ای Literal String)) به عنوان اولین آرگومان سازنده ی SqlCommand، از یک متغیر به نام InsertString استفاده می گردد. همان طور که در کد مشاهده می کنید، متغیر InsertString درست در بالای تعریف SqlCommand اعلان شده است.به دو عدد تک کوتیشن (") در متنِ Insert String در بالای کلمه ی “doesn”t” دقت نمایید. با استفاده از این کاراکتر اطمینان حاصل می کنیم که ستون های جدول پایگاه داده به طور صحیح با مقدار رشته ای مزبور پر می شود و هر گونه ابهام که ممکن است بر اثر استفاده از کوتیشن به وجود آمده باشد، برطرف می گردد.نکته ی دیگری که باید به آن اشاره کرده و توضیحی ارایه بدهیم این است که در کد بالا صراحتا نام ستون های Category و Description را از جدول Category ذکر (مشخص) کردیم. جدول Category یک فیلد Primary Key به نام CategoryID دارد. از آنجایی که خودِ SQL Server این فیلد را اضافه خواهد کرد، آن را در لیست لحاظ نکردیم. در صورت تلاش برای افزودن یک مقدار به فیلد Primary Key، مثل CategoryID، با خطا (Exception) مواجه خواهید شد.برای اجرای این فرمان، کافی است از متد ExecuteNonQuery بر روی نمونه ی SqlCommand، که cmd نام دارد، استفاده کنیم. این کد بخشی از متد Insert Data است که در بخش جمع بندی بررسی خواهیم نمود.متد ExecuteNonQuery برای به روز رسانی داده ها نیز استفاده می شود. کدهای زیر نشان می دهند که داده ها چگونه به روز رسانی می شوند:// prepare command stringstring updateString = @&quotupdate Categories set CategoryName = 'Other' where CategoryName = 'Miscellaneous'" // 1. Instantiate a new command with command text onlySqlCommand cmd = new SqlCommand(updateString); // 2. Set the Connection propertycmd.Connection = conn; // 3. Call ExecuteNonQuery to send commandcmd.ExecuteNonQuery();مجددا، فرمان SQL را درون یک متغیر رشته ای (String Variable) قرار می دهیم، اما این بار از یک سازنده ی متفاوتِ SqlCommand استفاده می کنیم که تنها دستور را دریافت می کند. در گام دوم، شی ِconn را به ویژگی (property) مربوط به شی cmd تخصیص می دهیم. این کار را می توانستیم به وسیله ی تابع سازنده ای (Constructor) که برای دستور Insert استفاده شد به همراه دو پارامتر ورودی نیز انجام دهیم. این روش در واقع به این امر اشاره دارد که می توان یک شی Connection (اتصال به پایگاه داده) را که برای یک فرمان خاص تخصیص یافته، در هر زمانی تغییر داد.متد ExecuteNonQuery دستور یا عملیات Update را اجرا می کند. این کد بخشی از Update Data مربوط به لیست دستور 1 است که در بخش بعدی در مورد آن صحبت خواهیم کرد. https://www.aparat.com/v/ogjMA حذف داده ها (Deleting Data)با استفاده از متد ExecuteNonQuery می توان داده ها را حذف نیز نمود. مثال پایین نشان می دهد که چگونه می توان با استفاده از این متد، یک سطر (Record) را از پایگاه داده حذف نمود.// prepare command stringstring deleteString = @&quotdelete from Categories where CategoryName = 'Other'" // 1. Instantiate a new commandSqlCommand cmd = new SqlCommand(); // 2. Set the CommandText propertycmd.CommandText = deleteString; // 3. Set the Connection propertycmd.Connection = conn; // 4. Call ExecuteNonQuery to send commandcmd.ExecuteNonQuery();در مثال فوق از متد سازنده ی SqlCommand بدون ارسال پارامتر ورودی به آن، استفاده شده است. در عوض، Property یا خصوصیت های CommandText و Connection از شی SqlCommand را به صورت صریح مقداردهی (set) کرده است. همچنین می توان از هر کدام از دو حالت overload شده سازنده SqlCommand قبلی که برای فرمان Insert و یا به روز رسانی استفاده شده اند، با نتایج یکسانی استفاده نمود. این مساله نشان می دهد که می توان در هر زمانی هم متن فرمان(Command Text) و هم شی اتصال (Connection Object) را تغییر داد. متد Execute Non Query، فرمان را به پایگاه داده انتقال می دهد. این کد بخشی از متد DeleteData است که در بخش بعدی درباره ی آن صحبت خواهیم کرد.آموزش سی شارپبه دست آوردن مقادیر مجزا (Single Values)گاهی اوقات تمام آنچه که از پایگاه داده نیاز دارید یک مقدار واحد است که می تواند عبارت باشد از محاسبه (count)، جمع بندی(sum) ، میانگین (average)، و یا دیگر مقادیر معین شده در مجموعه ی داده ها (Data Set). برای نیل به این هدف، اجرای متد ExecuteReader و محاسبه ی نتایج در کد، شیوه ی کارآمدی نخواهد بود. بهترین انتخاب این است که به پایگاه داده اجازه داده شود این کار را انجام دهد و رقم مجزایی که نیاز دارید را برگرداند. مثال پایین نشان می دهد که چگونه می توان این کار را با متد ExecuteScalar انجام داد:// 1. Instantiate a new commandSqlCommand cmd = new SqlCommand(&quotselect count(*) from Categories&quot, conn); // 2. Call ExecuteNonQuery to send commandint count = (int)cmd.ExecuteScalar();کوئری Query گرفتن از داده ها در سازنده ی SqlCommand، شمارشِ تمامی رکوردها از جدول دسته بندی (Category Table) را به دست می آورد. این Query تنها یک مقدار واحد را برمی گرداند. متد ExecuteScalar در گام دوم، این مقدار را باز می گرداند. از آنجایی که نوع خروجی ExecuteScalar گونه داده ای Object می باشد، از عبارت (int) پیش از آن برای تبدیل مقدار به مقدار عددی صحیح استفاده می گردد.جمع بندیدر بخش های قبلی، برای راحتی در نشان دادنِ تکنیک های کاربردی، بخش های کوچکی از کدها ارایه شد. برای مشاهده ی اینکه چگونه این کدها در یک برنامه ی کاربردی مورد استفاده قرار می گیرند، فراهم نمودن لیست کدهای کامل نیز مفید خواهد بود. در اینجا تمامی کدهای مورد استفاده در این مثال را به همراه درایوی در متد اصلی (Main method) برای تولید خروجی های شکل گرفته (formatted output)، نشان می دهد.using System;using System.Data;using System.Data.SqlClient; /// <summary>/// Demonstrates how to work with SqlCommand objects/// </summary>class SqlCommandDemo{ SqlConnection conn; public SqlCommandDemo() { // Instantiate the connection conn = new SqlConnection(&quotData Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI&quot); } // call methods that demo SqlCommand capabilities static void Main() { SqlCommandDemo scd = new SqlCommandDemo(); Console.WriteLine(); Console.WriteLine(&quotCategories Before Insert&quot); Console.WriteLine(&quot------------------------&quot); // use ExecuteReader method scd.ReadData(); // use ExecuteNonQuery method for Insert scd.Insertdata(); Console.WriteLine(); Console.WriteLine(&quotCategories After Insert&quot); Console.WriteLine(&quot------------------------------&quot); scd.ReadData(); // use ExecuteNonQuery method for Update scd.UpdateData(); Console.WriteLine(); Console.WriteLine(&quotCategories After Update&quot); Console.WriteLine(&quot------------------------------&quot); scd.ReadData(); // use ExecuteNonQuery method for Delete scd.DeleteData(); Console.WriteLine(); Console.WriteLine(&quotCategories After Delete&quot); Console.WriteLine(&quot------------------------------&quot); scd.ReadData(); // use ExecuteScalar method int numberOfRecords = scd.GetNumberOfRecords(); Console.WriteLine(); Console.WriteLine(&quotNumber of Records: {0}&quot, numberOfRecords); } /// <summary> /// use ExecuteReader method /// </summary> public void ReadData() { SqlDataReader rdr = null; try { // Open the connection conn.Open(); // 1. Instantiate a new command with a query and connection SqlCommand cmd = new SqlCommand(&quotselect CategoryName from Categories&quot, conn); // 2. Call Execute reader to get query results rdr = cmd.ExecuteReader(); // print the CategoryName of each record while (rdr.Read()) { Console.WriteLine(rdr[0]); } } finally { // close the reader if (rdr != null) { rdr.Close(); } // Close the connection if (conn != null) { conn.Close(); } } } /// <summary> /// use ExecuteNonQuery method for Insert /// </summary> public void Insertdata() { try { // Open the connection conn.Open(); // prepare command string string insertString = @&quotinsert into Categories (CategoryName, Description) values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')" // 1. Instantiate a new command with a query and connection SqlCommand cmd = new SqlCommand(insertString, conn); // 2. Call ExecuteNonQuery to send command cmd.ExecuteNonQuery(); } finally { // Close the connection if (conn != null) { conn.Close(); } } } /// <summary> /// use ExecuteNonQuery method for Update /// </summary> public void UpdateData() { try { // Open the connection conn.Open(); // prepare command string string updateString = @&quotupdate Categories set CategoryName = 'Other' where CategoryName = 'Miscellaneous'" // 1. Instantiate a new command with command text only SqlCommand cmd = new SqlCommand(updateString); // 2. Set the Connection property cmd.Connection = conn; // 3. Call ExecuteNonQuery to send command cmd.ExecuteNonQuery(); } finally { // Close the connection if (conn != null) { conn.Close(); } } } /// <summary> /// use ExecuteNonQuery method for Delete /// </summary> public void DeleteData() { try { // Open the connection conn.Open(); // prepare command string string deleteString = @&quotdelete from Categories where CategoryName = 'Other'" // 1. Instantiate a new command SqlCommand cmd = new SqlCommand(); // 2. Set the CommandText property cmd.CommandText = deleteString; // 3. Set the Connection property cmd.Connection = conn; // 4. Call ExecuteNonQuery to send command cmd.ExecuteNonQuery(); } finally { // Close the connection if (conn != null) { conn.Close(); } } } /// <summary> /// use ExecuteScalar method /// </summary> /// <returns>number of records</returns> public int GetNumberOfRecords() { int count = -1; try { // Open the connection conn.Open(); // 1. Instantiate a new command SqlCommand cmd = new SqlCommand(&quotselect count(*) from Categories&quot, conn); // 2. Call ExecuteScalar to send command count = (int)cmd.ExecuteScalar(); } finally { // Close the connection if (conn != null) { conn.Close(); } } return count; }}در برنامه بالا، شی SqlConnection در SqlCommandDemo نمونه سازی شده است. این کار مشکلی ندارد زیرا زمانی که زباله جمع کنِ CLR اجرا می شود، خودِ شی پاکسازی خواهد شد. مهمترین مساله این است که پس از اتمام کار، حتما اتصال را قطع نماییم. در همه ی متدها، این برنامه اتصال را در یک قطعه کد (try block) try برقرار نموده و در یک final block قطع می نماید. متد ReadData، محتوای ستونِ CategoryName را در جدول دسته بندی (Category Table) نشان می دهد. برای نشان دادن وضعیت فعلی جدول دسته بندی (Category Table)، که پس از هر یک از فرمان های delete، insert، و update عوض می شود، بارها از این متد استفاده می نماییم. به همین دلیل، استفاده ی مجدد به منظور نشان دادنِ تاثیراتِ هر متد، کاری راحت خواهد بود.خلاصهشی SqlCommand به شما این اجازه را می دهد که از داده ها Query گرفته یا فرمانی را به دیتابس ارسال نمایید. این شی متدهایی دارد که برای فرمان های مختلفی تخصیص داده شده اند. متد ExecuteReader یک شی SqlDataReader را برای مشاهده ی نتایجِ یک کوئریِ (select query)، بر می گرداند. برای فرمان های Sql مربوط به insert، update، و delete، از متد ExecuteNonQuery استفاده می شود. اگر تنها به یک رقم مجموع و واحد از یک Query نیاز داشته باشیم، متد ExecuteScalar بهترین گزینه خواهد بود.پايان قسمت یازدهمآموزش سي شارپ