减少向三个表发送信息所需的 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 检查 Username
和 password
是否正确以及它们的 account is not suspended
是否正确。然后(应该)return Row ID.
如果 RowID > 0
那么我们有一个有效的登录。
下一个 SQLCommand 更新同一个 table 中的 IsOnline
状态
下一个 SQLCommand 将用户 ID 和日期时间插入到 LogonHistory 中。现在用 Row Id
设置 id
最后执行 SQLCommand 以将我们从上一条命令获得的 RowId
和 User's Id
插入到 UserLogOnHistory
中。 (这使我们能够快速查找)- 理论上用于更新该用户注销时的 LogonHistory。
我现在意识到这是一团糟!
所以问题:
- 如何获取受最后一条命令影响的 table 的 RowId。
- 我如何优化查询以减少执行的 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:请考虑各位同事的隐私,散列他们的密码。
我有以下代码:
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 检查 Username
和 password
是否正确以及它们的 account is not suspended
是否正确。然后(应该)return Row ID.
如果 RowID > 0
那么我们有一个有效的登录。
下一个 SQLCommand 更新同一个 table 中的 IsOnline
状态
下一个 SQLCommand 将用户 ID 和日期时间插入到 LogonHistory 中。现在用 Row Id
设置 id
最后执行 SQLCommand 以将我们从上一条命令获得的 RowId
和 User's Id
插入到 UserLogOnHistory
中。 (这使我们能够快速查找)- 理论上用于更新该用户注销时的 LogonHistory。
我现在意识到这是一团糟!
所以问题:
- 如何获取受最后一条命令影响的 table 的 RowId。
- 我如何优化查询以减少执行的 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:请考虑各位同事的隐私,散列他们的密码。