Invoegen in ... waarden ( SELECT ... FROM ... )

Ik probeer een INSERT INTO tabel te maken met de input van een andere tabel. Hoewel dit voor veel database engines goed mogelijk is, heb ik altijd moeite om de juiste syntax te onthouden voor de SQL engine van de dag (MySQL, Oracle, SQL Server, Informix, en DB2).

Is er een silver-bullet syntax afkomstig van een SQL standaard (bijvoorbeeld, SQL-92) die mij in staat zou stellen om de waarden in te voegen zonder me zorgen te maken over de onderliggende database?

Oplossing

Probeer het:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Dit is standaard ANSI SQL en zou moeten werken op elke DBMS

Het werkt zeker voor:

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

@Shadow_x99: Dat zou prima moeten werken, en je kunt ook meerdere kolommen en andere gegevens ook hebben:

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

Edit: Ik moet vermelden dat ik'deze syntax alleen heb gebruikt met Access, SQL 2000/2005/Express, MySQL, en PostgreSQL, dus die zouden gedekt moeten zijn. Een commentator heeft me erop gewezen dat het ook zal werken met SQLite3.

Commentaren (2)

Beide antwoorden die ik zie werken prima in Informix specifiek, en zijn in principe standaard SQL. Dat wil zeggen, de notatie:

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

werkt prima met Informix en, naar ik verwacht, met alle DBMS'en. (Ooit, 5 of meer jaar geleden, was dit het soort ding dat MySQL niet altijd ondersteunde; het heeft nu fatsoenlijke ondersteuning voor dit soort standaard SQL syntaxis en, AFAIK, het zou OK werken met deze notatie). De kolomlijst is optioneel, maar geeft de doel-kolommen in volgorde aan, dus de eerste kolom van het resultaat van de SELECT zal in de eerste vermelde kolom gaan, enz. Bij afwezigheid van de kolomlijst gaat de eerste kolom van het resultaat van de SELECT naar de eerste kolom van de doeltabel.

Wat kan verschillen tussen systemen is de notatie die wordt gebruikt om tabellen in verschillende databases te identificeren - de standaard heeft niets te zeggen over inter-database (laat staan inter-DBMS) operaties. Bij Informix kunt u de volgende notatie gebruiken om een tabel te identificeren:

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

Dat wil zeggen dat u een database specificeert, optioneel de server identificeert die die database host als die zich niet in de huidige server bevindt, gevolgd door een optionele eigenaar, punt, en tenslotte de eigenlijke tabelnaam. De SQL-standaard gebruikt de term schema voor wat Informix de eigenaar noemt. In Informix kan dus elk van de volgende notaties een tabel identificeren:

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

De eigenaar hoeft in het algemeen niet te worden geciteerd; maar als u wel citaten gebruikt, moet u de naam van de eigenaar correct spellen - het wordt hoofdlettergevoelig. Dat wil zeggen:

someone.table
"someone".table
SOMEONE.table

identificeren allemaal dezelfde tabel. Met Informix is er een milde complicatie met MODE ANSI databases, waar eigenaarsnamen over het algemeen worden omgezet naar hoofdletters (informix is de uitzondering). Dat wil zeggen, in een MODE ANSI database (niet algemeen gebruikt), zou je kunnen schrijven:

CREATE TABLE someone.table ( ... )

en de naam van de eigenaar in de systeemcatalogus zou "SOMEONE" zijn, in plaats van 'someone'. Als je de eigenaarsnaam tussen dubbele aanhalingstekens zet, werkt het als een begrensde identifier. Met standaard SQL kunnen begrensde identifiers op veel plaatsen worden gebruikt. Met Informix kunt u ze alleen gebruiken rond eigenaarsnamen -- in andere contexten behandelt Informix zowel enkel-aanhalingstekens als dubbel-aanhalingstekens als tekenreeksen, in plaats van enkel-aanhalingstekens te scheiden als tekenreeksen en dubbel-aanhalingstekens als begrensde identifiers. (Natuurlijk, voor de volledigheid, er is een omgevingsvariabele, DELIMIDENT, die kan worden ingesteld - op elke waarde, maar Y is het veiligst - om aan te geven dat dubbele aanhalingstekens altijd om begrensde identifiers staan en enkele aanhalingstekens altijd om tekenreeksen).

Merk op dat MS SQL Server erin slaagt om [gelimiteerde identifiers] tussen vierkante haken te gebruiken. Het ziet er voor mij vreemd uit, en maakt zeker geen deel uit van de SQL standaard.

Commentaren (0)