it-swarm-id.com

Bagaimana cara kerja tabel Oracle DUAL?

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

SQL> select 4*5 from dual;

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

SQL>

Saya merasa sangat aneh. Jika tidak ada kolom bernama 4 * 5 dalam dua kali lipat, bagaimana cara kerja pernyataan pilih?

Juga, mengapa saya tidak melihat perilaku yang sama ketika saya membuat tabel ganda sendiri?

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

Dari Wikipedia :

Tabel DUAL adalah tabel satu-baris khusus yang hadir secara default di semua instalasi basis data Oracle. Sangat cocok untuk digunakan dalam memilih pseudocolumn seperti SYSDATE atau USER. Tabel ini memiliki kolom VARCHAR2 (1) tunggal yang disebut DUMMY yang memiliki nilai 'X'.

Dengan demikian, tabel ganda adalah cara untuk melakukan operasi terhadap jumlah yang menjadi tabel kosong tetapi tidak nol. Ini berguna ketika seseorang tidak peduli tentang tabel, tetapi perlu melakukan operasi melalui pernyataan pilih. Jika tabel memiliki lebih dari satu baris atau kolom, beberapa hasil akan dikembalikan (karena beroperasi pada seluruh rangkaian tupel saat melakukan operasi.)

Seharusnya tidak digunakan dalam produksi, kecuali jika Anda secara khusus perlu menjalankan prosedur tertentu melalui SQL.

4*5 adalah operasi matematika, sama seperti 'Foo' adalah string. Jadi, seperti halnya seseorang dapat memilih 4 * 5 dari tabel mana pun, seperti halnya seseorang dapat memilih 'Foo' dari tabel mana pun, DUAL adalah cara untuk memilihnya dari tabel yang dikenal baik yang tidak akan pernah memiliki banyak hasil.

Dari dokumentasi (CONCEPTS):

DUAL adalah tabel kecil dalam kamus data yang dapat dirujuk oleh Oracle Database dan program yang ditulis pengguna untuk menjamin hasil yang diketahui. Tabel ganda berguna ketika nilai harus dikembalikan hanya sekali, misalnya, tanggal dan waktu saat ini. Semua pengguna basis data memiliki akses ke DUAL.

Tabel DUAL memiliki satu kolom yang disebut DUMMY dan satu baris yang berisi nilai X.

Dan Referensi SQL :

DUAL adalah tabel yang secara otomatis dibuat oleh Oracle Database bersama dengan kamus data. DUAL ada dalam skema SYS pengguna tetapi dapat diakses dengan nama DUAL untuk semua pengguna. Ini memiliki satu kolom, DUMMY, didefinisikan sebagai VARCHAR2 (1), dan berisi satu baris dengan nilai X. Memilih dari tabel DUAL berguna untuk menghitung ekspresi konstan dengan pernyataan SELECT. Karena DUAL hanya memiliki satu baris, konstanta dikembalikan hanya sekali. Sebagai alternatif, Anda dapat memilih konstanta, pseudocolumn, atau ekspresi dari tabel mana pun, tetapi nilainya akan dikembalikan berkali-kali karena ada baris dalam tabel. Lihat "Tentang Fungsi SQL" untuk banyak contoh memilih nilai konstan dari DUAL.

Dimulai dengan Oracle Database 10g Release 1, I/O logis tidak dilakukan pada tabel DUAL saat menghitung ekspresi yang tidak termasuk kolom DUMMY. Optimasi ini terdaftar sebagai DUAL CEPAT dalam rencana eksekusi. Jika Anda MEMILIH kolom DUMMY dari DUAL, maka pengoptimalan ini tidak terjadi dan terjadi I/O yang logis.

29

DUAL adalah tabel dengan persis satu baris seperti yang ditampilkan oleh pernyataan SQL berikut:

SELECT * FROM dual;

Anda dual2 table tidak memiliki baris. Jika Anda memasukkan satu, Anda akan melihat perilaku yang sama.

4 * 5 adalah ekspresi yang dapat dievaluasi Oracle tanpa benar-benar menggunakan data dari tabel. Ini akan mengevaluasi satu kali untuk setiap baris, sama seperti yang akan dilakukan dengan ekspresi kolom normal. Jadi jika tidak ada baris, tidak ada hasil yang dikembalikan, jika ada dua baris, Anda akan mendapatkan 20 dua kali.

18

Tabel dual "berfungsi" hampir seperti cara kerja tabel lainnya: ini adalah tabel tempat Anda dapat memilih catatan.

Ini berarti, misalnya, Anda bisa menggambarkan tabel. Di sini, di SQL*Plus:

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

Jadi, tabel memiliki satu kolom, bernama dummy yang merupakan varchar2(1).

