با سلام خدمت شما کاربران گرامی ، امیدوارم که شاد باشید.این درس آبجکت SqlCommand و چگونگی استفاده از آن برای تعامل با یک دیتابیس را توصیف می کند. در اینجا اهداف این درس را مشاهده می کنید:

· دانستن اینکه یک command object چیست.

· یادگیری چگونگی استفاده از متود ExecuteReader برای داده ی query.

· یادگیری چگونگی استفاده از متود ExecuteNonQuery برای وارد کردن و یا حذف داده.

· یادگیری چگونگی استفاده از متود ExecuteScalar برای گزارش یک مقدار مجزا.

مقدمه:

یک آبجکت SqlCommand به شما اجازه می دهد تا بدانید چه نوع تعاملی با یک دیتابیس می خواهید. برای مثال روی ردیف های داده در یک جدول دیتابیس، می توانید دستورات selsct، insert، modify و delete را انجام دهید. آبجکت SqlCommand می تواند برای پشتیبانی از سناریوهای سازماندهی داده ی غیرمتصل، استفاده شود، اما در این درس تنها از آبجکت SqlCommand استفاده می کنیم. درس بعدی در مورد SqlDataAdapter چگونگی اجرای برنامه ای را توضیح خواهد داد که از داده ی غیر متصل استفاده می کند. این درس همچنین به شما چگونگی بازیابی یک مقدار مجزا از یک دیتابیس ،مانند تعداد رکوردها در یک جدول، را نشان خواهد داد.

ایجاد یک آبجکت sqlcommand:

مشابه دیگر آبجکت های C#، یک آبجکت SqlCommand را از طریق اعلام نمونه ی جدید، نمونه گذاری کرده اید، مانند زیر:

SqlCommand cmd = new SqlCommand(“select CategoryName from Categories”, conn);

خط بالا نمونه ای برای نمونه گذاری آبجکت SqlCommand می باشد. این خط دارای یک رشته پارامتر است که فرمان مورد نظر شما برای اجرا را در خود حفظ می کند و نیز یک ارجاع به آبجکت SqlConnection. SqlCommand دارای بارگذاریهای کمی است که در مثال های این آموزش مشاهده خواهید کرد.

Querying Data:

هنگام استفاده از یک فرمان SQL select، یک مجموعه ی داده برای مشاهده بازیابی می کنید. برای تکمیل این کار با آبجکت SqlCommand، از متود ExecuteReader استفاده می کنید که آبجکت SqlDataReader را باز می گرداند. در مورد SqlDataReader در بخش بعد بحث خواهیم کرد. مثال زیر چگونگی استفاده از آبجکت SqlCommand را برای برقراری یک آبجکت SqlDataReader نشان می دهد:

‎// ۱٫ Instantiate a new command with a query and connection

SqlCommand cmd = new SqlCommand(“select CategoryName from Categories”, conn);

‎// ۲٫ Call Execute reader to get query results

SqlDataReader rdr = cmd.ExecuteReader();‎

در مثال بالا با انتقال رشته ی فرمان و آبجکت اتصال، یک آبجکت SqlCommand را نمونه گذاری کردیم. سپس با فراخوانی متود ExecuteReader از آبجکت SqlCommand،cmd، آبجکت SqlDataReader را برقرار کردیم.

این کد بخشی از متود ReadData از لیست ۱ در بخش Putting it All Together مربوط به این درس می باشد.

وارد کردن داده:

برای وارد کردن داده، از متود ExecuteNonQuery مربوط به آبجکت SqlCommand استفاده کنید. کد زیر چگونگی وارد کردن داده به یک جدول دیتابیس را نشان می دهد:

‎// prepare command string

‎ string insertString = @”

‎ insert into Categories

‎ (CategoryName, Description)

‎ values (‘Miscellaneous’, ‘Whatever doesn”t fit elsewhere’)”;

‎ // ۱٫ Instantiate a new command with a query and connection

‎ SqlCommand cmd = new SqlCommand(insertString, conn);

‎ // ۲٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();‎

نمونه گذاری SqlCommand فقط کمی متفاوت از آنچه قبلا دیده اید می باشد، اما اساسا همان است. به جای یک رشته ی دقیق به عنوان اولین پارامتر سازنده ی SqlCommand، ما در حال استفاده از متغیر insertString هستیم. متغیر insertString درست در بالای اعلان SqlCommand بیان می شود.

