it-swarm-eu.dev

Jak funguje tabulka Oracle DUAL?

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

SQL> select 4*5 from dual;

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

SQL>

Připadá mi to opravdu zvláštní. Pokud neexistuje dvojitý sloupec s názvem 4 * 5, jak funguje příkaz select?

Proč také nevidím stejné chování, když vytvářím vlastní duální tabulku?

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

Od Wikipedia :

Tabulka DUAL je speciální jednorozměrná tabulka, která je ve výchozím nastavení ve všech instalacích databáze Oracle. Je vhodný pro použití při výběru pseudo sloupce jako SYSDATE nebo USER. Tabulka obsahuje jeden sloupec VARCHAR2 (1) nazvaný DUMMY, který má hodnotu 'X'.

Duální tabulka je tedy způsob, jak provádět operace s tím, jaké částky jsou prázdné, ale nikoli nulové tabulky. To je užitečné, pokud se o tabulku nestaráte, ale musíte provést operace pomocí příkazu select. Pokud by tabulka měla více než jeden řádek nebo sloupec, bylo by vráceno více výsledků (kvůli práci s celou sadou n-tic při provádění operace).

Nemělo by být použito ve výrobě, pokud si nepotřebujete vyvolat určité procedury pomocí SQL.

4*5 je matematická operace, stejně jako 'Foo' je řetězec. Stejně jako je tedy možné vybrat 4 * 5 z libovolné tabulky, stejně jako lze vybrat „Foo“ z libovolné tabulky, DUAL je způsob, jak ji vybrat ze známé tabulky dobré, která nikdy nebude mít více výsledků.

Z dokumentace (CONCEPTS):

DUAL je malá tabulka v datovém slovníku, na kterou mohou Oracle Database a programy napsané uživateli odkazovat a zaručit tak známý výsledek. Duální tabulka je užitečná, když musí být hodnota vrácena pouze jednou, například aktuální datum a čas. Všichni uživatelé databáze mají přístup k DUAL.

Tabulka DUAL má jeden sloupec nazvaný DUMMY a jeden řádek obsahující hodnotu X.

A SQL Reference :

DUAL je tabulka, kterou Oracle Database automaticky vytvoří spolu s datovým slovníkem. DUAL je ve schématu uživatele SYS, ale je přístupný pod názvem DUAL pro všechny uživatele. Má jeden sloupec DUMMY, definovaný jako VARCHAR2 (1), a obsahuje jeden řádek s hodnotou X. Výběr z tabulky DUAL je užitečný pro výpočet konstantního výrazu pomocí příkazu SELECT. Protože DUAL má pouze jeden řádek, konstanta se vrací pouze jednou. Alternativně můžete z libovolné tabulky vybrat konstantu, pseudo sloupec nebo výraz, ale hodnota bude vrácena tolikrát, kolikrát jsou v tabulce řádky. V části „O funkcích SQL“ najdete mnoho příkladů výběru konstantní hodnoty z DUAL.

Počínaje Oracle Database 10g Release 1 se logické I/O neprovádějí v tabulce DUAL při výpočtu výrazu, který nezahrnuje sloupec DUMMY. Tato optimalizace je v plánu provádění uvedena jako RYCHLE DUÁLNÍ. Pokud vyberete sloupec DUMMY z DUAL, pak k této optimalizaci nedojde a dojde k logickým I/O.

29

DUAL je tabulka s přesně jedním řádkem, jak se zobrazí následující příkaz SQL:

SELECT * FROM dual;

Vaše dual2 tabulka nemá žádné řádky. Pokud jej vložíte, uvidíte stejné chování.

4 * 5 je výraz, který může Oracle vyhodnotit, aniž by skutečně použil data z tabulky. Vyhodnotí ji jednou pro každý řádek, stejně jako by to bylo u normálního výrazu sloupce. Pokud tedy není žádný řádek, není vrácen žádný výsledek, pokud jsou dva řádky, dostanete 20 dvakrát.

18

Tabulka dual "funguje" téměř přesně tak, jak funguje jakákoli jiná tabulka: je to tabulka, ze které můžete vybrat záznamy.

To například znamená, že můžete popsat tabulku. Zde v SQL*Plus:

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

Tabulka má tedy jeden sloupec s názvem dummy, což je varchar2(1).