Tabel memiliki, menurut desain, satu catatan (setidaknya jika tidak ada yang mengotak-atiknya):

SQL> select count(*) from dual;

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

Jadi, untuk mendapatkan perilaku yang sama dengan dual2 Seperti yang Anda miliki dengan dual, Anda harus memasukkan satu rekaman menjadi dua. Lebih baik lagi, buat dengan create table as select (Ctas):

SQL> create table dual2 as select * from dual;

Sekarang, permintaan Anda berfungsi:

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

Sebelumnya, saya mengatakan bahwa dual hampir berfungsi seperti tabel lainnya. Jadi, kapan tidak berfungsi seperti tabel lainnya?

Itu berperilaku berbeda, jika tidak ada nilai dari tabel itu sendiri dipilih. Sekali lagi, dengan pertanyaan Anda, saya membiarkan Oracle jelaskan mereka ...

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

EXPLAIN PLAN ausgef³hrt.

... untuk melihat bagaimana tabel diakses:

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

Dapat dilihat bahwa pernyataan melakukan full table access Pada dual2.

Sekarang, hal yang sama dengan 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 |
-----------------------------------------------------------------

Di sinilah tabel dual berperilaku berbeda: nilai dummy tidak diperlukan, jadi operasi fast dual Dijalankan, agar instance tidak membaca nilai aktual pada disk.

14

Secara kebetulan, DUAL adalah salah satu dari beberapa 'tabel' yang berfungsi ketika instance telah dimulai tetapi database belum dibuka.

Anda mendapatkan sesuatu seperti

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

Selain jawaban lain, Oracle tidak begitu pilih-pilih tentang spasi teks SQL (setidaknya di beberapa tempat). Parser SQL juga ditandai oleh perbedaan kelas karakter dalam beberapa kasus, bukan hanya oleh spasi putih.

Misalnya, Anda dapat menjalankan pernyataan seperti itu:

 SQL> select * from dual; 
 
 D 
 - 
 X 
 
 
 SQL> pilih (1) dari dua; 
 
 (1) 
 ---------- 
 1 
 
 SQL> select-null dari dual; 
 
 -NULL 
 ---------- 
 
 
 SQL> select-1 from dual; 
 
 -1 
 ---------- 
 -1 
 
 SQL> 
 

Juga dimungkinkan untuk menjalankan SQL tanpa spasi di dalamnya:

 SQL> pilih * dari/**/dual; 
 
 D 
 - 
 X 
 

Saya punya beberapa contoh lagi di sini:

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

Tanel Poder

9
Tanel Poder

Operasi ganda cepat menulis ulang kode Anda ke kueri x $ ganda. Karena "tabel" ini adalah struktur data C dalam SGA, Anda dapat menanyakannya dalam mode nomount.

8

Pertanyaannya sudah dijawab. Ini adalah beberapa catatan untuk tujuan tabel ganda. Ganda dapat digunakan untuk mengevaluasi ekspresi dalam klausa pilih. Banyak sistem basis data lainnya tidak memerlukan tabel seperti itu untuk tujuan ini. MS SQL Server, MySql, Posgres dapat mengevaluasi pernyataan berikut

select 3+5 ;

Oracle tidak bisa. Pernyataan pilih Oracle selalu membutuhkan "from" -clause.

Beberapa fungsi tidak dapat digunakan dalam ekspresi pl/sql seperti DUMP .

Begitu

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

akan memunculkan eksepsi tetapi

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

akan bekerja.

Itu bisa digunakan untuk memperpanjang set hasil dari suatu query

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

yang memberi

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

atau menghasilkan data dengan kueri pemilihan menggunakan CONNECT BY:

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

atau CTE rekursif:

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

yang kembali

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

di sqlfiddle

4
miracle173

Untuk apa nilainya, ia bekerja dengan cara yang persis sama di 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> 

Dan juga tampak bahwa DUAL adalah semacam struktur memori di MySQL juga. Perhatikan perbedaan dalam dua menjelaskan rencana - "tidak ada tabel yang digunakan" untuk DUAL di MySQL.

Namun yang menarik, saya tidak dapat melakukan DESC pada dual MySQL, yang berbeda dengan Oracle - tetapi diperkenalkan khusus AIUI untuk memungkinkan sintaks Oracle bekerja pada 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

Dalam database Oracle, Dual table pada dasarnya digunakan untuk mendapatkan nilai pseudo-kolom. Ini berisi properti berikut:

  1. Dimiliki oleh pengguna sys
  2. Ini tersedia untuk semua pengguna
  3. Ini hanya berisi satu kolom yang namanya dummy dengan datatype Varchar2 (1), kolom ini dapat memiliki lebar maksimum satu karakter.

Jika Anda ingin mendapatkan detail lebih lanjut, periksa di sini

2
Vipul