Oracle DUAL tablosu nasıl çalışır?


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

SQL> select 4*5 from dual;

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

SQL>

Bunu gerçekten garip buluyorum. Çift olarak 4 * 5 adında bir sütun yoksa, select cümlesi nasıl çalışır?

Ayrıca, kendi ikili masamı oluştururken neden aynı davranışı görmüyorum?

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> 

Yanıtlar:


29

Gönderen Vikipedi :

DUAL tablosu, tüm Oracle veritabanı kurulumlarında varsayılan olarak mevcut olan özel bir tek tablodur. SYSDATE veya KULLANICI gibi bir sahte sütun seçmede kullanım için uygundur. Tabloda DUMMY adlı ve 'X' değerinde tek bir VARCHAR2 (1) sütunu var.

Bu nedenle, ikili tablo, boş ancak boş olmayan bir tablo olan miktarlara karşı işlemleri gerçekleştirmenin bir yoludur. Bu, bir tabloyu önemsemediğinde, ancak bir select ifadesiyle işlemleri gerçekleştirmesi gerektiğinde yararlıdır. Tabloda birden fazla satır veya sütun varsa, birden fazla sonuç döndürülür (işlemi gerçekleştirirken tüm tupler kümesi üzerinde işlem yapılması nedeniyle).

Belirli prosedürleri SQL yoluyla çağırmanız gerekmedikçe, üretimde kullanılmamalıdır.

4*5'Foo' dize gibi matematiksel bir işlemdir . Böylece, herhangi bir masadan 4x5'i seçebildiği gibi, herhangi bir masadan 'Foo'yu da seçebildiği gibi, DUAL, onu asla çok sayıda sonuç vermeyecek olan iyi bilinen bir masadan seçmenin bir yoludur.

Gönderen belgeler (KAVRAMLAR):

DUAL, veri sözlüğünde, Oracle Database ve kullanıcı tarafından yazılmış programların bilinen bir sonucu garanti etmek için başvurabilecekleri küçük bir tablodur. İkili tablo, bir değerin yalnızca bir kez, örneğin geçerli tarih ve saat olarak döndürülmesi gerektiğinde faydalıdır. Tüm veritabanı kullanıcılarının DUAL'e erişimi var.

DUAL tablosunun DUMMY adlı bir sütunu ve X değerini içeren bir satır vardır.

Ve SQL Referansı :

DUAL, Oracle Database tarafından veri sözlüğü ile birlikte otomatik olarak oluşturulan bir tablodur. DUAL, SYS kullanıcısının şemasındadır, ancak tüm kullanıcılara DUAL adıyla erişilebilir. VARCHAR2 (1) olarak tanımlanan bir DUMMY sütunu vardır ve X değeri olan bir satır içerir. DUAL tablosundan seçim, SELECT ifadesiyle sabit bir ifade hesaplamak için kullanışlıdır. DUAL'in yalnızca bir satırı olduğundan, sabit yalnızca bir kez döndürülür. Alternatif olarak, herhangi bir tablodan bir sabit, sözde sütun veya ifade seçebilirsiniz, ancak değer tablodaki satırlar kadar çok sayıda döndürülür. DUAL'den sabit bir değer seçmenin birçok örneği için "SQL İşlevleri Hakkında" bölümüne bakın.

Oracle Database 10g Sürüm 1'den başlayarak, DUMMY sütunu içermeyen bir ifadeyi hesaplarken DUAL tablosunda mantıksal G / Ç işlemi gerçekleştirilmez. Bu optimizasyon yürütme planında HIZLI ÇİFT olarak listelenmiştir. DUMMY sütununu DUAL'den SEÇerseniz, bu optimizasyon gerçekleşmez ve mantıksal G / Ç işlemleri gerçekleşir.


5
“Özel olarak SQL ile belirli prosedürleri çağırmanız gerekmedikçe, üretimde kullanılmamalıdır” Neden olmasın?
Nick Pierpoint

2
Üretimde kullanılmaması gerektiğine de katılıyorum. Bu bana "rostoyu kes" ucunu gibi geliyor.
ErikE

1
Bu cevabın kendisi ile aynı fikirde olmadığı için iyileştirilmesi gerekiyor. Bir yerde, resmi belgelerden kopyalar: "İkili masa faydalıdır " ve diğerinde ise " Üretimde kullanılmaması gerekir ..."
önerilmektedir

18

DUAL aşağıdaki SQL ifadesinin göstereceği gibi tam olarak bir satır içeren bir tablodur:

SELECT * FROM dual;

Masanızda dual2hiç sıra yok. Bir tane eklerseniz, aynı davranışı göreceksiniz.

4 * 5, Oracle'ın tablodaki verileri kullanmadan değerlendirebileceği bir ifadedir. Normal bir sütun ifadesinde olduğu gibi, her satır için bir kez değerlendirir. Yani satır yoksa, sonuç döndürülmez, iki satır varsa, 20'yi iki kez alırsınız.


14

