1

让我们以基本场景为例,只有在数据库中不存在用户名的情况下,我才想在用户注册期间插入一条记录。

我的问题是,您将创建 2 个单独的存储过程并对数据库进行 2 次调用,一次检查用户名是否存在,第二次调用实际插入数据库,还是创建一个存储过程并在其中编写两个查询?

如果您创建一个存储过程,那么我的第二个问题应该从存储过程中实际返回什么?我通常从存储过程中返回硬编码数字,然后检查内部代码。这是一个好习惯吗?

4

4 回答 4

4

此操作最终需要是“原子的” - 检查不能与实际创建分离,否则您可能会遇到并发问题。虽然您可以通过两个或多个 SP 的事务和锁定来处理其中的一些问题,但恕我直言,最好的方法是使用一个 SP 并在插入发生的同时(在同一条语句中)执行检查。

我将返回一个包含插入用户的完整记录的记录集,如果存在名称冲突,则会引发错误。

于 2012-04-13T08:38:00.520 回答
3

我将执行一个存储过程,该过程将返回新插入用户的 ID,如果没有插入则返回 -1

于 2012-04-13T08:30:30.540 回答
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 注入攻击。

于 2012-04-13T08:47:02.163 回答
0

MERGE声明可能会有所帮助。假设MERGE是有条件的INSERT/ UPDATE。在单个语句中,INSERT如果它不存在,您可以新用户,或者UPDATE如果存在,您可以新用户。

正如其他人所写:存储过程比动态SQL要好得多。裹MERGECREATE PROCEDURE.

在现实世界中,您的应用程序/网络应用程序中的用户交互/工作流程会告诉您是否需要一两个程序。

情景一)

  • 给我你的用户数据
  • 我将为您创建一个帐户或只是更新它(一个存储过程)

在场景 A 中,MERGE为条件INSERT/做UPDATE

场景 B)

  • 给我你的用户数据,然后决定你是想唱歌还是只登录
  • (你想注册) - 检查给定的登录是否是免费的(第一个存储过程或只是查询)
  • (它是免费的;注册!) - 创建一个帐户,但必须再次检查登录是否仍然免费(第二个存储过程)

在场景 B 中,您可以检查登录是否存在,然后在块中执行INSERT或(更好)执行。您可以在块中使用有用的消息/状态 - 因此您可以通过从 SQL 中抛出“异常”(而不是返回参数)并在应用程序代码中捕获它来报告创建帐户的问题。这种逻辑在编码中可能更有用。INSERTTRY .. CATCHRAISERRORCATCH

于 2012-04-13T09:40:27.413 回答