Insert into ... values ( SELECT ... FROM ... )

Başka bir tablodan gelen girdiyi kullanarak bir tabloya INSERT INTO yapmaya çalışıyorum. Bu birçok veritabanı motoru için tamamen mümkün olsa da, günün SQL motoru (MySQL, Oracle, SQL Server, Informix ve DB2) için doğru sözdizimini hatırlamakta her zaman zorlanıyorum.

Bir SQL standardından (örneğin, SQL-92) gelen ve temel veritabanı hakkında endişelenmeden değerleri eklememe izin verecek bir gümüş kurşun sözdizimi var mı?

Çözüm

Dene:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Bu standart ANSI SQL'dir ve herhangi bir DBMS üzerinde çalışmalıdır

Kesinlikle işe yarıyor:

  • Oracle
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
Yorumlar (0)

@Shadow_x99: Bu iyi çalışmalıdır ve ayrıca birden fazla sütun ve diğer verilere de sahip olabilirsiniz:

INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT  table2.column1, table2.column2, 8, 'some string etc.'
FROM    table2
WHERE   table2.ID = 7;

Düzenleme: Bu sözdizimini yalnızca Access, SQL 2000/2005/Express, MySQL ve PostgreSQL ile kullandığımı belirtmeliyim, bu nedenle bunlar kapsanmalıdır. Bir yorumcu SQLite3 ile de çalışacağını belirtti.

Yorumlar (2)

Gördüğüm her iki yanıt da özellikle Informix'te iyi çalışıyor ve temelde standart SQL. Yani, gösterim:

INSERT INTO target_table[()] SELECT ... FROM ...;

Informix ve sanırım tüm DBMS'lerle sorunsuz çalışır. (5 ya da daha fazla yıl önce, bu MySQL'in her zaman desteklemediği türden bir şeydi; şimdi bu tür standart SQL sözdizimi için iyi bir desteği var ve AFAIK, bu gösterimde iyi çalışacaktır). Sütun listesi isteğe bağlıdır, ancak hedef sütunları sırayla gösterir, bu nedenle SELECT sonucunun ilk sütunu listelenen ilk sütuna gider, vb. Sütun listesinin olmaması durumunda, SELECT sonucunun ilk sütunu hedef tablonun ilk sütununa gider.

Sistemler arasında farklı olabilecek şey, farklı veritabanlarındaki tabloları tanımlamak için kullanılan gösterimdir - standardın veritabanları arası (DBMS'ler arası bir yana) işlemler hakkında söyleyecek hiçbir şeyi yoktur. Informix ile, bir tabloyu tanımlamak için aşağıdaki gösterimi kullanabilirsiniz:

[dbase[@server]:][owner.]table

Yani, bir veritabanı belirtebilir, isteğe bağlı olarak geçerli sunucuda değilse bu veritabanını barındıran sunucuyu tanımlayabilir, ardından isteğe bağlı bir sahip, nokta ve son olarak gerçek tablo adını belirtebilirsiniz. SQL standardı, Informix'in sahip olarak adlandırdığı şey için şema terimini kullanır. Dolayısıyla, Informix'te aşağıdaki gösterimlerden herhangi biri bir tabloyu tanımlayabilir:

table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table

Genel olarak sahibin tırnak içine alınmasına gerek yoktur; ancak, tırnak işareti kullanırsanız, sahip adının doğru yazılmasını sağlamanız gerekir - büyük/küçük harfe duyarlı hale gelir. Yani:

someone.table
"someone".table
SOMEONE.table

hepsi aynı tabloyu tanımlar. Informix ile, sahip adlarının genellikle büyük harfe dönüştürüldüğü MODE ANSI veritabanlarında hafif bir komplikasyon vardır (informix istisnadır). Yani, bir MODE ANSI veritabanında (yaygın olarak kullanılmaz), şöyle yazabilirsiniz:

CREATE TABLE someone.table ( ... )

ve sistem kataloğundaki sahip adı 'someone' yerine "SOMEONE" olacaktır. Sahip adını çift tırnak içine alırsanız, sınırlandırılmış bir tanımlayıcı gibi davranır. Standart SQL ile, sınırlandırılmış tanımlayıcılar birçok yerde kullanılabilir. Informix ile, bunları yalnızca sahip adları etrafında kullanabilirsiniz -- diğer bağlamlarda, Informix tek tırnaklı dizeleri dizeler olarak ve çift tırnaklı dizeleri sınırlandırılmış tanımlayıcılar olarak ayırmak yerine, hem tek tırnaklı hem de çift tırnaklı dizeleri dizeler olarak ele alır. (Tabii ki, sadece bütünlük için, çift tırnakların her zaman sınırlandırılmış tanımlayıcıları çevrelediğini ve tek tırnakların her zaman dizeleri çevrelediğini belirtmek için - herhangi bir değere, ancak Y en güvenlisidir - ayarlanabilen DELIMIDENT adlı bir ortam değişkeni vardır).

MS SQL Server'ın köşeli parantez içine alınmış [sınırlandırılmış tanımlayıcıları] kullanmayı yönettiğini unutmayın. Bana garip geliyor ve kesinlikle SQL standardının bir parçası değil.

Yorumlar (0)