it-swarm.com.de

Wie funktioniert die Oracle DUAL-Tabelle?

SQL> desc dual
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 DUMMY                                              VARCHAR2(1)

SQL> select 4*5 from dual;

       4*5
----------
        20

SQL>

Ich finde es wirklich seltsam. Wie funktioniert die select-Anweisung, wenn es keine Spalte mit dem Namen 4 * 5 in dual gibt?

Warum sehe ich nicht dasselbe Verhalten, wenn ich meine eigene Doppeltabelle erstelle?

SQL> create table dual2(dummy varchar2(1)); 

Table created.

SQL> desc dual2
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 DUMMY                                              VARCHAR2(1)

SQL> select 4*5 from dual2;

no rows selected

SQL> 
32
Lazer

Von Wikipedia :

Die DUAL-Tabelle ist eine spezielle einzeilige Tabelle, die standardmäßig in allen Oracle-Datenbankinstallationen vorhanden ist. Es eignet sich zur Auswahl einer Pseudospalte wie SYSDATE oder USER. Die Tabelle enthält eine einzelne VARCHAR2 (1) -Spalte namens DUMMY mit dem Wert 'X'.

Somit ist die duale Tabelle eine Möglichkeit, Operationen für eine leere, aber nicht nullte Tabelle auszuführen. Dies ist nützlich, wenn man sich nicht um die Tabelle kümmert, sondern Operationen über eine select-Anweisung ausführen muss. Wenn die Tabelle mehr als eine Zeile oder Spalte enthält, werden mehrere Ergebnisse zurückgegeben (aufgrund der Operation über den gesamten Satz von Tupeln bei der Ausführung der Operation).

Es sollte nicht in der Produktion verwendet werden, es sei denn, Sie müssen bestimmte Prozeduren speziell über SQL aufrufen.

4*5 ist eine mathematische Operation, genau wie 'Foo' ist eine Zeichenfolge. So wie man 4 * 5 aus jeder Tabelle auswählen kann, so wie man 'Foo' aus jeder Tabelle auswählen kann, ist DUAL eine Möglichkeit, es aus einer bekanntermaßen guten Tabelle auszuwählen, die niemals mehrere Ergebnisse haben wird.

Aus dem Dokumentation (KONZEPTE):

DUAL ist eine kleine Tabelle im Datenwörterbuch, auf die Oracle Database und benutzerdefinierte Programme verweisen können, um ein bekanntes Ergebnis zu gewährleisten. Die Doppeltabelle ist nützlich, wenn ein Wert nur einmal zurückgegeben werden muss, z. B. das aktuelle Datum und die aktuelle Uhrzeit. Alle Datenbankbenutzer haben Zugriff auf DUAL.

Die DUAL-Tabelle enthält eine Spalte mit dem Namen DUMMY und eine Zeile mit dem Wert X.

Und die SQL-Referenz :

DUAL ist eine Tabelle, die von Oracle Database zusammen mit dem Datenwörterbuch automatisch erstellt wird. DUAL befindet sich im Schema des Benutzers SYS, ist jedoch für alle Benutzer unter dem Namen DUAL zugänglich. Es hat eine Spalte, DUMMY, die als VARCHAR2 (1) definiert ist, und enthält eine Zeile mit dem Wert X. Die Auswahl aus der DUAL-Tabelle ist nützlich, um einen konstanten Ausdruck mit der SELECT-Anweisung zu berechnen. Da DUAL nur eine Zeile hat, wird die Konstante nur einmal zurückgegeben. Alternativ können Sie eine Konstante, eine Pseudospalte oder einen Ausdruck aus einer beliebigen Tabelle auswählen. Der Wert wird jedoch so oft zurückgegeben, wie Zeilen in der Tabelle vorhanden sind. Unter "Informationen zu SQL-Funktionen" finden Sie viele Beispiele für die Auswahl eines konstanten Werts aus DUAL.

Ab Oracle Database 10g Release 1 werden keine logischen E/A-Vorgänge für die DUAL-Tabelle ausgeführt, wenn ein Ausdruck berechnet wird, der die DUMMY-Spalte nicht enthält. Diese Optimierung wird im Ausführungsplan als FAST DUAL aufgeführt. Wenn Sie die Spalte DUMMY aus DUAL AUSWÄHLEN, findet diese Optimierung nicht statt und es erfolgt eine logische E/A.

29

DUAL ist eine Tabelle mit genau einer Zeile, wie die folgende SQL-Anweisung zeigt:

