【问题标题】:Conditionally inserting from a stored procedure从存储过程有条件地插入
【发布时间】:2011-12-05 21:11:39
【问题描述】:

我正在尝试自学 SQL。我有一个正在处理的 Web 矩阵项目,用于编辑和显示由 SQL 服务器数据库支持的帖子。一位工作同事建议我使用存储过程来提交帖子,而不是编写内联 sql。

到目前为止,该过程看起来还不错,但我想检查 url slug 是否已经存在,如果存在则返回一些内容来说明(url slug 应该是唯一的)。我正在努力在插入之前如何检查。我还读到从存储过程返回是不好的做法,但我认为返回一些东西让调用者知道插入没有继续是个好主意。

非常感谢任何帮助。

 -- =============================================
 -- Author:     Dean McDonnell
 -- Create date: 05/12/2011
 -- Description:    Commits an article to the database.
 -- =============================================

 CREATE PROCEDURE CommitPost

 @UrlSlug VARCHAR(100),
 @Heading VARCHAR(100),
 @SubHeading VARCHAR(300),
 @Body VARCHAR(MAX)

 AS

 INSERT INTO Posts(UrlSlug, Heading, SubHeading, Body, Timestamp)

 VALUES(@UrlSlug, @Heading, @SubHeading, @Body, GETDATE())

这是我目前所拥有的。

【问题讨论】:

    标签: stored-procedures sql-server-2008-r2


    【解决方案1】:
     CREATE PROCEDURE CommitPost
    
     @UrlSlug VARCHAR(100),
     @Heading VARCHAR(100),
     @SubHeading VARCHAR(300),
     @Body VARCHAR(MAX)
    
     AS
    IF NOT EXISTS (SELECT * FROM Posts WHERE UrlSlug = @UrlSlug)
    
     INSERT INTO Posts(UrlSlug, Heading, SubHeading, Body, Timestamp)
     VALUES(@UrlSlug, @Heading, @SubHeading, @Body, GETDATE())
    SELECT @@ROWCOUNT
    

    【讨论】:

    • 调用 RAISERROR 而不是让他们检查行数怎么样?
    【解决方案2】:

    要检查是否存在,请像这样执行SELECT COUNT

    CREATE PROCEDURE CommitPost
    
     @UrlSlug VARCHAR(100),
     @Heading VARCHAR(100),
     @SubHeading VARCHAR(300),
     @Body VARCHAR(MAX)
    
     AS
    
     DECLARE @count INT
    
     SELECT @count = COUNT(*) FROM  Posts WHERE UrlSlug = @UrlSlug
    
     IF @count = 0 THEN
     BEGIN
    
       INSERT INTO Posts(UrlSlug, Heading, SubHeading, Body, Timestamp)
       VALUES(@UrlSlug, @Heading, @SubHeading, @Body, GETDATE())
     END
    

    您可以在 UrlSlug 上设置唯一索引,以使数据库拒绝插入已在数据库中的 url,但您应该在插入之前检查。

    如果您的调用者想知道该行是否已插入,请返回 @count 值。如果为 0,则插入该行,否则不插入。我不知道关于从 SP 返回值的“坏习惯”。但是,由于 SP 没有结果,因此您需要使用 out 参数。

    【讨论】:

      【解决方案3】:

      如果您只执行一个类似插入的 SQL 语句,您可以只使用参数化查询,即我假设您使用的是 .NET。

      如果您想返回值,我建议您使用 FUNCTION 而不是 STORED PROCEDURE。您可以从函数中返回表格或任何您想要的内容。

      虽然有一些限制。您可以更深入地挖掘差异以查看何时使用什么。这是一个可以帮助您入门的链接:

      Function vs. Stored Procedure in SQL Server

      如果您仍然想使用存储过程,您可以使用 SELECT 返回单行单列结果集,或者只使用输出参数。

      如果您想根据列是否存在来执行操作,我建议您查看MERGE 语句。这样您只需对数据库执行一个查询,而不是两个或更多(执行 SELECT 然后插入)。

      还有其他方法可以使用数据库访问,例如代码中数据库顶部的各种 ORM,这将使您的生活更轻松,例如 LINQ-to-SQL 等。那里有很多可能性。您需要确定在特定情况下什么是最好的。

      【讨论】:

        猜你喜欢
        • 2020-09-11
        • 1970-01-01
        • 1970-01-01
        • 2018-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多