2015-02-07 50 views
1

我有以下代碼:減少發送信息所需SqlCommands的數量,三個表

command = new SqlCommand("SELECT UserId from Users WHERE Username = N'" + userName + " AND " + userPassword + "= N'" + userPassword + "AND AccountStatus = 0"); 
      command.CommandType = System.Data.CommandType.Text; 
      command.Connection = conn; 
      int uid = (int)command.ExecuteScalar(); 
      if(uid > 0) 
      {    
       command = new SqlCommand("UPDATE IsOnline =" + true + " WHERE UserId = 'N" + uid); 
       command.ExecuteNonQuery(); 
       command = new SqlCommand("INSERT INTO LogonHistory OUTPUT LogonHistoryId VALUES(NULL," + uid + "," + DateTime.Now + ")"); 
       int id = (int) command.ExecuteNonQuery(); 
       command = new SqlCommand("INSERT INTO UsersLogOnHistory VALUES(NULL," + uid + "," + id + ")"); 
       command.ExecuteNonQuery(); 
       IsAuthorised = true; 
       SendMessage(ID, ServerCommands.Success, IsAuthorised.ToString()); 
      } 
      else 
      { 
       // User does not exist 
       SendMessage(ID, ServerCommands.Failed, IsAuthorised.ToString()); 
      } 

第一SqlCommand的執行檢查,看是否Usernamepassword是正確的,如果他們的account is not suspended。它然後(應該)返回Row ID.

如果RowID > 0那麼我們有一個有效的登錄。

下一個SQLCommand更新同一表中的IsOnline狀態 下一個SQLCommand將用戶標識和日期時間插入到LogonHistory中。現在設置idRow Id 最後的SqlCommand執行插入我們從最後的命令得到了RowIdUser's IdUserLogOnHistory。 (這使我們能夠快速查找)理論上來說,用於在此用戶註銷時更新LogonHistory。

我現在意識到這是一團糟!

所以對這些問題:

  1. 我如何獲得受上一命令表的ROWID。
  2. 如何優化查詢以減少執行的SQLCommands的數量 - 或者看起來是否合理?
+0

[SQL注入警報](http://msdn.microsoft.com/en-us/library/ms161953%28v=sql.105%29.aspx) - 您應該**不**將您的SQL語句連接在一起 - 使用**參數化查詢**來代替以避免SQL注入 – 2015-02-08 09:14:47

+0

我瞭解SQL注入 - 但由於這是一個私有API,並且公衆不能訪問另一個內部應用程序,所以這不是必需的。沒有人能夠注入。但我仍然應該使用參數,因爲這是良好的做法 – 2015-02-08 10:28:13

回答

3

您可以通過簡單的... 包括多個TSQL命令在一個批處理中發出多個TSQL命令。要徹底,你應該用;,但在大多數(不是全部)的情況下,這是可選的,它將無法工作。

獲取最近插入的標識值; SCOPE_IDENTITY()。這僅適用於INSERT,並且只有IDENTITY列。在所有其他情況下:OUTPUT

注意;你應該參數,但考慮:

UPDATE IsOnline = 1 WHERE UserId = @uid; 
DECLARE @lhid int 
INSERT INTO LogonHistory (explict columns here) 
VALUES(NULL,@uid, GETUTCDATE()); 
SET @lhid = SCOPE_IDENTITY(); 
INSERT INTO UsersLogOnHistory (explicit columns here) 
VALUES(NULL,@uid, @lhid); 

注意,你也可以用INSERT觸發做LogonHistory最後位,或通過OUTPUT

往返這裏的數量:1

+0

我不知道如何使用您顯示的代碼。 – 2015-02-08 10:29:06

+1

@DaveGordon顯示的TSQL出現在'SqlCommand'中;那麼只需'cmd.Parameters.AddWithValue(「@ uid」,uid);'等等 – 2015-02-08 18:23:49

0

如果是我,我會把所有的邏輯在存儲過程中,它更容易測試,並實現更好的去耦。

CREATE PROC logon 
     @username   NVARCHAR(MAX) 
    , @password   NVARCHAR(MAX) 
    , @IsAuthorized  BIT OUTPUT 
AS 
BEGIN 
    SELECT @UID = UserId 
    FROM Users 
    WHERE Username    = @username 
     AND userPasswordHash = CHECKSUM(@password); 

    UPDATE Users 
    SET IsOnline = 1 
    WHERE UserId = @UID; 

    INSERT INTO LogonHistory 
    VALUES(NULL,@UID,GETDATE()); 

    INSERT INTO UsersLogOnHistory 
    VALUES(NULL,@UID,SCOPE_IDENTITY()); 

    IF @UID IS NOT NULL 
     SET @IsAuthorized = 1; 
    ELSE 
     SET @IsAuthorized = 0; 
END; 

PS:請爲你的同事考慮你的隱私和哈希密碼。

相關問題