INSERT'te auto_increment anahtarları nasıl kullanılır (SELECT * FROM…)


13

MySQL'de table1ve var table2. Her ikisinin de birincil auto_incrementanahtarı vardır id.

Tablo şemaları eşleşir ve ben INSERT INTO table1 (SELECT * FROM table2)eklenen yeni satırlarla ilgili ne olur table1? idBir satır table1aynı olduğunda eski değerlerini koruyor ve çakışmalar oluşturuyorlar idmı? Auto_increment tarafından yeni değerler oluşturuluyor mu? Depolama motoruna veya kilitlemeye bağlı mı?

Yanıtlar:


13

Bir otomatik artış sütununa ekleyebilir ve bir değer belirleyebilirsiniz. Bu iyi; otomatik artış üretecini geçersiz kılar.

NULL veya 0 değerini girmeye çalışırsanız veya DEFAULTINSERT ifadenizdeki sütunlardan otomatik artış sütununu atlarsanız, otomatik artış üreteci etkinleştirilir.

Yani, bu iyi INSERT INTO table1 SELECT * FROM table2(bu arada, parantez gerekmez). İd değerleri, o bu araçlar table2aynen kopyalanmış olacak ve table1olacak değil yeni değerler üretmek.

Eğer varsa istediğiniz table1 yeni değerler üretmek, yapamayacağınız SELECT *. Kimlik sütunu için null veya 0 kullanırsınız:

INSERT INTO table1 SELECT 0, col1, col2, col3, ... FROM table2;

Ya da sütunu hem INSERT deyiminin sütun listesinden hem de SELECT deyiminin seçim listesinden çıkarırsınız:

-- No id in either case:
INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3, ... FROM table2;

Sormadan önce, SQL'de "bir sütun hariç" select * "sözdizimi yoktur. Eklemek istediğiniz sütun adlarının tam listesini yazmanız gerekir.


Değer olarak 0 eklemeye izin veren / izin vermeyen bir seçenek yok mu? (2. paragrafınız ile ilgili)
Sascha Rambeaud

1
Evet, SQL_MODE = NO_AUTO_VALUE_ON_ZERO , aksi takdirde bir AI sütununa hiçbir zaman gerçek bir sıfır değeri ekleyemedik. Bu SQL modunu kullanırsanız, NULL hala AI üretecini etkinleştirmek için çalışır veya sütunu atlamak da çalışır.
Bill Karwin

@BillKarwin, son paragrafınızla ilgili olarak, alt sonucu aldıktan sonra select * from table, ilk sütununu kaldırmak için bu alt sonuç üzerinde çalışmanın bir yolu yok mu?
Pacerier

@Pacerier, doğru anlarsam, select *anlam ifade edip edemeyeceğini soruyorsun select * except for the first column. Cevap hayır. select *her zaman bu tablodaki tüm sütunları ister . Bir altküme istiyorsanız, istediğiniz sütunları hecelemeniz gerekir.
Bill Karwin

@BillKarwin, Hmm, düşünüyordum masanın döndürülme hükümler, sonra tekrar mesela döner nerede dikey yapmak select*from transpose(select*from(transpose(select*from table where Id=1))where col_name<>Id)ya da belki daha özlü olarak select*from table where Id=1 and $col<>Idne düşünüyorsun?
Pacerier

3

Seçimdeki kimlik tabloya eklenen değerle aynı olacaktır. Varolan satırları kopyalamaya çalışıyorsanız bu bir hatayla sonuçlanır.

Bill Karwin: Sormadan önce, SQL'de "bir sütun hariç" select * "sözdizimi yoktur.

Bu, bazı yaratıcılıklarla başarılabilir:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Bu, yeni satırın seçilen satırdaki kimlik yerine otomatik olarak artırılmış bir kimlik almasına neden olur.


2
Zeki, ama bana göre, bu, eklemek istediğiniz sütun adlarının tam listesini heceleyerek sayılır.
Bill Karwin

1
Peki mysql, manuel olarak yapmak yerine otomatik olarak yazıyor. Çok sütunlu tablolarınız varsa, birini kaçırmanızı veya birkaçını yanlış yazmanızı önler.
curmil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.