Neden ikili tablodan seçim yapmam gerekiyor?


15

Bu, SQL Server, MySQL, PostgreSQL ve SQLite (WebSQL) olmak üzere StackOverflow / dba.stackexchange'te görünme olasılığı olan büyük İlişki Veritabanı Yönetim Sistemlerinde çalışır .

select 'abc' abc, 1 def;

Oracle üzerinde çalışmaz. Oracle'da neden DUAL arasından seçim yapmamız gerekiyor? SQL için ISO / ANSI standardı SELECT deyimleri için bir FROM yantümcesi gerektiriyor mu?


Düzenle:

Cevabına Bacon Bitgöre, SQL standardı tarafından gerekli görülüyor.

Yani gerçekte, DUAL adı böyle bir yanlış adlandırma olduğu için, eğer bir tablo oluşturup ATOM ya da ONE olarak adlandırırsam, örneğin create table one (atom int);.. select 'abc' abc, 1 def FROM one;- Karşılaştırılan bir performans cezası var mı SELECT .. FROM DUAL?


Ben düşünüyorum DB2 de yapamaz selectbir olmadan from. DB2, SYSIBM.SYSDUMMY1 adlı benzer bir kukla tabloya sahiptir . Ayrıca muhtemelen bunu zaten biliyorsunuzdur, ancak siz select 'A' from dual, dualtabloya gerçekten erişilmez , bu da düzenlemenizdeki soruyu cevaplar (yeni bir soru btw'yi hak eder).
Jack diyor ki topanswers.xyz

1
O mu değil "tüm" DBMS çalışır. Bir FROM olmadan bir SELECT öğesine izin vermeyen birkaç DBMS vardır. Kılavuz performansla ilgili sorunuza cevap veriyor: docs.oracle.com/cd/E11882_01/server.112/e26088/…
a_horse_with_no_name 12:03

3
@JackDouglas: Haklısın. DB2 bir FROMmadde gerektirir . Başımın üstünden: Informix, Firebird ve Apache Derby de gerektiriyor.
a_horse_with_no_name

1
DB2 bir FROM yan tümcesi gerektirir, ancak bir alternatif gibi bir ifade kullanmaktır values ('abc', 1). Elbette böyle bir ifade arasından seçim yapabilirsiniz:select abc from ( values ('abc',1) ) as t(abc,def)
Lennart

Yanıtlar:


30

Kesinlikle, evet, FROMbir SELECTifadenin cümlesi isteğe bağlı değildir. SQL-99 sözdizimi temel SELECTifadeyi detaylandırır ve FROMyan tümcesinde etrafında köşeli ayraç yoktur. Bu, standardın isteğe bağlı olmadığını düşündüğünü gösterir:

SELECT [ DISTINCT | ALL ]
{Column expression [ AS name ]} [ ,... ] | *
FROM <Table reference> [ {,<Table reference>} ... ]
[ WHERE search condition ]
[ GROUP BY Columns [ HAVING condition ] ]
[ORDER BY {col_name | expr | position} [ASC | DESC],...]                                     
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options |
 INTO DUMPFILE 'file_name' |
 INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]

Gerçek kullanımda, programcılar ve DBA'lar genellikle tablolardaki verileri veya tabloları ve veri yapılarını manipüle etmekten başka şeyler yapmayı yararlı bulurlar. Bu tür şeyler büyük ölçüde SQL standardının kapsamı dışındadır, bu da veri özellikleri ile ilgili belirli uygulamaların somun ve cıvatalarından daha fazladır. İster çalıştırmak ister isterse SELECT getdate()ya SELECT 1da SELECT DB_NAME()(ya da lehçeniz ne olursa olsun), aslında bir tablodan veri istemiyoruz.

Oracle, aşağıdaki etkili tanımlamaya sahip bir sahte tablo kullanarak standart ve uygulama tutarsızlığını çözmeyi seçer:

CREATE TABLE DUAL (
  DUMMY CHAR(1)
  )

INSERT INTO DUAL (DUMMY) VALUES ('X')

Diğer RDBMS'ler esas olarak FROM, belirtilmezse sahte bir tablonun kullanıldığını varsayar .

ÇİFT tablonun tarihçesi Wikipedia'da geçerli:

DUAL tablosu, Oracle şirketlerinden Charles Weiss tarafından dahili görünümlere katılmak için bir tablo sağlamak üzere oluşturuldu:

DUAL tablosunu, Oracle Data Dictionary'de temel alınan bir nesne olarak oluşturdum. Asla kendini görmek istemiyordu, bunun yerine sorgulanması beklenen bir görünüm içinde kullanılıyordu. Fikir, DUAL tablosuna BİRLEŞME yapabileceğiniz ve tablonuzdaki her satır için iki satır oluşturabileceğinizdi. Daha sonra GROUP BY kullanılarak sonuçta elde edilen birleşim, VERİ kapsamı ve INDEX kapsam (lar) ı için depolama miktarını göstermek üzere özetlenebilir. DUAL adı, sadece birinden bir çift satır oluşturma sürecine uygun görünüyordu.

