2015-01-31 3 views
0

로그인 페이지에서 작업하고 있습니다. 나는 사용자 이름 & 암호가 데이터베이스에 있는지 확인하고 싶습니다. 세 개의 데이터베이스 테이블이 있습니다 : 팀, 주최자, 사용자 이름이 각각 & 인 관리자, 각각 각 테이블의 비밀번호 필드. 3 계층 아키텍처에서 로그인을 구현 중입니다.사용자 이름/암호가 여러 테이블에 있는지 확인하십시오.

아래 SQL 문에 문제가 있다고 생각합니다. 고유 한/유효한 팀 사용자 이름과 팀 암호로 SQL 쿼리를 테스트했습니다. COUNT 쿼리가 두 개 이상의 행을 반환하는데 잘못되었습니다. 비즈니스 로직 계층 코드에 관해서는

public int getExistingAccount(string username, string password) 
    { 
     string queryStr = "SELECT COUNT(*) FROM Teams t,Organizers o,Admins a WHERE ([email protected] AND [email protected]) OR ([email protected] AND [email protected]) OR ([email protected] AND [email protected])"; 

     SqlConnection conn = new SqlConnection(_connStr); 
     SqlCommand cmd = new SqlCommand(queryStr, conn); 
     cmd.Parameters.AddWithValue("@username", username); 
     cmd.Parameters.AddWithValue("@password", password); 

     int returnValue = 0; 

     conn.Open(); 
     returnValue = (int)cmd.ExecuteScalar(); 

     conn.Close(); 
     return returnValue; 

    } 

:

이 데이터 액세스 계층에 대한 내 코드입니다

public string getAccount(string username, string password) 
    { 
     string returnMessage = ""; 

     if (username.Length == 0) 
      returnMessage += "Username cannot empty</br>"; 

     if (password.Length == 0) 
      returnMessage += "Password cannot be empty</br>"; 

     if (username.Equals(password)) 
     { 
      returnMessage += "Duplicate value. Please try again</br>"; 
     } 

     //Invoke validateInput() method to validate data 
     if (returnMessage.Length == 0) 
     { 
      int noOfRows = 0; 

      LogAccounts logInd = new LogAccounts(); 
      noOfRows = logInd.getExistingAccount(username, password); 

      if (noOfRows > 0) 
       returnMessage += "Account found"; 
      else 
       returnMessage += "Invalid username/password."; 
     } 

     return returnMessage; 
    } 
+0

count (*)를 *로 바꾸면 어떻게됩니까? 예상되는 행을 얻었습니까? – jarlh

+0

번호는 t에 팀의 이름 로 ( SELECT t.teamUsername에서 예상 행을 – Enovyne

+0

SELECT COUNT (*) 를 반환하지 않습니다 WHERE [email protected] 및 [email protected] UNION SELECT o.organizerUsername 조직 FROM 자명 같은 O WHERE 자명 로서 관리자 [email protected] FROM AND [email protected] 연합 SELECT a.adminUsername WHERE [email protected] AND a.adminPassword = @password ) –

답변

0

디자인이 정말 안좋아서 모든 사용자가 한 테이블에 있어야합니다. 그 후에 ID로 사용자를 데려 가고 싶다면 3 개의 diff 테이블을 점검해야합니다. 어쨌든 문제는 다음과 같이 작성해야합니다.

string queryStr = @" 
SELECT 
    COUNT(*) AS TeamsCount, 
    (SELECT COUNT(*) Organizers WHERE [email protected] AND [email protected]) AS OrgCount, 
    (SELECT Count(*) Admins WHERE [email protected] AND [email protected]) AS AdminCount 
FROM 
    Teams 
WHERE 
    [email protected] AND 
    [email protected]"; 

쿼리는 다음과 유사해야합니다. 그런 다음 DataSet에서이를 반환해야합니다.

DataSet dst = new DataSet(); 
using(SqlAdapter adapter = new SqlAdapter(cmd)) 
{ 
    adapter.Fill(dst); 
} 

이 경우 3 열의 dst가 표시됩니다. 기존 사용자가 다음과 같아야합니다 :

if(dst.Tables[0].Rows[0]["TeamsCount"] > 0 || 
    dst.Tables[0].Rows[0]["OrgCount"] > 0 || 
    dst.Tables[0].Rows[0]["AdminCount"] > 0) 
{ 
    //user already exist ! 
} 
1

은 당신이 단일 사용자를 가져 오는 것은 비정상적으로 큰/긴 SQL 쿼리를 필요로하는 정말 어색 데이터베이스 디자인을 가지고 보인다.

거의 모든 사용 사례에서 사용자 테이블이 하나 뿐이므로 추가 정보를 사용자에게 연결해야하는 경우 사용자 테이블에 대한 참조는 UserId입니다. 외래 키에 대해서도 읽어야합니다.

빠른 샘플 :

Users: 

- UserId (int or guid) (primary key) 

- .... (additional fields removed for brewity) 

다른 테이블이 UserId 열을 참조하고, 참여와 사용자에 대한 정보를 끌어 것을 사용합니다.

SELECT COUNT(*) FROM Users WHERE Username = xx AND Password = xx

주어진 사용자 이름/암호 조합을 일치하는 행 수를 지정하는 integer을 반환 :

예컨대 : SELECT T.*, U.* FROM Teams T INNER JOIN Users U ON U.UserId = T.UserId WHERE U.Username = "AwesomeCoach";

간단한 검증 쿼리는 다음과 같이 될 것이다. 1 또는 0이어야합니다. Username 열에 Unique 구속을 넣고 각각 Username의 발생이 하나만 존재하는지 확인하십시오.

각주 : 내가 직면 한 문제를 해결하는 해답을 얻었으나 일부 ​​데이터베이스 디자인을 읽고 가능한 한 간단하게 유지하도록 권장합니다. 여러 테이블에서 여러 사용자를 관리하는 것은 응용 프로그램이 성장함에 따라 번거로운 작업이 될 수 있습니다.

관련 문제