You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现Oracle数据库指定表全量数据控制台打印的问题

如何修改C# Oracle程序以适配任意表结构打印全量数据

嘿,我来帮你搞定这个问题!你的原代码只固定读取了第一列的数据,要实现适配所有表结构打印全量数据,咱们需要做几个关键修改——核心就是要动态遍历结果集的所有列,还要处理不同数据类型的字段,同时还得注意安全性问题。

原代码的问题点

原代码里reader.GetString(0)是硬编码取第一列的字符串值,这就导致只能看到第一列,而且如果第一列不是字符串类型还会报错。要适配任意表,得动态获取列的数量和每一列的值。

解决方案关键步骤

  • 动态获取列数:利用OracleDataReader.FieldCount属性拿到结果集的总列数,然后循环遍历每一列
  • 处理不同数据类型:不要直接用GetString,改用GetValue()方法,它能适配所有数据类型,再转成字符串输出;同时要处理DBNull的空值情况
  • 打印表头(可选但友好):先打印每一列的列名,让输出结果更易读
  • 防范SQL注入:原代码直接拼接用户输入的表名,这有很大的安全风险!咱们可以先查询Oracle的USER_TABLES视图,验证用户输入的表名是否存在,避免恶意输入

修改后的完整代码

using System;
using Oracle.ManagedDataAccess.Client;

namespace Ass1Que1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string constr = "DATA SOURCE=localhost:1521/orclpdb;PERSIST SECURITY INFO=True;USER ID=HR;password=hr";
                
                // 使用using自动释放资源,避免内存泄漏
                using (OracleConnection con = new OracleConnection(constr))
                {
                    con.Open();
                    Console.WriteLine("Connected to Oracle Database {0}", con.ServerVersion);

                    Console.Write("Enter the table name: ");
                    string tableName = Console.ReadLine().Trim().ToUpper();

                    // 先验证表名合法性,彻底防范SQL注入
                    if (!IsTableExists(con, tableName))
                    {
                        Console.WriteLine($"Error: Table '{tableName}' does not exist in HR schema!");
                        Console.WriteLine("Press RETURN to exit.");
                        Console.ReadLine();
                        return;
                    }

                    // 执行查询
                    string sql = $"SELECT * FROM {tableName}";
                    using (OracleCommand cmd = con.CreateCommand())
                    {
                        cmd.CommandText = sql;
                        using (OracleDataReader reader = cmd.ExecuteReader())
                        {
                            if (!reader.HasRows)
                            {
                                Console.WriteLine($"No data found in table '{tableName}'.");
                                Console.WriteLine("Press RETURN to exit.");
                                Console.ReadLine();
                                return;
                            }

                            // 打印表头:遍历所有列名
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                Console.Write($"{reader.GetName(i),-20}"); // 格式化列名,左对齐占20字符
                            }
                            Console.WriteLine("\n" + new string('-', reader.FieldCount * 20)); // 打印分隔线

                            // 遍历每一行数据
                            while (reader.Read())
                            {
                                // 遍历当前行的所有列
                                for (int i = 0; i < reader.FieldCount; i++)
                                {
                                    // 处理空值,将DBNull转为"NULL"字符串
                                    string value = reader.IsDBNull(i) ? "NULL" : reader.GetValue(i).ToString();
                                    Console.Write($"{value,-20}"); // 格式化输出,保持列对齐
                                }
                                Console.WriteLine(); // 每行结束换行
                            }
                        }
                    }

                    Console.WriteLine("\nPress RETURN to exit.");
                    Console.ReadLine();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error : {0}", ex.Message);
                Console.ReadKey();
            }
        }

        /// <summary>
        /// 验证HR用户下是否存在指定表
        /// </summary>
        private static bool IsTableExists(OracleConnection connection, string tableName)
        {
            string checkSql = "SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME = :tableName";
            using (OracleCommand cmd = connection.CreateCommand())
            {
                cmd.CommandText = checkSql;
                cmd.Parameters.Add(":tableName", OracleDbType.Varchar2).Value = tableName;
                int count = Convert.ToInt32(cmd.ExecuteScalar());
                return count > 0;
            }
        }
    }
}

关键修改说明

  1. 资源自动管理:用using语句包裹连接、命令和读取器,自动释放资源,避免内存泄漏
  2. SQL注入防护:新增IsTableExists方法,通过参数化查询验证表名合法性,彻底避免恶意输入风险
  3. 动态列处理:
    • 用reader.FieldCount获取总列数,循环打印列名作为表头
    • 每行数据遍历所有列,用GetValue(i)兼容所有数据类型,同时处理DBNull空值
  4. 格式化输出:用{value,-20}让每列左对齐并固定宽度,输出结果更整齐易读

这样修改后,不管HR用户下的表结构是什么样的,程序都能自动识别所有列并打印全量数据,同时解决了原代码的安全隐患和数据类型兼容问题。

内容的提问来源于stack exchange,提问作者S_Madankar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:39:12