SQL INSERT: Kapsamlı Rehber
SQL INSERT INTO
komutu, SQL'deki en popüler komutlardan biridir ve kullanmayı öğrendiğiniz ilk komutlardan biridir. Bu rehberde, verileri nasıl ekleyeceğinizi ve INSERT
komutunun tüm işlevselliğini nasıl kullanacağınızı öğrenin.
Bu makale Oracle, SQL Server, MySQL ve PostgreSQL için geçerlidir.
SQL INSERT Komutu Nedir?
INSERT
komutu, ya da INSERT INTO
komutu, bir tabloya veri eklemek (ya da eklemek) için kullanılır.
Tablonun önceden oluşturulmuş olması gerekir. Bir tablo oluşturmak, CREATE
komutunun bir parçası olarak yapılan ayrı bir adımdır (bunun hakkında yazdığım rehbere buradan ulaşabilirsiniz).
Bu komut, bir tabloya birçok farklı şekilde ve çeşitli kaynaklardan veri eklemenizi sağlar.
Ayrıca, bazı veritabanı sağlayıcılarına özgü işlevler de vardır. Eğer INSERT
komutunu başka veritabanlarında kullandıysanız, burada daha önce kullanmamış olabileceğiniz bazı özellikler de olabilir.
SQL INSERT INTO Söz Dizimi
INSERT
komutunun birçok ayarı ve varyasyonu vardır, ancak aynı zamanda verileri eklemek için oldukça temel bir kullanım şekli de mevcuttur.
Temel INSERT
komutunun söz dizimi tüm veritabanı sağlayıcıları için ortaktır:
INSERT INTO table_reference [ (column_names) ]
[ subquery3 | VALUES ( sql_expression ) [ returning_clause ] ]
Bu komut şu an için oldukça kafa karıştırıcı görünebilir, özellikle de tüm bu seçeneklerle. Ancak, rehberin ilerleyen bölümlerinde INSERT
komutunun her bir kullanım yolunu örneklerle açıklayacağız, bu da bu seçenekleri anlamanızı kolaylaştıracak.
Temel INSERT Komutu
İlk olarak, temel bir INSERT komutuna göz atalım.
Aşağıdaki gibi bir tabloya sahip olduğumuzu varsayalım:
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | John | Smith | 500 | 100 | 01/Feb/15 | M |
2 | Susan | Johnson | 150 | 150 | 12/Jan/15 | F |
3 | Tom | Capper | 350 | 320 | 06/Mar/15 | M |
4 | Mark | Holloway | 500 | 410 | 20/Jan/15 | M |
5 | Steven | Webber | 100 | 80 | 09/Mar/15 | M |
6 | Julie | Armstrong | 100 | 0 | 12/Feb/15 | F |
7 | Michelle | Randall | 250 | 23/Jan/15 | F | |
8 | Andrew | Cooper | 800 | 400 | 04/Mar/15 | M |
9 | Robert | Pickering | 110 | 100 | 30/Jan/15 | M |
10 | Tanya | Hall | 150 | 150 | 28/Jan/15 | F |
Bu tablo için CREATE TABLE komutu aşağıdaki gibidir.
CREATE TABLE student (
student_id INT,
first_name VARCHAR(50),
last_name VARCHAR(50),
fees_required INT,
fees_paid INT,
enrolment_date DATE,
gender VARCHAR(1)
);
INSERT komutunu kullanarak tabloya yeni bir kayıt ekleyebiliriz.
INSERT komutunu SQL’de kullanmak için birkaç şeye ihtiyacımız var:
- Veriyi eklemek istediğimiz tablonun adı
- Tabloya eklenecek değerler
- Değerlerin ekleneceği sütunlar (bu aslında isteğe bağlıdır)
Sütun adlarını belirtmek zorunda olmasak da, bunları belirtmek iyi bir uygulamadır. Sütun adlarını belirtmezsek, tablo yapısı değiştiğinde INSERT komutları başarısız olabilir.
Bu tablo için bir INSERT komutuna göz atalım.
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES (11, 'Jarrad', 'Winston', 700, 300, NULL);
INSERT INTO komutuyla başlarız; bu, SQL anahtar kelimeleridir.
Ardından, tablo adını belirtiriz. Bu durumda, tablo adı student.
Sonra parantezleri açarız ve parantezler içinde, değer eklemek istediğimiz sütunların bir listesini veririz. Tüm sütunları belirtmemiz gerekmez (bunu birazdan daha ayrıntılı açıklayacağım), ancak bu örnekte belirtmiş olduk.
Sonraki adımda VALUES anahtar kelimesi gelir.
Daha sonra parantezleri açar ve eklemek istediğimiz değerleri belirtiriz. Bu liste içinde, virgülle ayrılmış bir değerler listesi bulunur. Bu değerler, daha önce belirttiğimiz sütunlarla uyumlu olmalıdır.
İlk değer ilk sütunla, ikinci değer ikinci sütunla ve bu şekilde devam eder.
Değerler aşağıdaki gibi belirtilebilir:
- Sayılar, tırnak içine alınmadan belirtilir.
- Dizeler, tek tırnak içine alınmalıdır.
- NULL, NULL değerinin ekleneceğini belirtir (bu örnekte enrolment_date sütunu için bu yapılmıştır).
- Fonksiyonlar veya diğer sütunlar, daha sonra ele alacağız.
Son olarak, parantezleri kapatır ve bir noktalı virgül ile bitiririz.
Bu sorgu ne yapacak? Gelin çalıştırıp görelim.
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES (11, 'Jarrad', 'Winston', 700, 300, NULL);
1 satır eklendi.
SELECT * FROM student;
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | John | Smith | 500 | 100 | 01/Feb/15 | M |
2 | Susan | Johnson | 150 | 150 | 12/Jan/15 | F |
3 | Tom | Capper | 350 | 320 | 06/Mar/15 | M |
4 | Mark | Holloway | 500 | 410 | 20/Jan/15 | M |
5 | Steven | Webber | 100 | 80 | 09/Mar/15 | M |
6 | Julie | Armstrong | 100 | 0 | 12/Feb/15 | F |
7 | Michelle | Randall | 250 | 23/Jan/15 | F | |
8 | Andrew | Cooper | 800 | 400 | 04/Mar/15 | M |
9 | Robert | Pickering | 110 | 100 | 30/Jan/15 | M |
10 | Tanya | Hall | 150 | 150 | 28/Jan/15 | F |
11 | Jarrad | Winston | 700 | 300 | (null) | (null) |
Gördüğünüz gibi, bu tabloya tek bir kayıt eklenmiştir.
Sütunlar Belirtilmeden INSERT Komutu
Sütunları belirtmeden bir SQL INSERT INTO ifadesi kullanırsanız ne olur?
Daha önce bunların isteğe bağlı olduğunu söylemiştim, peki ne olacak?
INSERT INTO student
VALUES (12, 'Mary', 'Taylor', 500, 100, NULL, 'F');
1 satır eklendi.
SELECT *
FROM student;
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | John | Smith | 500 | 100 | 01/Feb/15 | M |
2 | Susan | Johnson | 150 | 150 | 12/Jan/15 | F |
3 | Tom | Capper | 350 | 320 | 06/Mar/15 | M |
4 | Mark | Holloway | 500 | 410 | 20/Jan/15 | M |
5 | Steven | Webber | 100 | 80 | 09/Mar/15 | M |
6 | Julie | Armstrong | 100 | 0 | 12/Feb/15 | F |
7 | Michelle | Randall | 250 | 23/Jan/15 | F | |
8 | Andrew | Cooper | 800 | 400 | 04/Mar/15 | M |
9 | Robert | Pickering | 110 | 100 | 30/Jan/15 | M |
10 | Tanya | Hall | 150 | 150 | 28/Jan/15 | F |
11 | Jarrad | Winston | 700 | 300 | (null) | (null) |
12 | Mary | Taylor | 500 | 100 | (null) | F |
Kaydın eklendiğini görebiliyoruz. Ancak bununla ilgili bazı sorunlar yaşayabiliriz:
- Tabloyu değiştirirsek ve sütun ekler veya kaldırırsak ne olur? INSERT ifadesi artık çalışmayabilir.
- INSERT ifadesinde değerleri yanlış sıraya koyarsak ne olur? Bu da başarısız olur.
Yani işe yarayabilir ama genelde iyi bir fikir değildir.
Bir İfade ile Birden Fazla Satır Ekleme
Şimdiye kadar verdiğimiz örnekler, bir ifade ile tek bir değeri ekleme yeteneğini göstermiştir. Peki, birden fazla değeri nasıl ekleyebilirsiniz?
Ayrı ayrı ifadeler yazabilirsiniz:
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES (11, 'Jarrad', 'Winston', 700, 300, NULL);
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES (12, 'Michael', 'Brown', 750, 500, NULL);
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES (13, 'Paul', 'Masters', 200, 10, NULL);
Bu işlem biraz “uzun” ve tekrarlayıcı olabilir. Ayrıca, yüzlerce veya binlerce satır ekliyorsanız, her ifade tek tek işlendiğinden zaman alabilir.
Neyse ki, daha iyi bir yol var.
Tek bir SQL INSERT komutuyla birden fazla kayıt ekleyebilirsiniz.
Bunu yapma yöntemi, her veritabanı sağlayıcısında farklılık gösterir. Bir göz atalım..
MySQL Birden Fazla Satır Ekleme
MySQL de birden fazla satır eklemenin yolu SQL Server ve PostgreSQL ile aynıdır; burada sütun adlarını bir kez belirtirsiniz ve her satırı VALUES ifadesinde virgülle ayırırsınız.
Örneğin:
INSERT INTO student (student_id, first_name, last_name, fees_required, fees_paid, enrolment_date)
VALUES
(11, 'Jarrad', 'Winston', 700, 300, NULL),
(12, 'Michael', 'Brown', 750, 500, NULL),
(13, 'Paul', 'Masters', 200, 10, NULL);
Burada dikkat edilmesi gereken birkaç husus var.
Sütun adları yalnızca bir kez , tablo adından sonra belirtilir; bu, tek bir kayıt ekliyormuşsunuz gibi yapılır.
VALUES anahtar sözcüğünden sonra birkaç satır belirtilir ve bunlar virgülle ayrılır.
Bu ifadenin çalıştırılması, üç satırın da aynı anda tabloya eklenmesine neden olur.
MySQL'de bir ifadeye ekleyebileceğiniz maksimum satır sayısı nedir? SQL Server gibi tanımlanmış bir sınır yoktur. Ancak, ifadenin boyutu "max_allowed_packet" özelliğinden büyükse, bir hata alırsınız.
Sorgu Sonucundan Veri Ekleme
Diyelim ki yeni bir tablo oluşturmak ve bu tabloyu doldurmak istiyorsunuz. Ancak verileri başka bir sorgunun sonuçlarıyla doldurmak istiyorsunuz.
Ne yapabilirsiniz?
Şunları deneyebilirsiniz:
- SELECT sorgusunu çalıştırın
- Çıktıyı bir elektronik tablo dosyasına kopyalayın
- Bir dizi INSERT ifadesi yazmak için formüller kullanın
- Bu INSERT ifadelerini bir SQL dosyasına kopyalayın
- SQL dosyasını çalıştırın
Bunlar oldukça fazla iş gibi görünüyor, değil mi?
Daha kolay bir yol var.
SELECT sorgusunun sonuçlarına dayalı bir SQL INSERT INTO ifadesi kullanabilirsiniz – hepsini tek bir ifadede.
Bu işlemin sözdizimi şu şekildedir:
INSERT INTO target_tablename (col1, col2, col3...)
SELECT (col1, col2, col3...)
FROM source_tablename...
Bir SELECT ifadesi çalıştırırsınız ve bu ifadenin sonuçları tabloya eklenir. source_tablename verilerin geldiği tabloyu, target_tablename ise verilerin ekleneceği tabloyu temsil eder.
Bu tür bir INSERT ifadesini çalıştırırken dikkate almanız gereken birkaç ipucu vardır.
Öncelikle, sütunlar ve veri türleri eşleşmelidir. Aynı sayıda sütun olmalı ve aynı türde değerler eklemelisiniz. Örneğin, bir VARCHAR2 değerini NUMBER alanına ekleyemezsiniz.
İkinci olarak, INSERT ifadesini SELECT ifadesi ile çalıştırmadan önce SELECT ifadesini ayrı olarak test etmek iyi bir fikirdir. Bu, SELECT ifadesinin döndürdüğü verileri görmenizi ve veriler eklenmeden önce gözden geçirmenizi sağlar.
Bir örneğe bakalım.
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid)
SELECT student_id, first_name, last_name, 1000, 0
FROM new_students
WHERE requested_date > '01-JAN-2019';
Bu sorgu, öğrenci tablosuna yeni değerler ekleyecektir. Değerler new_students tablosundan gelir.
Bazı sütunlar için eklenen adlar hedef tablodaki adlarla aynıdır. Diğerleri için farklıdır.
Bu örnekte, tüm kayıtlar için fees_required değerine 1000 değerini ekliyoruz.
Yani sütun adlarının eşleşmesi gerekmiyor, ancak sütun sayılarının ve veri türlerinin eşleşmesi gerekiyor.
INSERT If Not Exists ile Tekrar Eden Kayıtları Önleme
Bir veritabanına kayıt eklerken, bazen kaydın zaten mevcut olduğundan emin olmak istersiniz. Tabloyun içinde tekrar eden kayıtların olmasını istemeyebilirsiniz.
Bunu nasıl yapabilirsiniz?
İyi haber şu ki, Oracle SQL'de bunu yapmak mümkündür. Bu işlev için önerilen yöntem MERGE ifadesidir çünkü bu işlevsellik için tasarlanmıştır.
Ancak, SQL'de gerçekten INSERT ifadesi ile yapmak istiyorsanız, bunu bir alt sorgu ile gerçekleştirebiliriz.
Tekrar öğrenci tablomuzu ve bazı kayıtları olduğunu varsayalım.
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | John | Smith | 500 | 100 | 01/Feb/15 | M |
2 | Susan | Johnson | 150 | 150 | 12/Jan/15 | F |
3 | Tom | Capper | 350 | 320 | 06/Mar/15 | M |
4 | Mark | Holloway | 500 | 410 | 20/Jan/15 | M |
5 | Steven | Webber | 100 | 80 | 09/Mar/15 | M |
6 | Julie | Armstrong | 100 | 0 | 12/Feb/15 | F |
7 | Michelle | Randall | 250 | 23/Jan/15 | F | |
8 | Andrew | Cooper | 800 | 400 | 04/Mar/15 | M |
9 | Robert | Pickering | 110 | 100 | 30/Jan/15 | M |
10 | Tanya | Hall | 150 | 150 | 28/Jan/15 | F |
11 | Jarrad | Winston | 700 | 300 | (null) | (null) |
12 | Mary | Taylor | 500 | 100 | (null) | F |
Şimdi, içinde birkaç kayıt daha bulunan new_student tablomuz var.
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | Mark | Anderson | 860 | 45 | M | |
2 | John | Rogers | 210 | 700 | M | |
3 | Susan | Johnson | 500 | 0 | F |
Ama bazı tekrarlanan kayıtlar da var – Susan Johnson.
Yinelenen bir kaydı nasıl tanımlarız? Buradaki önemli soru bu.
İlk olarak, hangi sütunların yinelenen bir kaydı tanımladığını belirtmeniz gerekir. Bu örnekte, yinelenen bir kaydı tanımlayan sütunların first_name ve last_name sütunları olduğunu varsayalım (aynı adı taşıyan iki öğrenciyi hesaba katmaz, ancak bu yalnızca bir örnektir).
Değerlerimizi ekleyen bir INSERT ifadesi yazmamız gerekir, ancak değerin tabloda mevcut olmadığını kontrol etmek için bir WHERE ifadesi kullanmamız gerekir.
Sorgumuz şu şekilde olabilir:
INSERT INTO student
(student_id, first_name, last_name, fees_required, fees_paid, enrolment_date, gender)
SELECT
student_id, first_name, last_name, fees_required, fees_paid, enrolment_date, gender
FROM new_student
WHERE NOT EXISTS (
SELECT *
FROM student
WHERE student.first_name = new_student.first_name
AND student.last_name = new_student.last_name
);
2 satır eklendi.
Bu sorgu new_student tablosundaki değerleri, first_name ve last_name kayıtlarının eşleşmediği student tablosuna ekleyecektir.
Bakalım şimdi bu tablo ne gösteriyor.
SELECT * FROM student;
STUDENT_ID | FIRST_NAME | LAST_NAME | FEES_REQUIRED | FEES_PAID | ENROLMENT_DATE | GENDER |
1 | John | Smith | 500 | 100 | 01/Feb/15 | M |
2 | Susan | Johnson | 150 | 150 | 12/Jan/15 | F |
3 | Tom | Capper | 350 | 320 | 06/Mar/15 | M |
4 | Mark | Holloway | 500 | 410 | 20/Jan/15 | M |
5 | Steven | Webber | 100 | 80 | 09/Mar/15 | M |
6 | Julie | Armstrong | 100 | 0 | 12/Feb/15 | F |
7 | Michelle | Randall | 250 | 23/Jan/15 | F | |
8 | Andrew | Cooper | 800 | 400 | 04/Mar/15 | M |
9 | Robert | Pickering | 110 | 100 | 30/Jan/15 | M |
10 | Tanya | Hall | 150 | 150 | 28/Jan/15 | F |
11 | Jarrad | Winston | 700 | 300 | (null) | (null) |
12 | Mary | Taylor | 500 | 100 | (null) | F |
100 | Mark | Anderson | 860 | 45 | (null) | M |
102 | John | Rogers | 210 | 700 | (null) | M |
Öğrenci tablosunun güncellendiğini görebilirsiniz.
Daha önce de belirttiğim gibi, bunu yapmanın en iyi yolu MERGE ifadesini kullanmaktır, ancak eğer INSERT kullanarak mevcut olmayan değerleri eklemeniz gerekiyorsa, bunu şu şekilde yapabilirsiniz.
Tarih Değerlerini Bir Tabloya Ekleme
Tarihlerle ilgili değerleri bir tabloya eklerken sıklıkla sorun yaşadım. Çoğu zaman bunun nedeni, gerekli formatı bilmemem veya farklı veritabanı sağlayıcıları arasındaki farklardan kafamın karışmasıdır.
SQL'de bir tarih eklemek oldukça basittir ve sağlayıcıya bağlıdır.
MySQL'de Tarih Değeri Ekleme
MySQL'de bir tarih veya tarih-saat değeri eklemek için, tarihi bir string içine alabilir ve belirli bir formatta belirtebilirsiniz:
- Tarih için YYYY-MM-DD (veya YY-MM-DD)
- Tarih ve saat için YYYY-MM-DD HH:MM(veya YY-MM-DD HH:MM)
Bu örnek tabloyu kullanarak bir göz atalım:
CREATE TABLE datetest (
id INTEGER,
date_test DATE);
Değeri eklemek için tarihi YYYY-AA-GG biçiminde belirten bu INSERT ifadesini kullanabilirsiniz:
INSERT INTO datetest (id, date_test)
VALUES (1, '2019-03-01');
Eğer değeri bu formata getiremiyorsanız, o zaman STR_TO_DATE fonksiyonunu belirli bir stil ile kullanabilirsiniz.
INSERT INTO datetest (id, date_test)
VALUES (1, STR_TO_DATE('01 Mar 2019', '%d %b %Y'));
Bu STR_TO_DATE işlevinin ikinci parametresi bir dizi biçim değeri alabilir. Bu örnekte, %d güne, %b kısaltılmış bir ay adına ve %Y dört basamaklı yıla ilişkindir.
Sonuç olarak, INSERT ifadesi oldukça güçlüdür ve birçok şey yapmanıza olanak tanır:
- Verileri bir tabloya ekle
- Sütunları belirtmeden veri ekle
- Tek bir ifadeye birden fazla kayıt ekleyin
- Kayıtları birden fazla tabloya ekleme (yalnızca Oracle)
- Bir veya daha fazla tabloya bazı kayıtlar ekleme
- Yinelenen değerlerin eklenmesini önleme