Próbuję INSERT INTO
do tabeli używając danych wejściowych z innej tabeli. Chociaż jest to całkowicie wykonalne dla wielu silników baz danych, zawsze mam problem z zapamiętaniem poprawnej składni dla danego silnika SQL
(MySQL, Oracle, SQL Server, Informix i DB2).
Czy istnieje składnia silver-bullet pochodząca ze standardu SQL (na przykład SQL-92), która pozwoliłaby mi wstawić wartości bez martwienia się o bazę danych?
Spróbuj:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
To jest standardowy ANSI SQL i powinien działać na każdym DBMS
To zdecydowanie działa dla:
@Shadow_x99: To powinno działać dobrze, a także możesz mieć wiele kolumn i innych danych, jak również:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
Edycja: Powinienem wspomnieć, że I've tylko używał tej składni z Access, SQL 2000/2005/Express, MySQL i PostgreSQL, więc te powinny być objęte. Jeden z komentatorów zauważył, że będzie to działać z SQLite3.
Obie odpowiedzi, które widzę, działają dobrze w Informixie i są w zasadzie standardowym SQL. To znaczy, notacja:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
działa dobrze z Informixem i, jak się spodziewam, wszystkimi DBMS. (Kiedyś, 5 lub więcej lat temu, jest to rodzaj rzeczy, które MySQL nie zawsze obsługiwał; teraz ma przyzwoite wsparcie dla tego rodzaju standardowej składni SQL i, AFAIK, będzie działać OK na tej notacji). Lista kolumn jest opcjonalna, ale wskazuje kolumny docelowe w kolejności, więc pierwsza kolumna wyniku SELECT trafi do pierwszej wymienionej kolumny, itd. W przypadku braku listy kolumn, pierwsza kolumna wyniku SELECT trafia do pierwszej kolumny tabeli docelowej.
To, co może się różnić pomiędzy systemami, to notacja używana do identyfikacji tabel w różnych bazach danych - standard nie ma nic do powiedzenia na temat operacji pomiędzy bazami danych (nie mówiąc już o operacjach pomiędzy DMS). W Informixie możesz użyć następującej notacji do identyfikacji tabeli:
[dbase[@server]:][owner.]table
Oznacza to, że możesz określić bazę danych, opcjonalnie identyfikując serwer, który hostuje tę bazę danych, jeśli nie jest to bieżący serwer, a następnie opcjonalnego właściciela, kropkę i wreszcie rzeczywistą nazwę tabeli. Standard SQL używa terminu schemat dla tego, co Informix nazywa właścicielem. Tak więc w Informixie dowolna z poniższych notacji może identyfikować tabelę:
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
Właściciel w ogólności nie musi być cytowany; jeśli jednak używasz cudzysłowów, musisz poprawnie przeliterować nazwę właściciela - wielkość liter ma znaczenie. To jest:
someone.table
"someone".table
SOMEONE.table
wszystkie identyfikują tę samą tabelę. W przypadku Informixa, istnieje lekka komplikacja z bazami MODE ANSI, gdzie nazwy właścicieli są zazwyczaj konwertowane na wielkie litery (Informix jest wyjątkiem). Oznacza to, że w bazie MODE ANSI (nieużywanej powszechnie) można napisać:
CREATE TABLE someone.table ( ... )
a nazwa właściciela w katalogu systemowym brzmiałaby "SOMEONE", a nie 'ktoś'. Jeśli nazwa właściciela jest ujęta w cudzysłów, działa jak delimitowany identyfikator. W standardowym SQL-u identyfikatory delimitowane mogą być używane w wielu miejscach. W Informixie można ich używać tylko wokół nazw właścicieli - w innych kontekstach Informix traktuje zarówno łańcuchy z pojedynczym jak i podwójnym cudzysłowem jako łańcuchy, zamiast oddzielać łańcuchy z pojedynczym cudzysłowem jako łańcuchy i łańcuchy z podwójnym cudzysłowem jako identyfikatory delimitowane. (Oczywiście, dla uzupełnienia, istnieje zmienna środowiskowa DELIMIDENT, którą można ustawić na dowolną wartość, ale najbezpieczniejsza jest Y, aby wskazać, że cudzysłowy zawsze otaczają identyfikatory z delimitacją, a pojedyncze cudzysłowy zawsze otaczają łańcuchy).
Zauważ, że MS SQL Server radzi sobie z użyciem [delimited identifiers] ujętego w nawiasy kwadratowe. Wygląda to dla mnie dziwnie i z pewnością nie jest częścią standardu SQL.