0

我的代码正在运行,该函数为我提供了正确的选择计数 (*) 值,但无论如何,它都会引发 ORA-25191 异常 - 无法引用索引组织表提示的溢出表,位于 retVal = Convert.ToInt32(cmd.ExecuteScalar ());

由于我经常使用该函数,异常会极大地减慢我的程序。

 private int getSelectCountQueryOracle(string Sqlquery)
        {
            try
            {
                int retVal = 0;
                using (DataTable dataCount = new DataTable())
                {
                    using (OracleCommand cmd = new OracleCommand(Sqlquery))
                    {
                        cmd.CommandType = CommandType.Text;
                        cmd.Connection = oraCon;

                        using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
                        {
                            retVal = Convert.ToInt32(cmd.ExecuteScalar());
                        }
                    }
                }
                return retVal;
            } 
            catch (Exception ex)
            {
                exceptionProtocol("Count Function", ex.ToString());
                return 1;
            }
        }

该函数在foreach循环中调用

    // function call in foreach loop which goes through tablenames
        foreach (DataRow row in dataTbl.Rows)
                    {...    
                     tableNameFromRow = row["TABLE_NAME"].ToString();                                 
                     tableRows=getSelectCountQueryOracle("select count(*) as 'count' from " +tableNameFromRow);
                     tableColumns = getSelectCountQueryOracle("SELECT COUNT(*) as 'count' FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='" + tableNameFromRow + "'");
                     ...}

dataTbl.rows在这个外部循环中,反过来,来自查询

SELECT * FROM USER_TABLES ORDER BY TABLE_NAME
4

2 回答 2

0

这篇文章帮助我解决了我的问题。

我已将查询更改为:

SELECT * FROM user_tables 
WHERE iot_type IS NULL OR iot_type != 'IOT_OVERFLOW' 
ORDER BY TABLE_NAME
于 2021-10-28T08:03:40.843 回答
0

如果您使用的是 ADO.Net 等与数据库无关的 API,您几乎总是希望使用 API 的框架来获取元数据,而不是针对每个数据库的元数据表编写自定义查询。各种 ADO.Net 提供程序更有可能编写处理所有各种极端情况的数据字典查询,并且比您可能编写的查询更有可能得到优化。因此,与其编写自己的查询来填充dataTbl数据表,不如使用GetSchema方法

DataTable dataTbl = connection.GetSchema("Tables");  

如果您出于某种原因想要保留自定义编码的数据字典查询,则需要过滤掉 IOT 溢出表,因为您无法直接查询这些表。

select *
  from user_tables
 where iot_type IS NULL
    or iot_type != 'IOT_OVERFLOW'

但是请注意,您可能不想尝试从中获取计数的其他表。例如,该dropped列指示表是否已被删除——大概您不想计算回收站中对象的行数。所以你也需要一个dropped = 'NO'谓词。而且您不能对嵌套表执行 a操作,因此如果您的架构碰巧包含嵌套表count(*),您也希望有一个谓词。nested = 'NO'可能还有其他极端情况,具体取决于您的特定架构使用的确切功能集,提供者的开发人员已添加了您必须处理的代码。

所以我会从

select *
  from user_tables
 where (   iot_type IS NULL
        or iot_type != 'IOT_OVERFLOW')
   and dropped = 'NO'
   and nested = 'NO'

但要知道,您可能需要/想要添加一些额外的过滤器,具体取决于用户使用的特定功能。我当然宁愿让开发 ADO.Net 提供程序的优秀人员担心所有这些极端情况,也不愿自己处理所有这些情况。

不过,退后一步,我会质疑为什么您经常count(*)对架构中的每个表执行 a 以及为什么您需要一个准确的答案。在您进行计数的大多数情况下,您要么只做一次性的,您不太关心它需要多长时间(即迁移后的验证步骤),要么近似计数就足够了(即获取列表系统中最大的表,以便对一些工作进行分类或跟踪预测随时间的增长)在这种情况下,您可以只使用已经存储在数据字典中的计数user_tables.num_rows- 从上次运行统计数据开始。

于 2021-10-28T08:03:48.030 回答