SELECT * FROM dual;

Ihre dual2 Tabelle hat keine Zeilen. Wenn Sie eine einfügen, sehen Sie dasselbe Verhalten.

4 * 5 ist ein Ausdruck, den Oracle auswerten kann, ohne tatsächlich Daten aus der Tabelle zu verwenden. Es wird einmal für jede Zeile ausgewertet, genau wie bei einem normalen Spaltenausdruck. Wenn also keine Zeile vorhanden ist, wird kein Ergebnis zurückgegeben. Wenn zwei Zeilen vorhanden sind, erhalten Sie die 20 zweimal.

18

Die dual -Tabelle "funktioniert" fast genau wie jede andere Tabelle: Es ist eine Tabelle, aus der Sie Datensätze auswählen können.

So können Sie beispielsweise die Tabelle beschreiben. Hier in SQL*Plus:

SQL> set lines 50
SQL> desc dual
Name                    Null?    Typ
----------------------- -------- ----------------
DUMMY                            VARCHAR2(1)

Die Tabelle enthält also eine Spalte mit dem Namen dummy, die eine varchar2(1) ist.

Der Tisch hat von Natur aus einen Datensatz (zumindest wenn niemand damit herumgespielt hat):

SQL> select count(*) from dual;

COUNT(*)
----------
         1

Um mit dual2 Das gleiche Verhalten wie mit dual zu erzielen, müssen Sie einen Datensatz in dual einfügen. Besser noch, erstellen Sie es mit einem create table as select (Ctas):

SQL> create table dual2 as select * from dual;

Jetzt funktioniert Ihre Abfrage:

SQL> select 4*5 from dual2;
       4*5
----------
        20

Vorhin habe ich gesagt, dass dual fast wie jede andere Tabelle funktioniert. Also, wann funktioniert es nicht wie jede andere Tabelle?

Es verhält sich anders, wenn kein Wert aus der Tabelle selbst ausgewählt ist. Wieder mit Ihren Fragen lasse ich Oracle erklären sie ...

SQL> set lines 150
SQL> explain plan for select 4*5 from dual2;

EXPLAIN PLAN ausgef³hrt.

... um zu sehen, wie auf die Tabelle zugegriffen wird:

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------
Plan hash value: 3445655939

-------------------------------------------------------------------
| Id  | Operation         | Name  | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT  |       |     1 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| DUAL2 |     1 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------

Es ist ersichtlich, dass die Anweisung einen full table access Für dual2 Ausführt.

Nun dasselbe mit dual:

SQL> explain plan for select 4*5 from dual;

EXPLAIN PLAN ausgef³hrt.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------
Plan hash value: 1388734953

-----------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     1 |     2   (0)| 00:00:01 |
|   1 |  FAST DUAL       |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------

Hier verhält sich die Tabelle dual anders: Der Wert von dummy wird nicht benötigt, daher wird eine Operation fast dual Ausgeführt, damit die Instanz den tatsächlichen Wert nicht liest auf der Festplatte.

14

DUAL ist übrigens eine der wenigen 'Tabellen', die funktionieren, wenn die Instanz gestartet wurde, die Datenbank jedoch nicht geöffnet wurde.

Du bekommst so etwas wie

ADDR     INDX   INST_ID D
-------- ------ ------- -
0C0362D4      0       1 X
10
Gary

Zusätzlich zu anderen Antworten ist Oracle nicht so wählerisch in Bezug auf den Leerzeichen-SQL-Text (zumindest an einigen Stellen). Der SQL-Parser wird in einigen Fällen auch durch Zeichenklassenunterschiede gekennzeichnet, nicht nur durch Leerzeichen.

Sie können beispielsweise folgende Anweisungen ausführen:

 SQL> wählen Sie * aus dual; 
 
 D 
 - 
 X 
 
 
 SQL> Wählen Sie (1) aus Dual; 
 
 (1) 
 ---------- 
 1 
 
 SQL> select-null from dual; 
 
 -NULL 
 ---------- 
 
 
 SQL> wähle-1 aus dual; 
 
 -1 
 ---------- 
 -1 
 
 SQL> 
 

Es ist auch möglich, SQL ohne Leerzeichen auszuführen:

 SQL> wählen Sie * aus/**/dual; 
 
 D 
 - 
 X 
 

Ich habe hier noch einige Beispiele:

http://blog.tanelpoder.com/2008/01/14/can-you-write-a-working-sql-statement-without-using-any-whitespace/

Tanel Poder