Tabulka má záměrně jeden záznam (přinejmenším pokud se s ním nikdo neohrál):

SQL> select count(*) from dual;

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

Abychom dosáhli stejného chování s dual2 Jako s dual, musíte vložit jeden záznam do duálního. Ještě lepší je vytvořit pomocí create table as select (Ctas):

SQL> create table dual2 as select * from dual;

Nyní váš dotaz funguje:

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

Dříve jsem řekl, že duální téměř funguje jako každá jiná tabulka. Takže kdy nefunguje jako žádná jiná tabulka?

Chová se jinak, pokud není vybrána žádná hodnota ze samotné tabulky. Opět, s vašimi dotazy, nechám Oracle vysvětlit ...

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

EXPLAIN PLAN ausgef³hrt.

... abyste viděli, jak je tabulka přístupná:

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 |
-------------------------------------------------------------------

Je vidět, že příkaz dělá full table access Na dual2.

Nyní to samé s 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 |
-----------------------------------------------------------------

Zde se tabulka dual chová jinak: hodnota dummy není nutná, takže je provedena operace fast dual, Aby instance nemohla přečíst skutečnou hodnotu. na disku.

14

Mimochodem, DUAL je jedna z mála „tabulek“, která funguje po spuštění instance, ale databáze nebyla otevřena.

Získáte něco podobného

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

Kromě jiných odpovědí Oracle není tak prostý na texty SQL mezer (alespoň na některých místech). Analyzátor SQL také v některých případech tokenizuje rozdíly ve znakové třídě, nejen mezerou.

Můžete například spustit tyto příkazy:

 SQL> vyberte * ze dvou; 
 
 D 
 - 
 X 
 
 
 SQL> vyberte (1) z duálního; 
 
 (1) 
 ---------- 
 1 
 
 SQL> select-null from dual; 
 
 -NULL 
 ---------- 
 
 
 SQL> vyberte-1 z duálních; 
 
 -1 
 ---------- 
 -1 
 
 SQL> 
 

Je také možné spustit SQL bez mezery v něm:

 SQL> vyberte * z/**/dual; 
 
 D 
 - 
 X 
 

Mám zde několik dalších příkladů:

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

Tanel Poder

9
Tanel Poder

Rychlá duální operace přepíše váš kód tak, aby dotazoval x $ dual. Protože tato „tabulka“ je datovou strukturou C v SGA, můžete ji dotazovat v režimu jmenování.

8

Otázka je již zodpovězena. Toto jsou některé poznámky k účelu duální tabulky. Dual lze použít k vyhodnocení výrazů v klauzuli select. Mnoho jiných databázových systémů takovou tabulku pro tento účel nepotřebuje. MS SQL Server, MySql, Posgres může vyhodnotit následující příkaz

select 3+5 ;

Oracle nemůže. Prohlášení Oracle select vždy vyžaduje „od“.

Některé funkce nelze použít ve výrazu pl/sql jako VÝPIS .

Tak

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

vyvolá výjimku, ale

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

bude pracovat.

Může být použit k rozšíření sady výsledků dotazu

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

což dalo

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

nebo generujte data pomocí vybraných dotazů pomocí CONNECT BY:

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

nebo rekurzivní CTE:

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

který se vrací

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

v sqlfiddle

4
miracle173

Pro to, co to stojí za to, funguje to úplně stejným způsobem v MySQL.

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> 

A také se zdá, že DUAL je nějaký druh struktury paměti v MySQL. Všimněte si rozdílu ve dvou vysvětlujících plánech - „nepoužívány tabulky“ pro DUAL v MySQL.

Je zajímavé, že nemůžu udělat DESC pro MySQL duální, který se liší od Oracle - ale byl zaveden konkrétně AIUI, aby Oracle syntaxe mohla pracovat na MySQL.

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

V databázi Oracle se duální tabulka v zásadě používá k získání hodnoty pseudosloupců. Obsahuje následující vlastnosti:

  1. Je ve vlastnictví uživatele sys
  2. Je k dispozici pro všechny uživatele
  3. Obsahuje pouze jeden sloupec, jehož jméno je fiktivní s datovým typem Varchar2 (1). Tento sloupec může mít maximální šířku jednoho znaku.

Pokud chcete získat více podrobností, zaškrtněte zde

2
Vipul