Dies funktioniert in den wichtigsten Relation Database Management-Systemen, die am wahrscheinlichsten in StackOverflow / dba.stackexchange vorkommen: SQL Server, MySQL, PostgreSQL und SQLite (WebSQL) .
select 'abc' abc, 1 def;
Unter Oracle funktioniert es nicht. Warum müssen wir in Oracle aus DUAL auswählen? Erfordert der ISO / ANSI-Standard für SQL eine FROM-Klausel für SELECT- Anweisungen?
Bearbeiten:
Per Bacon Bit
's Antwort scheint es durch den SQL-Standard erforderlich zu sein.
Also in Wirklichkeit, weil der Name DUAL so eine Fehlbezeichnung ist, wenn ich eine Tabelle erstellen und sie ATOM oder ONE nennen würde, zB create table one (atom int);
. select 'abc' abc, 1 def FROM one;
- Gibt es eine Leistungsminderung im Vergleich zu SELECT .. FROM DUAL
?
select
ohne a nicht auskommenfrom
. DB2 verfügt über eine ähnliche Dummy-Tabelle mit dem Namen SYSIBM.SYSDUMMY1 . Das wissen Sie wahrscheinlich auch schon, aber wenn Sie aufselect 'A' from dual
diedual
Tabelle nicht wirklich zugreifen, wird die Frage in Ihrer Bearbeitung beantwortet (die übrigens eine neue Frage verdient hat).FROM
Klausel. Aus dem Häuschen: Informix, Firebird und Apache Derby benötigen es auch.values ('abc', 1)
. Sie können natürlich auch aus solchen Aussagen auswählen:select abc from ( values ('abc',1) ) as t(abc,def)
Antworten:
Genau genommen ist die
FROM
Klausel einerSELECT
Aussage nicht optional. Die Syntax für SQL-99 beschreibt die grundlegendenSELECT
Anweisungen, und dieFROM
Klausel enthält keine eckigen Klammern. Dies zeigt an, dass der Standard dies als nicht optional ansieht:In der Praxis ist es für Programmierer und Datenbankadministratoren häufig nützlich, andere Aktionen als die Bearbeitung von Daten in Tabellen oder die Bearbeitung von Tabellen und Datenstrukturen durchzuführen. Diese Art von Dingen geht weit über den Geltungsbereich des SQL-Standards hinaus, der sich mehr mit den Datenmerkmalen befasst als mit den Schrauben und Muttern bestimmter Implementierungen. Egal, ob wir ausführen möchten
SELECT getdate()
oderSELECT 1
oderSELECT DB_NAME()
(oder was auch immer Ihr Dialekt bevorzugt), wir möchten eigentlich keine Daten aus einer Tabelle.Oracle entscheidet sich dafür, die Standard- und Implementierungsdiskrepanz mithilfe einer Dummy-Tabelle mit der folgenden effektiven Definition zu beheben:
Andere RDBMS setzen im Wesentlichen voraus, dass eine Dummy-Tabelle verwendet wird, wenn no
FROM
angegeben ist.Die Geschichte der DUAL-Tabelle ist auf Wikipedia:
quelle
Der
dual
Optimierer hat den Vorteil, dass erdual
eine spezielle Tabelle mit einer Zeile und einer Spalte (mitvarchar2
Datentyp) versteht. Wenn Sie sie in Abfragen verwenden, wird dieses Wissen bei der Entwicklung des Plans verwendet.Warum müssen wir
dual
in Oracle eine Auswahl treffen?Sie können auch aus
dual
oder aus Ihren eigenen Tabellen auswählen , wenn Sie möchten.Für mich bleibe
dual
ich dabei, weil ich weiß, dass esdual
existiert. Ich weiß, dass es mindestens 1 und höchstens 1 Zeile hat. Ich weiß, dass der Optimierer alles weißdual
und das effizienteste für mich tut. Der Optimierer verstehtdual
eine magische, spezielle 1-zeilige Tabelle. Es hörte auf,select *
weil es dort eine Reihe geben soll. So funktioniert es einfach.quelle
DUAL
. Achtung!Die beiden anderen Antworten liefern einen guten Hintergrund für meine Antwort.
In Oracle-Datenbanken ist dies traditionell und zuverlässig. Bei anderen Datenbanken, die keine
DUAL
Tabelle haben, schlägt dies fehl . Es ist nicht notwendig, dass Sie verwendenDUAL
, aber ich würde Ihnen empfehlen, dies zu tun.Für standardkonforme Datenbanken ist eine
FROM
Klausel erforderlich , in der mindestens ein Tabellenverweis angegeben ist. Wenn Sie eine ORDERS-Tabelle haben, funktioniert der folgende Ersatz für dieFROM DUAL
Klausel:Ersetzen Sie jede Tabelle oder Ansicht, aus der Sie auswählen können, und es wird funktionieren. Ersetzen Sie eine Tabelle oder Ansicht, aus der Sie nicht auswählen können, und dies schlägt fehl.
DUAL
Dies ist zuverlässiger, da ein Datenbankadministrator es nicht unterbrechen kann. Alle Benutzer können daraus auswählen und erhalten nur eine Zeile in der Ergebnismenge. (Es wird gelegentlich kaputt.)Mir ist kein standardkonformes Verb für den Zugriff auf Daten bekannt, die sich nicht in einer Tabelle befinden, ohne einen Tabellenverweis anzugeben. Angesichts dessen, wie wenig ich auf solche Daten zugreife, sehe ich keinen solchen Bedarf. Viele der Fälle, auf die ich stoße, können auf unterschiedliche Weise besser behandelt werden.
quelle
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)
ist standardkonform, glaube ich, und verlässt sich nicht auf eine bestimmte Tabelle.