Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 存储过程赢得';t返回0_C#_Asp.net_Sql Server_Stored Procedures - Fatal编程技术网

C# 存储过程赢得';t返回0

C# 存储过程赢得';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

这是我的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在许多表中都是外键。如果某个表的记录使用了TitleID,那么它会抛出这个异常,表示“外键冲突n stuff”。在上面的存储过程中,如果删除不成功,我将在else块中选择零。当delete成功时,它返回TitleID的值,比如50、99或其他值。现在发生的是,当删除不成功时,它不会返回零。我希望根据Delete存储过程返回的这个零值在屏幕上显示一条消息,但当它没有返回任何值时(当Delete失败时),我在DeleteTitle()方法的catch块中返回了零

现在我有两个问题:-

  • 为什么删除失败时存储过程不返回零
  • 在catch块中返回零是否像我在上面所做的那样正确?我不知道如何检索外键异常号和其他内容,所以我只是在catch块中返回了零
  • 你应该在你的程序中加入一个,而不是一个IF…ELSE


    仔细想想,当删除失败并违反外键时,您已经在语句的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作为外键的表?仍然在所有这些表中显式检查吗?请回答