C# 存储过程赢得';t返回0
这是我的spC# 存储过程赢得';t返回0,c#,asp.net,sql-server,stored-procedures,C#,Asp.net,Sql Server,Stored Procedures,这是我的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 Delet
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在许多表中都是外键。如果某个表的记录使用了TitleID,那么它会抛出这个异常,表示“外键冲突n stuff”。在上面的存储过程中,如果删除不成功,我将在else块中选择零。当delete成功时,它返回TitleID的值,比如50、99或其他值。现在发生的是,当删除不成功时,它不会返回零。我希望根据Delete存储过程返回的这个零值在屏幕上显示一条消息,但当它没有返回任何值时(当Delete失败时),我在DeleteTitle()方法的catch块中返回了零
现在我有两个问题:-
仔细想想,当删除失败并违反外键时,您已经在语句的If部分了。您的代码怎么可能跳转到ELSE块?问题是,如果ELSE语句因异常而失败,if语句将不会执行。您的IF语句似乎也不正确-是否应该是IF EXISTS[然后删除记录?]按照现在编写的方式,如果记录存在,则不会删除它 扩展的问题是,依赖异常(在C#、SQL或任何其他语言中)作为流控制方法被认为是不好的做法
最好使用EXISTS语句为每个相关表显式检查相关记录 如果
表
是一组表,则第一个表的第一列需要另一个[0]
。使用以下方法:
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
当多个表通过外键“链接”并删除父行时,会出现一个错误,就像报告一样,因为没有父行,子数据就不可能存在。您可能希望查看级联删除,或者在此过程中添加代码以通过外键从与标题关联的表中删除。将这些删除添加到从标题中删除之前
。这样做:
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
您可以对输出结果使用@@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
在我看来,表实际上是执行标量方法返回的“对象”。我希望它在那里抛出一个异常(或者实际上可能没有编译),因为在返回的对象上不会有一个名为“Table”的属性或方法。不过我可能错了。:)您至少应该捕获一个sqlexception(我相信这是正确的,如果不查找它的话)。目前,您可能会在这里捕获各种不相关的异常,并忽略它们。你真的应该捕捉到特定的异常,这样任何意外的异常都可以冒泡到应用程序级错误处理程序,以便进行适当的处理和记录以及其他任何操作。你是对的。。如果只存在。。是一个错误。。我已经更正了它。一个问题-有什么方法可以处理许多使用该标题ID作为外键的表?仍然在所有这些表中显式检查吗?请回答