OracleCommand 命令,ExecuteNonQuery 问题

Posted

技术标签:

【中文标题】OracleCommand 命令,ExecuteNonQuery 问题【英文标题】:OracleCommand command, ExecuteNonQuery issue 【发布时间】:2011-07-19 20:05:17 【问题描述】:

但是当我在运行以下代码时遇到问题时,我必须清除 oracle 数据库中的某些表

public static void ClearDataTables(IList<string> tableNames)
        
            string connectionString = "CONNECTIONSTRING";
            using (OracleConnection connection = new OracleConnection())
            
                connection.ConnectionString = connectionString;
                connection.Open();
                foreach (string table in tableNames)
                
                    OracleCommand command = connection.CreateCommand();
                    string sql = String.Format("DELETE FROM TOA_REPORTING.0", table);
                    command.CommandText = sql;
                    command.ExecuteNonQuery();
                
                connection.Close();
            
        

我用这个列表调用这个方法

ClearDataTables(new List<string>  "GROUP_DEFINITION", "GROUP_REPORT_EMAIL_LIST", "GROUP_EQUIPMENT_GROUP_STN_XREF");

前两个表运行良好,但在第三个表上,它卡住了,应用程序永远运行...

有趣的是,当我切换“GROUP_REPORT_EMAIL_LIST”和“GROUP_EQUIPMENT_GROUP_STN_XREF”时 应用程序在遇到第二个表名后永远运行。

因此,总而言之,该函数在命中“GROUP_EQUIPMENT_GROUP_STN_XREF”时将永远运行。我已经通过在 toad 上测试它来验证生成的 SQL 是否有效。

还有其他人遇到过这个问题吗?

编辑 - 前两个表在运行时确实会被清除。

解决方案

string connectionString = "CONNECTIONSTRING";
            using (OracleConnection connection = new OracleConnection(connectionString))
            
                connection.Open();
                OracleCommand command = connection.CreateCommand();
                OracleTransaction trans = connection.BeginTransaction();
                command.Transaction = trans;
                foreach (string table in tableNames)
                
                    string sql = String.Format("DELETE FROM TOA_REPORTING.0", table);
                    command.CommandText = sql;
                    command.ExecuteNonQuery();
                
                trans.Commit();
            

TRUNCATE 本来是一个很好的解决方案,但是我没有这样做的权限!

【问题讨论】:

任何带有完整源代码示例的最终解决方案? 【参考方案1】:

该表中有很多数据吗?这可以解释为什么删除数据需要这么长时间。 无论如何,我建议使用TRUNC 来清表。

【讨论】:

您无法确定 OP 是否确实需要使用 trunc 清除表时不可用的撤消功能。 @Mike:如何在commit 之后撤消delete 可以通过 UNDO 功能完成恢复场景。 download.oracle.com/docs/cd/B19306_01/server.102/b14196/… @Mike:感谢您的链接。不幸的是,我想我无法理解这与撤消已提交的删除有何关系。 在生产环境中,被删除的数据很可能需要手动恢复(文档中的闪回)直到某个点。截断表格消除了这种可能性。您没有提供任何建议 TRUNCATE 而不是 DELETE 的原因。【参考方案2】:

您是否忘记在 Toad(或任何其他客户端)中提交更改?一个打开的事务将导致它无限期地等待。

【讨论】:

【参考方案3】:

大量删除可能会非常慢,尤其是在一个事务中运行它们时。如果您根本不需要事务,请使用:

truncate table YourTable

如果这样做,请将delete 拆分为小型事务。基本运行:

delete from YourTable where rownum < 100

直到桌子为空。例如,请参见 blog post。

【讨论】:

【参考方案4】:

我可能会编写一个存储过程来执行所有删除或截断并调用一次 SP,而不是在客户端使用循环。

编辑:最好不要在循环内创建命令对象。使用 table-name 参数在循环外创建一次,然后在每次迭代时调用它为它提供不同的参数值。但是SP是首选。

【讨论】:

以上是关于OracleCommand 命令,ExecuteNonQuery 问题的主要内容,如果未能解决你的问题,请参考以下文章

OracleCommand.CommandText 中的查询文本是不是有最大长度?

简单的 Oracle 查询返回 OracleCommand.CommandText 无效

如何使用 OracleCommand C# 执行不同的多条 SQL 语句

OracleCommand SQL 参数绑定

oracle reader 返回 System.Data.OracleClient.OracleCommand 作为值

如何通过 OracleCommand 使用 OracleTransaction 将父表的 id 传递给子表