Jeg prøver å INSERT INTO
en tabell ved hjelp av input fra en annen tabell. Selv om dette er fullt mulig for mange databasemotorer, ser det ut til at jeg alltid sliter med å huske riktig syntaks for dagens SQL
-motor (MySQL, Oracle, SQL Server, Informix og DB2).
Finnes det en sølvkule-syntaks fra en SQL-standard (for eksempel SQL-92) som gjør at jeg kan sette inn verdiene uten å bekymre meg for den underliggende databasen?
Prøv:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
Dette er standard ANSI SQL og bør fungere på alle DBMS-er.
Det fungerer definitivt for:
@Shadow_x99: Det bør fungere fint, og du kan også ha flere kolonner og andre data i tillegg:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
Rediger: Jeg bør nevne at jeg bare har brukt denne syntaksen med Access, SQL 2000/2005 / Express, MySQL og PostgreSQL, så de skal dekkes. En kommentator har påpekt at det vil fungere med SQLite3.
Begge svarene jeg ser fungerer fint i Informix spesifikt, og er i utgangspunktet standard SQL. Det vil si notasjonen:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
fungerer fint med Informix og, vil jeg forvente, alle DBMS. (En gang for 5 eller flere år siden, dette er den slags ting som MySQL ikke alltid støtte; det har nå anstendig støtte for denne typen standard SQL-syntaks og, AFAIK, det ville fungere OK på denne notasjonen). Kolonnelisten er valgfri, men angir målkolonnene i rekkefølge, slik at den første kolonnen i resultatet av SELECT vil gå inn i den første oppførte kolonnen osv. I fravær av kolonnelisten går den første kolonnen i resultatet av SELECT inn i den første kolonnen i måltabellen.
Det som kan være forskjellig mellom systemer er notasjonen som brukes til å identifisere tabeller i forskjellige databaser - standarden har ingenting å si om inter-databaseoperasjoner (enn si inter-DBMS). Med Informix kan du bruke følgende notasjon for å identifisere en tabell:
[dbase[@server]:][owner.]table
Det vil si at du kan spesifisere en database, eventuelt identifisere serveren som er vert for den databasen hvis den ikke er på den nåværende serveren, etterfulgt av en valgfri eier, punktum og til slutt det faktiske tabellnavnet. SQL-standarden bruker begrepet skjema for det Informix kaller eier. I Informix kan en hvilken som helst av følgende notasjoner identifisere en tabell:
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
Eieren trenger generelt ikke å bli sitert; men hvis du bruker anførselstegn, må du få eiernavnet stavet riktig - det blir case-sensitivt. Det vil si
someone.table
"someone".table
SOMEONE.table
identifiserer alle den samme tabellen. Med Informix er det en mild komplikasjon med MODE ANSI-databaser, der eiernavn vanligvis konverteres til store bokstaver (informix er unntaket). Det vil si at i en MODE ANSI-database (ikke ofte brukt) kan du skrive:
CREATE TABLE someone.table ( ... )
og eiernavnet i systemkatalogen vil være "SOMEONE", i stedet for 'someone'. Hvis du setter eiernavnet i doble anførselstegn, fungerer det som en avgrenset identifikator. Med standard SQL kan avgrensede identifikatorer brukes mange steder. Med Informix kan du bare bruke dem rundt eiernavn - i andre sammenhenger behandler Informix både strenger med enkle og doble anførselstegn som strenger, i stedet for å skille strenger med enkle anførselstegn som strenger og strenger med doble anførselstegn som avgrensede identifikatorer. (For fullstendighetens skyld finnes det selvfølgelig en miljøvariabel, DELIMIDENT, som kan settes - til en hvilken som helst verdi, men Y er sikrest - for å angi at doble anførselstegn alltid omgir avgrensede identifikatorer og enkle anførselstegn alltid omgir strenger).
Merk at MS SQL Server klarer å bruke [avgrensede identifikatorer] omsluttet av hakeparenteser. Det ser rart ut for meg, og er absolutt ikke en del av SQL-standarden.