减少向三个表发送信息所需的 SqlCommand 数量

Reduce the number of SqlCommands required to send information to three tables

我有以下代码:

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 是否正确。然后(应该)return Row ID.

如果 RowID > 0 那么我们有一个有效的登录。

下一个 SQLCommand 更新同一个 table 中的 IsOnline 状态 下一个 SQLCommand 将用户 ID 和日期时间插入到 LogonHistory 中。现在用 Row Id 设置 id 最后执行 SQLCommand 以将我们从上一条命令获得的 RowIdUser's Id 插入到 UserLogOnHistory 中。 (这使我们能够快速查找)- 理论上用于更新该用户注销时的 LogonHistory。

我现在意识到这是一团糟!

所以问题:

  1. 如何获取受最后一条命令影响的 table 的 RowId。
  2. 我如何优化查询以减少执行的 SQLCommands 的数量 - 或者这是否合理。

您可以通过简单地在一批中发出多个 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);

请注意,您还可以使用 LogonHistory 上的 INSERT 触发器或通过 OUTPUT.

来完成最后几位

此处往返次数:1次

如果是我,我会把所有的逻辑都放在一个存储过程中,这样更容易测试并且可以更好地解耦。

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:请考虑各位同事的隐私,散列他们的密码。