如何设计方法的返回类型和存储过程的返回值

本文关键字:返回类型 存储过程 返回值 方法 | 更新日期: 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 中抛出"异常"(而不是返回参数)并在应用程序代码中捕获它来报告创建帐户的问题。此逻辑在编码中可能更有用。