如何设计方法的返回类型和存储过程的返回值
本文关键字:返回类型 存储过程 返回值 方法 | 更新日期: 2023-09-27 18:30:54
让我们以基本场景为例,即只有在数据库中不存在用户名的情况下,我才想在用户注册期间插入记录。
我的问题是,您会创建 2 个单独的存储过程并对数据库进行 2 次调用,一次用于检查用户名是否存在,第二次用于实际插入数据库,还是创建一个存储过程并仅在其中编写两个查询?
如果您创建了一个存储过程,那么我的第二个问题实际上应该从存储过程返回什么?我通常从存储过程中返回硬编码的数字,然后检查内部代码。这是一个好的做法吗?
此操作最终需要是"原子的"操作 - 检查无法与实际创建分离,否则可能会遇到并发问题。虽然您可以通过事务处理和跨两个或多个 SP 锁定来处理其中的一些问题,但恕我直言,最好的方法是使用一个 SP,并在插入发生时同时(在同一语句中)执行检查。
我会返回一个包含插入用户的完整记录的记录集,如果存在名称冲突,我会引发错误。
我将执行一个存储过程,该过程将返回新插入用户的 ID,如果未发生插入,则返回 -1
你可以做这样的事情:
CREATE PROCEDURE AddNewUser
(
@Username VARCHAR(30)
, @Password VARCHAR(30)
, @UserExists BIT OUTPUT
)
AS
-- CHECK IF THE USER EXISTS:
DECLARE @RowCount INT
SELECT @RowCount = COUNT(*)
FROM Users
WHERE Username = @Username
IF (@RowCount > 0)
BEGIN
SET @UserExists = 1
END
ELSE
BEGIN
SET @UserExists = 0
INSERT INTO Users
(Username, [Password])
VALUES
(@Username, @Password)
END
GO
然后在应用程序中,您可以使用 @UserExists 参数,1 表示用户已存在,0 表示用户不存在且已创建。
为了便于使用,您应该使用存储过程而不是内联 SQL,因为您将容易受到 SQL 注入攻击。
MERGE
语句可能会有所帮助。假设MERGE
是有条件的INSERT
/UPDATE
.在单个语句中,如果新用户不存在,您可以INSERT
新用户,如果存在,则只需UPDATE
它。
正如其他人所写的:存储过程比动态SQL好得多。将MERGE
包装成CREATE PROCEDURE
。
在现实世界中,您的应用程序/Web应用程序中的用户交互/工作流程会告诉您是否需要一个或两个过程。
场景 A)
- 给我你的用户数据
- 我将为您创建一个帐户或只是更新它(一个存储过程)
在场景 A 中,对条件INSERT
/UPDATE
执行MERGE
。
场景 B)
- 给我你的用户数据,并决定你是要唱歌还是只是登录
- (您要注册) - 检查给定的登录是否免费(第一个存储过程或只是查询)
- (它是免费的;注册!- 创建一个帐户,但必须再次检查登录是否仍然免费(第二个步骤)
在场景 B 中,您可以检查登录是否存在,然后在TRY .. CATCH
块中执行INSERT
或(最好)执行INSERT
。您可以使用有用的消息/状态CATCH
块中执行RAISERROR
- 因此您可以通过从 SQL 中抛出"异常"(而不是返回参数)并在应用程序代码中捕获它来报告创建帐户的问题。此逻辑在编码中可能更有用。