2009-11-19 38 views
3

前提的SQLite列的別名

我最近遇到了一個錯誤,在我的代碼select聲明。在意識到發生了什麼之後修復這個問題相當簡單,但我有興趣找到一種方法來確保類似的錯誤不會再發生。

下面是一個違規查詢的例子:

select 
    the, 
    quick, 
    brown 
    fox, 
    jumped, 
    over, 
    the, 
    lazy, 
    dog 
from table_name; 

我本來打算是:

select 
    the, 
    quick, 
    brown, 
    fox, 
    jumped, 
    over, 
    the, 
    lazy, 
    dog 
from table_name; 

對於那些誰看不出來,一個逗號brown後的前失蹤。這會導致該列被別名,因爲as關鍵字是而不是必需的。所以,你在結果得到的是:

the, 
    quick, 
    fox, 
    jumped, 
    over, 
    the, 
    lazy, 
    dog 

......在一個名爲fox列的brown所有值。這可以很容易地像上述(尤其是當每一列都有非常不同的值)短查詢注意到,但它想出了是一個相當複雜的查詢與大多整數列如下:

select 
    foo, 
    bar, 
    baz, 
    another_table.quux, 
    a1, 
    a2, 
    a3, 
    a4, 
    a5, 
    a6, 
    a7, 
    a8, 
    a9, 
    a10, 
    a11, 
    a12, 
    a13, 
    a14, 
    a15, 
    a16, 
    b1, 
    b2, 
    b3, 
    b7, 
    b8, 
    b9, 
    b10, 
    b11, 
    b12, 
    b13, 
    b14, 
    b18, 
    b19, 
    b20, 
    b21, 
    c1, 
    c2, 
    c3, 
    c4, 
    c5, 
    c6, 
    c7, 
    c8 
from table_name 
join another_table on table_name.foo_id = another_table.id 
where 
    blah = 'blargh' 
-- many other things here 
; 

即使具有更好的列名稱,這些值都非常相似。如果我在b11(例如)之後錯過逗號,然後所有b11值被調用b12,那麼當我們通過處理管道(取決於結果中的這些列名稱)運行數據時非常不幸。通常情況下,我會做select * from table_name,但我們需要的是要求我們選擇一點。

問題

我正在尋找的是一個戰略,以再次阻止這種情況發生。

有沒有辦法在別名列時需要as?或者寫一些東西讓它出錯? (例如,在C的語言,我開始寫1 == foo代替foo == 1引起編譯錯誤時我意外地留出一個等號,使其成爲無效1 = foo代替foo = 1。)

我使用vim通常,所以我可以使用hlsearch突出顯示逗號,以便我可以看到它。但是,我必須經常在其他環境中編寫查詢,其中包括一個專有接口,在這個接口中我無法輕鬆完成這樣的事情。

感謝您的幫助!

回答

6

我以前做過的一件事是將逗號移動到行的開頭。這可以帶來一些好處。首先,您可以立即查看是否缺少逗號。其次,您可以在最後添加一個新列,而無需修改以前的最後一行。

缺少:

select 
    the 
, quick 
, brown 
    fox 
, jumped 
, over 
, the 
, lazy 
, dog 
from table_name; 

不缺:

select 
    the 
, quick 
, brown 
, fox 
, jumped 
, over 
, the 
, lazy 
, dog 
from table_name; 
+0

我打算在我的問題中寫下這個,實際上 - 但我想我會留下來看看人們是否有更好的建議。 任何方式允許它在'the'之前?或者那只是一個可以與之共存的東西? – 2009-11-19 16:56:51

+0

某些東西在收集的一端或另一端會有所不同。如果你急於在選擇之後立即使用逗號,那麼你可以在選擇之後移動「the」,或者選擇一個虛擬常量,比如「select 1」。 – scwagner 2009-11-19 16:59:41

+0

這一切都很好 - 我錯過了一個逗號。我希望有一種總是有尾隨逗號的方式,就像在Python或Ruby中一樣。 (你可以寫[1,2,3,4],然後這個問題就會消失,當你只想對第二個問題發表評論時,這是個好主意。) – 2009-11-19 17:03:25

0

名稱

first 
,short 
,medium 
,longlonglong 
,... 

VS

first, 
short, 
medium, 
longlonglong, 
... 

也使得它可以很容易看到SQL的列表中選擇參數之前寫一個逗號

作品在任何IDE :)

-1

如果您有名稱相似的列,只能通過後綴數字進行區分, ady輸了。你有一個不好的數據庫設計。

現在大多數開發人員使用SQL生成器或ORM,而不是編寫這種「彙編語言」SQL。

+1

這件事情我來到的,不是我設計的所有權。絕對是我想改變的東西。 – 2009-11-19 16:54:17

+0

關於第二條評論,我通常使用ORM層。但是,仍然有很多複雜的情況,在這種情況下,編寫一個succint'select'查詢會勝過ORM。 – 2009-11-19 16:58:47

+0

我不是在責怪你。如果你還沒有擁有它,我只是給你方向。 :) – 2009-11-21 02:24:55

1

你可以在一個功能包的SQL調用,要麼:

  1. 遍歷結果集中的列,檢查包含空格的列名稱

  • 同時接受SQL語句和列的整數預計數量,然後檢查結果集,以確保列數相匹配你的原意。
  • 1

    我有和你一樣的問題。我已經使用make和perl腳本來做一個「lint」,就像查看我的代碼很長一段時間一樣。它有助於防止這樣的一些錯誤。 在生成文件中,我有:

    lint_code: 
        perl lint_code.pl <file_1.php 
    

    Perl的文件是:

    $st = 0; 
    $line_no = 0; 
    while (<>) 
    { 
        $line_no++; 
        $st = 1 if (/start-sql/); 
        $st = 0 if (/end-sql/); 
        $st = 2 if ($st == 1 && /select/); 
        $st = 3 if ($st == 2 && /from/); 
        if ($st == 2 && /^[ \t]+[a-zA-Z][a-zA-Z0-9]*[ \t*]$/) 
        { 
         if (! /select/) 
         { 
         printf ("Possible Error: Line: $line_no\n"); 
         } 
        } 
    } 
    

    我環繞我的意見select語句//啓動SQL和//最終SQL。我希望這有幫助。 我已更改正則表達式以反映您如何格式化SQL,因爲我一直在使用不同格式(使用前面的逗號)的 。

    作爲我的構建/測試過程的一部分,我對代碼運行一組檢查。這是一個不到 完美的解決方案,但它幫助了我。

    (我有與計算器富文本編輯器改變了我的代碼有點困難。 希望我將學習如何正確使用它。)

    +0

    感謝分享。我不確定多久我能夠將其納入我的工作流程,但是我非常感謝。出於好奇,你如何格式化你的SQL語句?我嘗試寫我的,所以我可以輕鬆地移動塊,但仍然可讀。 – 2009-11-19 17:08:39