这是我的sp
CREATE PROCEDURE DeteleTitle
(
@TitleID int
)
AS
BEGIN
IF EXISTS(Select TitleID from Titles WHERE TitleID=@TitleID)
BEGIN
DELETE FROM Titles WHERE TitleID=@TitleID
SELECT @TitleID
END
ELSE
BEGIN
SELECT 0
END
END
我称之为的方法是: -
public Int32 DeleteTitle(Int32 TitleID)
{
try
{
int ds=0;
SqlParameter[] sqlparam=new SqlParameter[1];
sqlparam[0]=(@TitleID,TitleID);
ds=Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["con"].ConnectionString,CommandType.StoredProcedure,"DeleteTitle",sqlparam).Tables[0]);
return ds;
}
catch(Exception ex)
{
return 0;
}
}
现在TitleID是许多表中的外键。如果某些Table的记录使用的是TitleID,那么它会抛出这个异常,说“外键违规n东西”。在我上面的存储过程中,我在else块中选择零,以防删除不成功。当删除成功时,它返回TitleID的值,如50,99或其他。现在发生的事情是,当删除不成功时,它不会返回零。我希望根据Delete Stored过程返回的零值在屏幕上显示一条消息,但是当它没有返回任何值时(当删除失败时),我在DeleteTitle()方法的catch块中返回零。
现在我有两个问题: -
答案 0 :(得分:3)
您需要在程序中使用TRY...CATCH,而不是IF ... ELSE。
如果您考虑一下,当DELETE因外键违规而失败时,您已经在语句的IF部分。您的代码怎么可能跳转到ELSE块?
答案 1 :(得分:3)
问题是如果if语句因异常而失败,那么它将不会执行ELSE语句。您的IF语句也显示不正确 - 不应该是IF EXISTS,[然后删除记录?]现在写的方式,如果记录存在则不会被删除。
扩展的问题是,依赖异常(使用C#,SQL或任何其他语言)作为流控制的方法被认为是不好的做法。
通过对每个相关表使用EXISTS语句,最好显式检查相关记录。
答案 2 :(得分:2)
如果Tables
是表的集合,则第一个表的第一列需要另一个[0]
。
答案 3 :(得分:2)
使用它:
CREATE PROCEDURE DeteleTitle
(
@TitleID int
)
AS
BEGIN TRY
DELETE FROM Titles WHERE TitleID=@TitleID
SELECT CASE
WHEN @@ROWCOUNT>0 THEN @TitleID
ELSE 0 --row did not exist
END
END TRY
BEGIN CATCH
SELECT 0 --delete failed
END CATCH
go
当多个表通过外键“链接”并删除父行时,会出现类似于报告的错误,因为子数据在没有父项的情况下不能存在。您可能希望查看级联删除,或在此过程中添加代码以从通过外键与标题关联的表中删除。在DELETE FROM Titles
之前添加这些删除。这样做:
CREATE PROCEDURE DeteleTitle
(
@TitleID int
)
AS
BEGIN TRY
BEGIN TRANSACTION
DELETE FROM YourOtherTablesA WHERE TitleID=@TitleID
DELETE FROM YourOtherTablesB WHERE TitleID=@TitleID
DELETE FROM Titles WHERE TitleID=@TitleID
SELECT CASE
WHEN @@ROWCOUNT>0 THEN @TitleID
ELSE 0 --row did not exist
END
COMMIT
END TRY
BEGIN CATCH
IF XACT_STATE()!=0
BEGIN
ROLLBACK TRANSACTION
END
SELECT 0 --delete failed
END CATCH
go
答案 4 :(得分:0)
您可以使用@@ ERROR作为输出结果。 @@ ERROR = 0表示其他成功的操作失败
CREATE PROCEDURE DeteleTitle
(
@TitleID int
)
AS
BEGIN
IF EXISTS(Select TitleID from Titles WHERE TitleID=@TitleID)
BEGIN
DELETE FROM Titles WHERE TitleID=@TitleID
END
Select @@ERROR
END