درباره نویسنده

Hamid J. Fard

Hamid J. Fard

متخصص پایگاه داده SQL Server دارای مدارک معتبر مایکروسافت از قبیلMicrosoft Certified Master: SQL Server 2008 و Microsoft Certified Solutions Master: Charter - Data Platform. من در گروههای کاربران SQL Server در کشور مالزی و سنگاپور به صورت فعال صحبت و آموزش می دهم.

15 Comments

  1. مجتبی شهریور

    مجتبی شهریور

       سلام مقالتون را خوندم عالی بود جدا از تشکر ار حضرتعال از تیم محترم نیک آموز هم  متشکرم بخاطر فراهم کردن حضور افرادی با سطح علمی شما با مقالات خوبتون در سایت

    پاسخ دادن
    1. Hamid J. Fard

      Hamid J. Fard

          ممنون مجتبی جان. به امید دیدار.

      پاسخ دادن
    1. مسعود طاهری

      مسعود طاهری

          سلام

      در تکمیل این مقاله خوب لینک زیر اطلاعات تکمیل کننده ای هم به دوستان ارائه می کند

      پاسخ دادن
  2. تورج عزیزی

       Great Article!
    دو سوال:

    ۱) آیا SELECT INTO یک تراکنش به حساب میاد یا هر INSERT یک تراکنش جداست؟
    ۲) اگر در حین اجرا SELECT INTO، حالت Crash رخ بده تراکنش Uncommited محسوب میشه،
     در این صورت ، SQL Server چطور تشخیص میده که کدوم رکورد ها مربوط به SELECT INTO است؟ (چون در حین ثبت لاگ برای SELECT INTO، برای Insert های تراکنش های دیگر که Comiit شدن هم لاگ ثبت میشه (با لاگ SELECT INTO  تداخل پیدا می کنه))

    پاسخ دادن
    1. Hamid J. Fard

      Hamid J. Fard

          تورج: عذر می خوام بابت اینکه دیر شد جواب بدم. امروز به کلی سرم شلوغ بود.

      ۱- هر Insert در Select Into یک تراکنش جدا هستش و خود آن تراکنش به صورت Implicit است یعنی به خودیه خود Commit می شود.
      ۲- تراکنشها تا قبل از Crash به عنوان Commited حساب می شوند ولی تراکنشهایی که همزمان با Crash مواجه شده اند به دلیل آنکه Commit شده اند در زمان Undo به unCommitted تبدیل شده یا به عبارت دیگری Rollback می شوند.
      ۳- Select Into خود یک تراکنش پدر است که تمامی تراکنش های Insert به صورت Implicit داخل آن است. ولی برای Rollback کرد آن باید یک تراکنش به صورت Explicit ساخته شود.
      پاسخ دادن
  3. تورج عزیزی

    تورج عزیزی

       یک سوال دیگه اینکه آیا تنظیم Isolation Level برای این دستور هم ممکنه؟
    یعنی اینکه آیا موقع خوندن از جدول مبدا هر رکورد رو لاک میکنه؟ و ما میتونیم اون رو با WITHNOLOCK بخونیم؟

    پاسخ دادن
    1. Hamid J. Fard

      Hamid J. Fard

          بازهم شما؟ (شوخی کردم)

      Isolation Level روی Select Into تاثیر می ذاره به دلیل اینکه این دستور باید یک جدول یا یک سری جداول رو بخونه.
      و اینکه بابت Lock این دستور Page ها و Extent ها را Lock می کند نه رکوردها را. البته شما می تونید با دستور With NoLock داده های قفل شده توسط Select Into رو بخوانید یا داده های قفل شده در جداول دیگر را.
      به این عکس یه نگاهی بنداز. این رو برای شما آماده کردم. همانطور که میبینید. تمامی Page ها و بعضی از Extent ها قفل شده اند.

      پاسخ دادن
  4. تورج عزیزی

       ممنون،

    اینکه چرا SQL Server روی رکوردی که در حال درج شدن هست Lock میزنه رو می تونیم به شکل زیر تفسیر کنیم؟
    “چون ممکنه تراکنش دیگه ای اون رو رکورد رو ناقص بخونه (مثلاً به جای خوندن کل ردیف چند تا ستون رو بیشتر نمی تونه بخونه) یا اینکه در حالی که هنوز رکورد به طور کامل با تمام اطلاعات ثبت نشده تراکنش دیگه ای بیاد و اون رو تغییر بده!”
    پاسخ دادن
    1. Hamid J. Fard

      Hamid J. Fard

          تورج: 

      یه جورایی درست می گی ولی اینجوری نیست که به جای کل ردیف چند تا ستون رو بخونه (روند ثبت رکورد فرق داره و در اینجا بحثش نمی گنجه). قفل کردن رکوردها برای Concurrency هستش. وقتی رکوردی قفل می شه (قفل ها در SQL Server انواع متفاوتی دارند که اینجا جاش نیست) همانطور که گفتی تراکنش دیگه ای نمی تونه اون رو تغییر بده ولی در شرایطی می تونه اون رو بخونه. به عنوان مثال یک رکورد آپدیت شده ولی هنوز تراکنش Commit نشده در این صورت شما می تونید داده تغییر داده شده رو بخونید ولی نمی تونید تغییر بدید و اگر بخواید تغییر بدید تراکنش جدید توسط تراکنش قبلی Block میشه. 
      پاسخ دادن
  5. Hamid J. Fard

    Hamid J. Fard

        تورج: البته اون عکسی که گذاشتم در رابطه با Lock درمورد Lockها روی جدول منبع است نه جدول جدیدی که ساخته می شه.

    پاسخ دادن
  6. سیدمهدی معصومی

    سیدمهدی معصومی

       با سلام
    بسیا عالی و جالب بود
    ممنون

    پاسخ دادن
  7. میلاد فیروزی

    میلاد فیروزی

        آیا برای Insert کردن رکوردهای تعداد بالا از SELECT INTO دستور پرسرعت تری هم وجود داره؟؟؟؟

    پاسخ دادن
  8. مسعود طاهری

    مسعود طاهری

    سلام 

    سناریو شما را کامل نمی دانم اما اگر کلی بخواهم جواب بدهم 
    بلی – روش های زیر می تواند مفید باشد

    استفاده از کلاس SQLBulkCopy در دات نت و درج دیتا در جدول به شکل Bulk Insert 
    یک روش دیگر هم استفاده از TVP است
    هر دو این موضوع در دوره SQL Server ویژه برنامه نویسان بررسی شده است
    پاسخ دادن

ارسال نظر

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

تمامی حقوق مادی و معنوی این وب سایت متعلق به نیک آموز می باشد.
این سایت توسط تیم آموزش برنامه نویسی نیک آموز مدیریت می شود.