dualTablo "çalışır" neredeyse başka tablo çalışmaları sadece yol: Eğer kayıtları seçebileceğiniz bir tablodur.

Bu, örneğin, masayı tanımlayabileceğiniz anlamına gelir. Burada SQL*Plus:

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

Yani, tablonun adı a dummyolan bir sütun vardır varchar2(1).

Tabloda, tasarım gereği, bir kayıt var (en azından kimse anlamadıysa):

SQL> select count(*) from dual;

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

Yani, aynı davranışa sahip dual2olmak için dual, ile aynı rekoru ikiye katlamalısınız. Daha da iyisi, bir create table as select(ctas) ile oluşturun:

SQL> create table dual2 as select * from dual;

Şimdi, sorgunuz çalışıyor:

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

Daha önce, dual'in neredeyse diğer masalar gibi çalıştığını söyledim . Peki, ne zaman başka bir masa gibi çalışmıyor?

Tablonun kendisinden bir değer seçilmezse, farklı davranır. Yine, sorularınızla Oracle'ın bunları açıklamasına izin verdim ...

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

EXPLAIN PLAN ausgef³hrt.

... masaya nasıl erişildiğini görmek için:

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

Deyim bir yaptığı görülebilir full table accessüzerinde dual2.

Şimdi, aynı şey 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 |
-----------------------------------------------------------------

Bu, dualtablonun farklı davrandığı yerdir : değeri dummygerekli değildir, bu nedenle fast dualörneğin diskteki gerçek değeri okumaması için bir işlem gerçekleştirilir.


10

Bu arada, DUAL, örnek başlatıldığında ancak veritabanı açılmadığında çalışan birkaç tablodan biridir.

Gibi bir şey olsun

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

9

Diğer yanıtlara ek olarak, Oracle, SQL metni (en azından bazı yerlerde) alanlarda çok seçici değildir. SQL ayrıştırıcısı, bazı durumlarda sadece boşluklarla değil, karakter sınıfı farklılıklarıyla da belirtiyor.

Örneğin, böyle ifadeleri çalıştırabilirsiniz:

SQL> dual'den * seçin;

D
-
X


SQL> dualden (1) seçim yapın;

       (1)
----------
         1

SQL> dual'den select-null;

     -BOŞ
----------


SQL> dualden seç-1;

        -1
----------
        -1

SQL> 

SQL'i içinde herhangi bir boşluk olmadan çalıştırmak da mümkündür:

SQL> / ** / / arasından seç *;

D
-
X

Burada başka örneklerim var:

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

Tanel Poder


2
Bu çok alanı atlamak için yeteneği, Oracle için benzersiz değil. SQL Server'da aynı çalışır.
ErikE

8

Hızlı bir çift işlem, x $ dual sorgusunu sorgulamak için kodunuzu yeniden yazar. Bu "tablo" SGA'daki bir C veri yapısı olduğundan, nomount modunda sorgulayabilirsiniz.


4

Soru çoktan cevaplandı. Bunlar ikili tablonun amacı için bazı notlar. Dual, bir seçim cümlesinde ifadeleri değerlendirmek için kullanılabilir. Diğer birçok veritabanı sisteminin bu amaç için böyle bir masaya ihtiyacı yoktur. MS SQL Server, MySQL, Posgres aşağıdaki ifadeyi değerlendirebilir

select 3+5 ;

Oracle yapamaz. Bir Oracle select ifadesi her zaman bir "dan" derdiyle sonuçlanır.

Bazı işlevler, DUMP gibi pl / sql ifadesinde kullanılamaz .

Yani

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

bir istisna uyandıracak

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

çalışacak.

Bir sorgunun sonuç kümesini genişletmek için kullanılabilir

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

hangi verdi

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

veya aşağıdakilerden birini kullanarak seçili sorgularla veri oluşturun CONNECT BY:

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

veya özyinelemeli bir CTE:

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

hangi döner

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

içinde sqlfiddle


3

Buna değer, MySQL'de aynı şekilde çalışır.

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> 

Ayrıca, DUAL’nin MySQL’de de bir çeşit bellek yapısı olduğu anlaşılıyor. İki açıklama planındaki farka dikkat edin - MySQL'deki DUAL için "tablo kullanılmadı".

Ancak ilginç bir şekilde, MySQL'in Oracle'ından farklı olan bir DESC yapamıyorum - ancak Oracle sözdiziminin MySQL üzerinde çalışmasına izin vermek için özel olarak AIUI tanıtıldı.

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> 

2

Oracle veritabanında, Dual tablo temel olarak sözde sütunların değerini almak için kullanılır. Aşağıdaki özellikleri içerir:

  1. Bu sys kullanıcısına aittir
  2. Tüm kullanıcılar tarafından kullanılabilir
  3. Bu veri türü Varchar2 (1) veri tipinde kukla olan yalnızca bir sütun içerir, Bu sütun bir karakter maksimum genişliğe sahip olabilir.

Daha fazla ayrıntı almak istiyorsanız, buraya bakın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.