2012-06-06 40 views
4

我想,必須有一個具體的設計原因,你可以不寫類似以下的查詢:爲什麼在SQL中動態選擇列和表名非常困難?

select 
    (select column_name 
    from information_schema 
    where column_name not like '%rate%' 
    and table_name = 'Fixed_Income') 
from Fixed_Income 

,而是不得不求助於動態SQL。

任何人都知道是什麼原因?我嘗試了谷歌搜索,但所有的點擊都呼籲幫助解決這個問題 - 這意味着這是一個非常普遍的需求,並沒有很好的理解。

+0

你在說什麼數據庫?'column_name'和'table_name'是什麼類型? – Oded

+0

這是一個通用的SQL設計問題。我不認爲任何數據庫都允許這樣做。 – SQLCurious

+0

在您的示例中,您通過說「我想要除%rate%以外的所有內容」來使其變爲動態。就像@usr所說的那樣,通過靜態的sql引擎是不可能的,爲此你必須使用適當的工具,即動態執行工具。 – Sebas

回答

1

你問了一個非常有趣的問題。

「關係代數」中的「關係」是指名稱 - 值對,而不是表之間的關係。在關係代數中,並不要求集合(表)中的所有記錄具有相同的列。

我最好的猜測是這個限制與實體關係圖的思想有關。數據庫圍繞表設計,並且這些表彼此具有關係。關於數據存儲和訪問的關係數據庫的選擇具體是什麼時候可以以這種方式存儲數據。瞭解實體及其屬性表明了數據的靜態形式,並因此提供了查詢中的靜態引用。

另外,作爲語言的SQL是聲明式語言而不是過程式語言。這表明 - 但不強加 - 與查詢運行分開的編譯步驟。通常,SQL引擎會執行以下操作(處於非常高的級別):

  1. 將查詢編譯爲某種數據流過程。
  2. 優化數據流程。 (通常是編譯過程的一部分。)
  3. 運行查詢。

前兩個結果是所謂的「查詢計劃」。儘管如此,除非您知道正在操作的對象,否則您實際上無法進行優化。因此,動態選擇表格和列意味着優化將成爲運行查詢的一部分而不是編譯它。

最後,像SQL Server這樣的一些數據庫支持動態SQL。這使您可以構建可以同時編譯和運行的字符串。這對於複雜的決策支持查詢非常有用。當您需要快速的事務處理吞吐量時,不推薦使用它,因爲編譯的開銷相對於查詢而言過高。

+0

我想我明白了。糾正我,如果我錯了,但它就像試圖編寫代碼打印所有名稱以'rate'開頭的變量。 – SQLCurious

6

原因是查詢優化器需要知道在編譯時引用的確切模式對象。它需要他們來優化查詢。如果沒有查詢優化器提供這些信息,你不會相信RDBMS會有多慢。

這有點像在實踐中靜態和動態類型的性能差異:通常有一個不平凡的區別(我在這裏只考慮主流語言)。編譯器可以利用靜態信息來生成優秀的代碼。

即使此功能存在,它也會通過首先計算表和列名稱,然後執行標準的「靜態」查詢計劃來實現。

+2

數據庫沒有針對開發人員的便利進行優化(實際上,這樣的事情可以節省不到5分鐘的工作量),但是對於查詢的性能而言。我做了30年的數據庫工作,從來沒有需要或想做這樣的事情。 – HLGEM

+0

我能想到一個假設的原因:一種「特設」查詢,可以讓最終用戶即時創建報表。例如,從列表中選擇要包括在最多可以有8列的報告上。但無論如何,這種任務最好由報告生成器處理。 – user158017

+0

如果沒有袋鼠,人類就不會知道它們沒有袋裝袋;)只是說我同意你的看法,但是,也許如果我們有這樣的工具,我們會用它來提出新的算法......誰知道。 – Sebas