به در آپاستروف (”) در متن insertString برای لغت “doesn”t” دقت کنید. این روشی است که از طریق آن از آپاسترف ها رها می شوید و می توانید ستون را به درستی پر کنید.

مشاهده ی دیگری در مورد فرمان insert این است که ستون های columns CategoryName و Description را به طور واضح مشخص کرده ایم. جدول Categories table دارای یک فیلد کلید اولیه به نام CategoryID می باشد. این بخش را خارج از لیست رها می کنیم زیرا خود SQL Server این بخش را اضافه خواهد کرد. در هنگام سعی برای افزودن یک مقدار به فیلد کلید اولیه، مقداری مانند CategoryID، یک استثنا تولید خواهد شد.

برای اجرای این فرمان، به سادگی متود ExecuteNonQuery را روی نمونه ی SqlCommand instance, cmd فرا می خوانیم.

این کد بخشی از متود Insertdata در لیست ۱ در بخش Putting it All Together می باشد.

آپدیت کردن داده:

متود ExecuteNonQuery برای آپدیت کردن داده استفاده می شود. کد زیر چگونگی آپدیت کردن یک داده را نشان می دهد:

‎// prepare command string

‎ string updateString = @”

‎ update Categories

‎ set CategoryName = ‘Other’

‎ where CategoryName = ‘Miscellaneous'”;

‎ // ۱٫ Instantiate a new command with command text only

‎ SqlCommand cmd = new SqlCommand(updateString);

‎ // ۲٫ Set the Connection property

‎ cmd.Connection = conn;

‎ // ۳٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();‎

مجددا فرمان SQL را در یک متغیر رشته قرار می دهیم، اما این بار از یک سازنده ی متفاوت SqlCommand استفاده کرده ایم که فقط دستور را می گیرد. در مرحله ی دوم آبجکت SqlConnection، conn را به پراپرتی اتصال از آبجکت SqlCommand object, cmd اختصاص می دهیم.

این کار می تواند توسط همان سازنده ی مورد استفاده برای فرمان insert با دو پارامتر استفاده شود، و توضیح می دهد که می توانید آبجکت اتصال اختصاص داده شده به یک دستور را در هر زمانی تغییر دهید.

متود ExecuteNonQuery فرمان آپدیت را اجرا می کند.

این کد بخشی از متود UpdateData از لیست ۱ در بخش Putting it All Together از این درس می باشد.

حذف داده:

می توانید با استفاده از متود ExecuteNonQuery داده را نیز حذف کنید. مثال زیر چگونگی حذف یک رکورد از یک دیتابیس را متود ExecuteNonQuery نشان می دهد.

‎// prepare command string

‎ string deleteString = @”

‎ delete from Categories

‎ where CategoryName = ‘Other'”;

‎ // ۱٫ Instantiate a new command

‎ SqlCommand cmd = new SqlCommand();

‎ // ۲٫ Set the CommandText property

‎ cmd.CommandText = deleteString;

‎ // ۳٫ Set the Connection property

‎ cmd.Connection = conn;

‎ // ۴٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();‎

این مثال از سازنده ی و بدون هیچ پارامتری استفاده می کند. در عوض پراپرتی های CommandText و Connection از آبجکت SqlCommand را به طور واضح تنظیم می کند.

همچنین می توانیم از بارگذاری دو سازنده ی SqlCommand قبل استفاده کنیم، که برای فرمان insert یا update استفاده می شود، و دارای همان نتیجه می باشد. این توضیح می دهد که می توانید هم متن فرمان و هم آبجکت اتصال را هر زمانی تغییر دهید.

فراخوانی متود ExecuteNonQuery فرمان را به دیتابیسارس ال می کند.

این کد بخشی از متود DeleteData از لیست ۱ در بخش Putting it All Together می باشد.

دریافت مقادیر مجزا:

گاهی اوقات تمام آنچه از یک دیتابیس لازم دارید، یک مقدار مجزا می باشد که می تواند یک محاسبه (count)، مجموع (sum)، میانگین (average) یا دیگر مقادیر تلفیقی از یک مجموعه ی داده باشد. اجرای یک ExecuteReader و محاسبه ی نتیجه در کد شما موثرترین راه برای انجام این کار نیست. بهترین انتخاب این است که به دیتابیس اجازه بدهید تا کار را اجرا کرده و تنها مقدار مورد نیاز شما را بازگرداند. مثال زیر چگونگی انجام این کار را با متود ExecuteScalar نشان می دهد:

‎// ۱٫ Instantiate a new command

‎ SqlCommand cmd = new SqlCommand(“select count(*) from Categories”, conn);

‎ // ۲٫ Call ExecuteNonQuery to send command

‎ int count = (int)cmd.ExecuteScalar();‎

Query در سازنده ی SqlCommand محاسبه ی تمام رکوردهای جدول Categories را برقرار می سازد.این query فقط یک مقدار مجزا را گزارش خواهد داد. متود ExecuteScalar در مرحله ی ۲ نیز این مقدار را باز می گرداند. از آنجایی که نوع بازگشت ExecuteScalar از نوع آبجکت می باشد، از اپزاتور cast برای تبدیل مقدار به int استفاده می کنیم.

این کد بخشی از متود GetNumberOfRecords از لیست ۱ در بخش Putting it All Together از این درس می باشد.

Putting it All Together

برای سادگی قسمت هایی از کد را در بخش های قبلی برای توضیح تکنیک های مناسب نمایش دادیم. همچنین داشتن یک لیست کلی از کد برای مشاهده ی چگونگی استفاده ازاین کد در یک برنامه ی اجرایی مفید می باشد. لیست ۱ همه ی کد استفاده شده در این مثال را، به همراه یک درایو در متود Main برای تولید خروجی قالب بندی شده، نشان می دهد.

Listing 1. SqlConnection Demo

‎ using System;

‎ using System.Data;

‎ using System.Data.SqlClient;

‎ ///

‎ /// Demonstrates how to work with SqlCommand objects

‎ ///

‎ class SqlCommandDemo

‎ {

‎ SqlConnection conn;

‎ public SqlCommandDemo()

‎ {

‎ // Instantiate the connection

‎ conn = new SqlConnection(

‎ “Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI”);

‎ }

‎ // call methods that demo SqlCommand capabilities

‎ static void Main()

‎ {

‎ SqlCommandDemo scd = new SqlCommandDemo();

‎ Console.WriteLine();

‎ Console.WriteLine(“Categories Before Insert”);

‎ Console.WriteLine(“————————“);

‎ // use ExecuteReader method

‎ scd.ReadData();

‎ // use ExecuteNonQuery method for Insert

‎ scd.Insertdata();

‎ Console.WriteLine();

‎ Console.WriteLine(“Categories After Insert”);

‎ Console.WriteLine(“——————————“);

‎ scd.ReadData();

‎ // use ExecuteNonQuery method for Update

‎ scd.UpdateData();

‎ Console.WriteLine();

‎ Console.WriteLine(“Categories After Update”);

‎ Console.WriteLine(“——————————“);

‎ scd.ReadData();

‎ // use ExecuteNonQuery method for Delete

‎ scd.DeleteData();

‎ Console.WriteLine();

‎ Console.WriteLine(“Categories After Delete”);

‎ Console.WriteLine(“——————————“);

‎ scd.ReadData();

‎ // use ExecuteScalar method

‎ int numberOfRecords = scd.GetNumberOfRecords();

‎ Console.WriteLine();

‎ Console.WriteLine(“Number of Records: {0}”, numberOfRecords);

‎ }

‎ ///

‎ /// use ExecuteReader method

‎ ///

‎ public void ReadData()

‎ {

‎ SqlDataReader rdr = null;

‎ try

‎ {

‎ // Open the connection

‎ conn.Open();

‎ // ۱٫ Instantiate a new command with a query and connection

‎ SqlCommand cmd = new SqlCommand(“select CategoryName from Categories”, ‎conn);

‎ // ۲٫ 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();

‎ }

‎ }

‎ }

‎ ///

‎ /// use ExecuteNonQuery method for Insert

‎ ///

‎ public void Insertdata()

‎ {

‎ try

‎ {

‎ // Open the connection

‎ conn.Open();

‎ // prepare command string

‎ string insertString = @”

‎ insert into Categories

‎ (CategoryName, Description)

‎ values (‘Miscellaneous’, ‘Whatever doesn”t fit elsewhere’)”;

‎ // ۱٫ Instantiate a new command with a query and connection

‎ SqlCommand cmd = new SqlCommand(insertString, conn);

‎ // ۲٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();

‎ }

‎ finally

‎ {

‎ // Close the connection

‎ if (conn != null)

‎ {

‎ conn.Close();

‎ }

‎ }

‎ }

