【问题标题】:Check SQL success [closed]检查SQL成功[关闭]
【发布时间】:2014-05-13 13:45:26
【问题描述】:

我正在用 C# 编写一个应用程序(第一次)。我有一个用户在表单中输入了很多数据,我正在将这些数据插入到数据库中。它是一个使用 SQL Server 的 Windows 窗体应用程序。

用户提交表单后,会更新多个表。 (大约 6 个)我试图避免更新 3 个表而第 4 个表抛出错误并且我不知道如何执行此操作的情况。所有数据都是正确的数据类型,所以我的问题更多是在数据库连接端。

因此,理想情况下,如果所有 6 次插入都不成功,我不希望它们都成功。我知道我可以在 catch 子句中删除记录以回滚。这是最有效的方法还是有“最佳实践”?

【问题讨论】:

  • 你试过什么?给我们看一些代码?
  • 您愿意分享一些代码吗?很难仅根据失败的解释提出建议。
  • 现在我正在考虑它,如果有连接问题,我无法删除回滚,所以我需要一个解决方案:)
  • 你听说过“交易”吗?我在想“不”。
  • 开始一个事务,在事务中做所有六次插入;如果到目前为止没有异常 - 提交事务,否则回滚它

标签: c# sql-server error-handling


【解决方案1】:

如果没有您当前的代码,这有点困难,但通常您可以为此使用 TransactionScope 类。

例如

using (TransactionScope scope = new TransactionScope())
    {
        using (SqlConnection connection1 = new SqlConnection(connectString1))
        {
            Action1(connection1);
            Action2(connection1);
            Action3(connection1);
            Action4(connection1);
            Action5(connection1);
            Action6(connection1);
        }

        // The Complete method commits the transaction. If an exception has been thrown, 
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();

    }

现在正如 cmets 所述,这不是性能最佳的解决方案,但可能适用于大多数中型项目。

您也可以使用Entity framework 进行数据访问。

另见Transactions in EF on stackoverflow

【讨论】:

  • 正是我想要的。感谢 Patrick、John 和 Dmitry!
  • 这将起作用,但需要每次由数据库解析。此外,所有 C# 业务逻辑更改都会导致代码重新分发。
【解决方案2】:

您绝对可以发送临时 TSQL 语句;但是,如果缓存计划不匹配,则每次都必须对其进行解析和编译。

为什么不使用使用表值参数(记录集)、事务和错误处理的存储过程?

这里的优点是它可以作为单独的代码单元进行测试,并且不会每次都被解析/重新编译。

如果你有大量的电话,那么这少量的时间就会加起来。

此外,如果业务规则发生变化,存储过程会发生变化,而不是 C# 程序。这是假设输入保持不变。

附上拼图部分的链接。剩下的就看你自己了。

-- Begin Transaction
http://technet.microsoft.com/en-us/library/ms188929.aspx

-- Try/Catch
http://technet.microsoft.com/en-us/library/ms175976.aspx

-- Commit transaction
http://technet.microsoft.com/en-us/library/ms190295.aspx

-- Roll back transaction
http://technet.microsoft.com/en-us/library/ms181299.aspx

-- Table Variable Parameter w/ADO.NET call
http://technet.microsoft.com/en-us/library/bb510489.aspx

【讨论】:

    【解决方案3】:

    最好的方法是创建一个 SQL Server 存储过程,它可以获取您希望保存的所有输入并使用提交事务管理插入。

    示例(SP 的一部分)

    开始尝试 开始交易;

            -- Do your inserts here i,e
            --INSERT INTO TABLE1 (COL1,COL2) VALUES ('Val1','Val2')
    
            COMMIT TRANSACTION;
    

    结束尝试

    开始捕捉

    ROLLBACK TRANSACTION;
    
    --PRINT ERROR_PROCEDURE()
    --PRINT ERROR_NUMBER()
    --PRINT ERROR_LINE()
    --PRINT ERROR_MESSAGE()
    
    --INSERT INTO ERRORLOG (PROGMODULE,ERRORNO,ERRORLINENO,ERROR,ErrorState,ERRORDATE,ERRMAKER)
    --VALUES
    --(ERROR_PROCEDURE(),ERROR_NUMBER(),ERROR_LINE(),ERROR_MESSAGE(),ERROR_STATE(),GETDATE(),'CUSTOM DESCRIPTION');
    
    --or you can return the error to your application
    

    结束捕捉

    【讨论】:

    • 我认为“最佳方式”根本不涉及存储过程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多