2014-07-15 103 views
1

我試着去定義一個當局按用戶名查詢:春季安全SQL查詢返回的數據太多

SELECT u.username, r.authrole FROM users u, roles r, user_role ur 
        WHERE u.id = ur.userid AND u.username = 'dit' 

它的尷尬,但此查詢將返回錯誤的結果,我不能修復它。

結果:

username  authrole 
----------------------- 
    dit  ROLE_ADMIN 
    dit  ROLE_USER 

這裏是我的表:

用戶:

id username password 
--------------------------------- 
    1  admin  ***** 
    2  dit  ***** 

USER_ROLE:

userid roleid 
--------------------- 
    1  1 
    2  2 

角色:

id  authrole 
--------------------- 
    1  ROLE_ADMIN 
    2  ROLE_USER 

UPDATE:我把這個壞查詢從這個example on github

+0

是「結果」您預期的結果之一的比賽? –

+1

'FROM users u JOIN user_role ur ON u.id = ur.userid JOIN role r ON r.id = ur.roleid WHERE u.username ='dit'' - 使用真正的連接而不是隱含的交叉連接,這是尤其重要的如果你不知道如何檢查你的連接是否正確。 – scragar

回答

3

使用此(注:內關鍵字是可選的):

SELECT u.username 
     ,r.authrole 
    FROM users u 
    INNER JOIN user_role ur 
    ON u.id = ur.userid 
    INNER JOIN roles r 
    ON r.id = ur.roleid 
    WHERE u.username = 'dit' 

問題是因爲你在角色表中沒有給出如何參與表的任何條件。結果將是笛卡爾產品,其中顯示正在連接的表格之間的所有可能組合。

然後加入WHERE子句中,使用JOIN語法更好(更清晰)。另外,更重要的是,使用JOIN語法會創建一個關注點分離。將您正在使用的字段放入where子句中可能會導致理解查詢困難。

基本上有四種不同類型的連接:

  • INNER JOIN:當有兩個表

  • LEFT JOIN中至少有一個匹配返回的所有行:從左邊返回所有行表格和右表匹配的行

  • 右連接:返回右表中的所有行以及左表中的匹配行

  • FULL JOIN:返回所有行的時候沒有在表中

+0

關於連接的信息是正確的,但請正確分解它們。您有三種主要的外連接類型:left,right和full,對於在連接的相關側不存在的條目返回null,以及三種類型的inner join,natural(基於具有相同名稱的列的匹配,不要相信它),inner(有on子句)和cross(沒有on子句,導致笛卡爾積)。 – scragar