9
Tanel Poder

Eine schnelle Doppeloperation schreibt Ihren Code neu, um x $ dual abzufragen. Da diese "Tabelle" eine C-Datenstruktur in der SGA ist, können Sie sie im Nomount-Modus abfragen.

Die Frage ist bereits beantwortet. Dies sind einige Anmerkungen zum Zweck der Doppeltabelle. Dual kann verwendet werden, um Ausdrücke in einer select-Klausel auszuwerten. Viele andere Datenbanksysteme benötigen zu diesem Zweck keine solche Tabelle. MS SQL Server, MySql, Posgres kann die folgende Anweisung auswerten

select 3+5 ;

Oracle kann nicht. Eine Oracle-Select-Anweisung benötigt immer eine "from" -Klausel.

Einige Funktionen wie DUMP können im pl/sql-Ausdruck nicht verwendet werden.

Damit

declare
str varchar2(100);
begin
str:=dump('Hallo');
end;
/

wird aber eine Ausnahme auslösen

declare
str varchar2(100);
begin
select dump('Hallo') into str from dual;
end;
/

wird funktionieren.

Es kann verwendet werden, um die Ergebnismenge einer Abfrage zu erweitern

select user_id,username from user_users
union all
select -1,'NO USER'
from dual
/

was gab

| USER_ID |     USERNAME |
|---------|--------------|
|  476267 | USER_4_E8C50 |
|      -1 |      NO USER |

oder generieren Sie Daten mit ausgewählten Abfragen mit CONNECT BY:

select level as n 
from dual
connect by level <= 5 ;

oder ein rekursiver CTE:

with nlist(n) as (
  select 1 from dual
  union all
  select n+1
  from nlist 
  where n<5    )
select n
from nlist
 ;

was zurückkehrt

| N |
|---|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |

in sqlfiddle

4
miracle173

Für das, was es wert ist, funktioniert es in MySQL genauso.

mysql> use test;
Database changed

mysql> create table fred(billy int);
Query OK, 0 rows affected (0.79 sec)

mysql> select 4 + 5 from fred;
Empty set (0.00 sec)

mysql> select 4 + 5 as mary from fred;
Empty set (0.00 sec)

mysql> insert into fred values(1);
Query OK, 1 row affected (0.13 sec)

mysql> select 4 + 5 from fred;
+-------+
| 4 + 5 |
+-------+
|     9 |
+-------+
1 row in set (0.00 sec)

mysql> select 4 + 5 as mary from fred;
+------+
| mary |
+------+
|    9 |
+------+
1 row in set (0.00 sec)

mysql> insert into fred values(2);
Query OK, 1 row affected (0.08 sec)

mysql> select 4 + 5 from fred;
+-------+
| 4 + 5 |
+-------+
|     9 |
|     9 |
+-------+
2 rows in set (0.00 sec)

mysql> select 4 + 5 as mary from fred;
+------+
| mary |
+------+
|    9 |
|    9 |
+------+
2 rows in set (0.00 sec)

mysql> explain select 4 + 5 as mary from fred;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | fred  | ALL  | NULL          | NULL | NULL    | NULL |    2 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

mysql> 

Und es scheint auch, dass DUAL auch in MySQL eine Art Speicherstruktur ist. Beachten Sie den Unterschied zwischen den beiden Erklärungsplänen - "Keine Tabellen verwendet" für DUAL in MySQL.

Interessanterweise kann ich jedoch kein DESC für MySQL Dual ausführen, das sich von Oracle unterscheidet. Es wurde jedoch speziell für AIUI eingeführt, damit die Oracle-Syntax unter MySQL funktioniert.

mysql> select 4 + 5 from dual;
+-------+
| 4 + 5 |
+-------+
|     9 |
+-------+
1 row in set (0.00 sec)

mysql> explain select 4 + 5 from dual;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | No tables used |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

mysql> desc dual;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'dual' at line 1
mysql> 
3
Vérace

In der Oracle-Datenbank wird die Dual-Tabelle im Wesentlichen verwendet, um den Wert von Pseudospalten abzurufen. Es enthält folgende Eigenschaften:

  1. Es gehört dem sys-Benutzer
  2. Es ist für alle Benutzer verfügbar
  3. Es enthält nur eine Spalte, deren Name Dummy mit dem Datentyp Varchar2 (1) ist. Diese Spalte kann eine maximale Breite von einem Zeichen haben.

Wenn Sie mehr Details erhalten möchten, überprüfen Sie hier

2
Vipul