‎ ///

‎ /// use ExecuteNonQuery method for Update

‎ ///

‎ public void UpdateData()

‎ {

‎ try

‎ {

‎ // Open the connection

‎ conn.Open();

‎ // prepare command string

‎ string updateString = @”

‎ update Categories

‎ set CategoryName = ‘Other’

‎ where CategoryName = ‘Miscellaneous'”;

‎ // ۱٫ Instantiate a new command with command text only

‎ SqlCommand cmd = new SqlCommand(updateString);

‎ // ۲٫ Set the Connection property

‎ cmd.Connection = conn;

‎ // ۳٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();

‎ }

‎ finally

‎ {

‎ // Close the connection

‎ if (conn != null)

‎ {

‎ conn.Close();

‎ }

‎ }

‎ }

‎ ///

‎ /// use ExecuteNonQuery method for Delete

‎ ///

‎ public void DeleteData()

‎ {

‎ try

‎ {

‎ // Open the connection

‎ conn.Open();

‎ // prepare command string

‎ string deleteString = @”

‎ delete from Categories

‎ where CategoryName = ‘Other'”;

‎ // ۱٫ Instantiate a new command

‎ SqlCommand cmd = new SqlCommand();

‎ // ۲٫ Set the CommandText property

‎ cmd.CommandText = deleteString;

‎ // ۳٫ Set the Connection property

‎ cmd.Connection = conn;

‎ // ۴٫ Call ExecuteNonQuery to send command

‎ cmd.ExecuteNonQuery();

‎ }

‎ finally

‎ {

‎ // Close the connection

‎ if (conn != null)

‎ {

‎ conn.Close();

‎ }

‎ }

‎ }

‎ ///

‎ /// use ExecuteScalar method

‎ ///

‎ /// number of records

‎ public int GetNumberOfRecords()

‎ {

‎ int count = -1;

‎ try

‎ {

‎ // Open the connection

‎ conn.Open();

‎ // ۱٫ Instantiate a new command

‎ SqlCommand cmd = new SqlCommand(“select count(*) from Categories”, conn);

‎ // ۲٫ Call ExecuteScalar to send command

‎ count = (int)cmd.ExecuteScalar();

‎ }

‎ finally

‎ {

‎ // Close the connection

‎ if (conn != null)

‎ {

‎ conn.Close();

‎ }

‎ }

‎ return count;

‎ }

‎ }‎

در لیست ۱، آبجکت SqlConnection در ساختارSqlCommandDemo نمونه گذاری می شود. این مسئله بسیار خوب است، زیرا خود آبجکت در هنگام اجرای CLR garbage collector تمیز خواهد شد. آنچه مهم است این است که ما اتصال را در هنگام اتمام استفاده از آن، می بندیم. این برنامه اتصال را در هر متود در یک try block باز می کند و در یک finally block می بندد.

متود ReadData محتوای ستون CategoryName از جدول Categories را نشان می دهد. از آن بارها در متود Main برای نشان دادن وضعیت جاری جدول Categoriesاستفاده کردیم، که پس از هر فرمان insert، update و delete تغییر می کند. به خاطر این مسئله استفاده ی مجدد از آن مناسب می باشد تا تاثیرات پس از فراخوانی هر متود را به شما نشان دهیم.

خلاصه:

یک آبجکت SqlCommand به شما اجازه می دهد تا فرمان ها را تنظیم و به یک دیتابیس ارسال کنید. این آبجکت دارای متودهایی است که به فرمان های مختلف اختصاص داده شده اند. متود ExecuteReader یک آبجکت SqlDataReader را برای مشاهده ی نتایج یک select query بازمی گرداند. برای فرمان های insert، update و delete در SQL از متود ExecuteNonQuery استفاده می کنید. اگر تنها به یک مقدار مجزا از یک query احتیاج دارید، ExecuteScalar بهترین انتخاب می باشد.

امیدوارم از این بخش لذت برده باشید و به شما به بخش بعدی Lesson 04: Reading Data with the SqlDataReader در این مجموعه خوش آمد می گویم.