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

时间:2012-04-13 08:28:13

标签: c# asp.net .net sql-server tsql

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

答案 2 :(得分: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注入攻击。

答案 3 :(得分:0)

MERGE声明可能会有所帮助。我们说MERGE是有条件的INSERT / UPDATE。在单一语句中,如果新用户不存在,则可以INSERT新用户,如果存在则只有UPDATE

正如其他人所写:存储过程比动态SQL好得多。将MERGE换行到CREATE PROCEDURE

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

情景A)

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

在方案A中,对条件MERGE / INSERT执行UPDATE

情景B)

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

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