我正在尝试自学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())
这是我到目前为止所做的。
答案 0 :(得分:2)
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
答案 1 :(得分:1)
要检查是否存在,请执行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上设置一个唯一索引,以使数据库拒绝已插入数据库中的网址,但您仍应在插入之前进行检查。
如果调用者想知道是否插入了行,则返回@count
值。如果它为0则插入线,否则不插入。我不知道从SP返回值的“不良做法”。但是,由于SP没有结果,您需要使用out参数。
答案 2 :(得分:0)
如果您只执行一个这样的SQL语句插入,您可以使用paratemerized查询,即我假设您使用的是.NET。
如果您想返回值,我建议您使用FUNCTION而不是STORED PROCEDURE。您可以从函数返回表或任何您想要的内容。
但是有一些限制。您可以更深入地了解差异,以了解何时使用。这是一个可以帮助您入门的链接:
Function vs. Stored Procedure in SQL Server
如果你想要使用存储过程,你可以返回单行,单列结果集,使用SELECT,或只使用输出参数。
如果您想根据列是否存在而执行操作,我建议您查看MERGE语句。这样您只能对数据库执行一次查询而不是两次或多次(执行SELECT然后INSERT)。
还有其他方法可以在数据库中使用数据库访问,例如各种ORM,这将使您的生活更轻松,例如LINQ-to-SQL等。有很多可能性。您需要确定在特定情况下哪种方式最佳。