Orijinal DUAL tablosunda iki satır (dolayısıyla adı) vardı, ancak daha sonra yalnızca bir satır vardı.


3
+1 ve dba.se'ye hoş geldiniz. Bu büyüleyici bir tarihle mükemmel bir cevaptır - umarım etrafta dolaşmaya ve daha fazla katkıda bulunmaya teşvik edilebilirsiniz :)
Jack diyor ki topanswers.xyz

4
Bir geliştirici, ikili bir kaç satır daha eklediğinde, saatler süren sonsuz eğlence benim tarafımdan oldu. Bol şey kırdı :) Suçlu izlemek için bir süre aldı!
Philᵀᴹ

8

dualOptimize edicinin anladığı avantaj, dualözel bir satır, bir sütun tablosu ( varchar2veri türüyle) - sorgularda kullandığınızda, planı geliştirirken bu bilgiyi kullanır.

Neden dualOracle'da seçim yapmamız gerekiyor ?

İsterseniz dualkendi tablolarınız arasından veya kendi tablolarınız arasından seçim yapabilirsiniz.

Benim için devam edeceğim dualçünkü var olduğunu biliyorum dual. En az 1 ve en fazla 1 sıra olduğunu biliyorum. Doktorun her şeyi bildiğini dualve benim için en verimli şeyi yaptığını biliyorum . Optimize edici dual, sihirli, özel 1 sıralı bir tablo olduğunu anlıyor . select *Orada durdu çünkü orada bir satır olacak. Yani tam da bu şekilde çalışıyor.


"En az 1 ve en fazla 1 sıra olduğunu biliyorum." DBA ayrıcalıklarına sahip bir sarsıntı (veya aptal) değişebilirDUAL . Dikkatli ol!
Nick Chammas

eğer bu sana olursa. Bu Kişiden OTURUM OLUŞTUR dışındaki tüm ayrıcalıkları iptal edin. ve eğer ikili yanlışlıkla biri tarafından düşürülürse?
DevYudh

oluşturmadan önce ikili tablo oluşturma (kukla varchar2 (1)) depolama alanı (ilk 1) veya flashback tablosu ikili kullanarak oluşturabilirsiniz
DevYudh 26:30 '

Peki, mevcut herhangi bir tablodan ifadeyi seçmeyle karşılaştırıldığında DUAL'i kullanmanın bir avantajı var, ancak PostgreSQL veya SQLServer'da olduğu gibi FROM'a sahip olmamaya alternatif olarak DUAL'e sahip olmanın avantajını açıklamıyor
Danubian Sailor

@Lukasz Lech #MSSQL Serv için FROM olmadan SELECT yoktur: SQL Server'da hiç Dual tabloya gerek yoktur. ancak kodunuzu oracle'tan SQL Serv'e aktardıysanız, bu komut dosyasını kullanarak ikili oluşturabilirsiniz. sql sunucusunda Dual tablo kullanma / oluşturma nedeni. ve ayrıca MSSQL Serv ve PostGRE SQL, Dummy tablosu gerektirmez
DevYudh

1

Diğer iki cevap cevabım için iyi bir arka plan sağlıyor.

Oracle veritabanlarında geleneksel ve güvenilirdir. DUALTablo olmayan diğer veritabanlarında başarısız olur . Kullanmanız gerekli değildir DUAL, ancak kullanmanızı tavsiye ederim.

Standartlarla uyumlu veritabanları, FROMen az Tablo referansını belirten bir madde gerektirir . SİPARİŞLER tablonuz varsa, FROM DUALyan tümce aşağıdaki yerine geçer :

FROM   orders
WHERE  rownum =1

Aralarından seçim yapabileceğiniz herhangi bir tabloyu veya görünümü değiştirin; Aralarından seçim yapamayacağınız bir tablo veya görünümü değiştirin; başarısız olur. DUALbir DBA'yı engellemesi nedeniyle daha güvenilirdir, tüm kullanıcılar ondan seçim yapabilir ve sonuç kümesinde yalnızca bir satır alır. (Zaman zaman kırılır.)

Tablo referansı içermeden bir tabloda olmayan verilere erişmek için standartlara uygun bir fiilin farkında değilim. Bu verilere ne kadar az eriştiğim göz önüne alındığında, böyle bir ihtiyaç görmüyorum. Karşılaştığım vakaların çoğu farklı şekillerde daha iyi ele alınabilir.


2
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)standart uyumlu olduğuna inanıyorum ve herhangi bir tabloya güvenmiyor.
Martin Smith

@MartinSmith Tablo başvurusunu kullanma yanıtımı güncelledim. Demek istediğim budur ve belirtmeliydim.
BillThor
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.