خانه/ تغییر داده‌ها/ INSERT

INSERT: افزودن داده‌ی تازه به جدول

مبتدی ۱۲ دقیقه مطالعه

تا این‌جای دوره، هر پرس‌وجویی که نوشتیم فقط داده‌ی موجود را می‌خواند. از این فصل به بعد، وارد دستورهایی می‌شویم که واقعاً داده را تغییر می‌دهند: INSERT، UPDATE، DELETE و MERGE. شروع می‌کنیم با ساده‌ترین‌شان — اضافه کردن ردیف تازه.

خیالت راحت باشد: هر تغییری که در جعبه‌های «امتحانش کن» همین درس بدهی، فقط روی یک پایگاه‌داده‌ی موقت و داخل حافظه‌ی مرورگر خودت اعمال می‌شود؛ با هر بار اجرا از نو ساخته می‌شود. یعنی می‌توانی کاملاً آزادانه هر ایده‌ای را امتحان کنی، بدون نگرانی از خراب‌کردن چیزی.

ساختار پایه

sql
INSERT INTO students (full_name, city, grade)
VALUES (N'رضا کریمی', N'یزد', 10);
همیشه نام ستون‌ها را صریح بنویس. می‌توان نوشت INSERT INTO students VALUES (...) بدون نام ستون، اما در آن صورت باید دقیقاً به همان ترتیبی که جدول تعریف شده، مقدار بدهی — و اگر روزی ترتیب یا تعداد ستون‌های جدول عوض شود، این کد بی‌سروصدا داده‌ی اشتباه وارد می‌کند. نوشتن صریح نام ستون‌ها، این ریسک را کاملاً از بین می‌برد.

بیا یک دانش‌آموز تازه به جدول اضافه کنیم:

امتحانش کن — افزودن یک ردیف
دقت کن ستون id اصلاً در INSERT نیامده — چون INTEGER PRIMARY KEY در SQLite (و IDENTITY در SQL Server، که در درس جدول‌ها دیدیم) خودش به‌طور خودکار شماره‌گذاری می‌کند.

افزودن چند ردیف در یک دستور

به‌جای نوشتن چند INSERT جدا، می‌توان چند ردیف را با کاما از هم جدا کرد و در یک دستور فرستاد — هم کوتاه‌تر است، هم معمولاً سریع‌تر اجرا می‌شود:

sql
INSERT INTO students (full_name, city, grade)
VALUES
  (N'رضا کریمی', N'یزد', 10),
  (N'سارا نجفی', N'کرمان', 11),
  (N'امیر رستمی', N'قم', 9);

بیا امتحان کنیم:

امتحانش کن — افزودن چند ردیف هم‌زمان

گرفتن شناسه‌ی ردیف تازه بلافاصله بعد از INSERT

در برنامه‌های واقعی، معمولاً بلافاصله بعد از افزودن یک ردیف، به شناسه‌ی خودکارِ همان ردیف نیاز داریم — مثلاً برای افزودن ردیف‌های وابسته به آن. SQL Server برای این کار SCOPE_IDENTITY() دارد، و SQLite معادلش last_insert_rowid() است:

sql
-- در SQL Server واقعی:
INSERT INTO Students (FullName) VALUES (N'رضا کریمی');
SELECT SCOPE_IDENTITY();

-- معادل در SQLite (همین Playground):
INSERT INTO students (full_name) VALUES ('رضا کریمی');
SELECT last_insert_rowid();

بیا امتحان کنیم:

امتحانش کن — گرفتن شناسه‌ی تازه‌ساخته‌شده

INSERT ... SELECT — کپی کردن نتیجه‌ی یک پرس‌وجو

به‌جای مقادیر ثابت، می‌توان نتیجه‌ی یک SELECT را مستقیم داخل جدول دیگری درج کرد — بدون خواندن داده به بیرون و نوشتن دوباره. این الگو برای آرشیو کردن، پشتیبان‌گیری جزئی، یا انتقال داده بین جدول‌ها بسیار رایج است:

sql
-- آرشیو کردن محصولات دسته‌ی «کتاب» در یک جدول جدا
INSERT INTO book_archive (product, price)
SELECT product, price
FROM sales
WHERE category = N'کتاب';

بیا این را عملاً امتحان کنیم:

امتحانش کن — کپی با INSERT ... SELECT
هر ۳ محصول دسته‌ی «کتاب» بدون این‌که مقادیرشان را دستی تایپ کنیم، مستقیم از sales به book_archive کپی شدند. این یعنی می‌توانی هر پرس‌وجویی — حتی با JOIN یا WHERE پیچیده — را مستقیم به یک INSERT تبدیل کنی.

جمع‌بندی این درس

  • همیشه نام ستون‌ها را در INSERT صریح بنویس، حتی اگر اختیاری باشد.
  • چند ردیف را می‌توان در یک دستور، با کاما جدا از هم، درج کرد.
  • last_insert_rowid() (در SQLite) و SCOPE_IDENTITY() (در SQL Server) شناسه‌ی خودکارِ آخرین ردیف را برمی‌گردانند.
  • INSERT ... SELECT نتیجه‌ی یک پرس‌وجو را مستقیم در جدول دیگری کپی می‌کند.

در درس بعدی سراغ UPDATE می‌رویم — و می‌بینیم چرا فراموش‌کردن WHERE در این دستور، می‌تواند یکی از خطرناک‌ترین اشتباهات SQL باشد.