【问题标题】:How to get the SqlType of a column in a DataTable?如何获取 DataTable 中列的 SqlType?
【发布时间】:2011-11-20 04:18:44
【问题描述】:

我有一个从 SQL 数据库获得的 DataTable,如下所示:

using (SqlCommand cmd = new SqlCommand(query, _sqlserverDB))
{
    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    {
        DataSet dataSet = new DataSet();
        adapter.Fill(dataSet);
        result = (dataSet != null && dataSet.Tables != null && dataSet.Tables.Count > 0) ? dataSet.Tables[0] : null;
    }
}

当我尝试通过 dataColumn.DataType 获取每列的 DataType 时,我得到了 C# 类型(Int32、Int64、String 等)。

问题:如何访问原生 SQL 数据类型(varchar、nvarchar、bigint...)而不是 C# 类型?

我试过dataColumn.DataType.UnderlyingSystemType,结果是一样的。

【问题讨论】:

    标签: c# sqldatatypes datacolumn


    【解决方案1】:

    当然可以取一列的SqlDbType,答案就在这里:link

    SqlCommand cmd = connection.CreateCommand();
    cmd.CommandText = "SET FMTONLY ON; select column from table; SET FMTONLY OFF";
    SqlDataReader reader = cmd.ExecuteReader();
    SqlDbType type = (SqlDbType)(int)reader.GetSchemaTable().Rows[0]["ProviderType"];
    

    【讨论】:

    • 不幸的是,SQL Server 2012 文档中有一条说明不要使用此功能。见msdn.microsoft.com/en-us/library/ms173839.aspx
    • 也只有reader.GetSchemaTable().Rows[x]["ProviderSpecificDataType"]
    • 为避免“SET FMTONLY ON”,您可以在选择语句中使用“TOP 0”
    【解决方案2】:

    您不能因为System.Data.DataTable(或DataColumn,或DataSet,或DataRow...)是一个通用的.NET 数据容器,无论您加载数据的特定数据库引擎如何,它的工作方式都是相同的来自。

    这意味着如果您为 SQL Server、MySQL、Access、PostgreSQL 或其他任何东西使用了 .NET 连接器,DataTableDataColumn 类总是相同的,并且作为 ADO.NET 对象是通用的任何 db 引擎,因此列是使用您发现的 .NET 类型键入的。

    【讨论】:

      【解决方案3】:
      SqlConnection SqlCon = new SqlConnection("Data Source=(local);Database=dbname;Integrated Security=SSPI;");
      
      SqlCon.Open();
      
      SqlCmd = SqlCon.CreateCommand();
      SqlCmd.CommandText = "select * from Tablename";
      
      SqlDataReader SqlDr = SqlCmd.ExecuteReader();
      SqlDr.Read();
      
      int i = 0;
      
      while (i < SqlDr.FieldCount)
      { 
         MessageBox.Show(SqlDr.GetDataTypeName(i));
         i++;
      }
      

      【讨论】:

      • 您好 Madhukar,欢迎来到 StackOverflow。考虑添加一些口头描述您的代码的作用。这将提高您答案的质量,更好地帮助将来阅读它的其他人,并为您提供更多支持。有关详细信息,请参阅How to Answer
      • 使用 SqlDataReader.GetDataTypeName() 返回本机 SQL Server 类型。 SqlDataReader.GetFieldType() 返回 .NET Framework 类型。当我需要构建 T-SQL 语句来更改数据库列类型或大小时,我发现前者很有用。
      【解决方案4】:

      另一种方法是让 SQL 为您完成工作:

      SqlConnection rConn = connectToSQL(); //returns sql connection
      SqlCommand SqlCmd = new SqlCommand();
      SqlCmd = rConn.CreateCommand();
      SqlCmd.CommandText = "SELECT ORDINAL_POSITION, " +
                               "COLUMN_NAME, " +
                               "DATA_TYPE, " +
                               "CHARACTER_MAXIMUM_LENGTH, " +
                               "IS_NULLABLE " +
                          "FROM INFORMATION_SCHEMA.COLUMNS " +
                          "WHERE TABLE_NAME = 'TableName'";
      SqlDataReader SqlDr = SqlCmd.ExecuteReader();
      SqlDr.Read();
      while (SqlDr.Read()) { 
          var OrdPos = SqlDr.GetValue(0);
          var ColName = SqlDr.GetValue(1);
          var DataType = SqlDr.GetValue(2);
          var CharMaxLen = SqlDr.GetValue(3);
          var IsNullable = SqlDr.GetValue(4);
          Console.WriteLine("ColName - " + ColName + " DataType - " + DataType + " CharMaxLen - " + CharMaxLen);
      }
      

      【讨论】:

      • 这将只返回 SqlDataTypes 的字符串版本。 OP 正在寻找 System.Data.SqlDbType 枚举。
      【解决方案5】:

      正如大卫所说...您在 .NET 中,因此类型将是 .NET 类型。这是从 SQL Server 到 .Net 的类型映射列表,它向您展示了对于给定的 Sql 列类型您最终会得到什么 .NET 类型..希望这会有所帮助..

      http://msdn.microsoft.com/en-us/library/ms131092.aspx

      【讨论】:

        【解决方案6】:

        基于 Madhukar Krishna 的回答,如果您有 SQLDataReaderMySQLDataReader 对象,您可以使用以下代码(适用于MySQLDataReader 对象的示例):

        ...
        MySqlDataReader dr = ...
        Console.WriteLine("dr.GetFieldType(1) = {0}, dr.GetName(1) = {1}, dr.GetValue(1) = {2}, dr.GetDataTypeName(1) = {3}", 
                                  dr.GetFieldType(1), dr.GetName(1), dr.GetValue(1), dr.GetDataTypeName(1));
                bool b = Enum.TryParse(dr.GetDataTypeName(1), true, out System.Data.SqlDbType mySqlDbTypeEnum);
                Console.WriteLine("mySqlDbTypeEnum = {0}, b = {1}", mySqlDbTypeEnum, b);
        

        行:

        bool b = Enum.TryParse(dr.GetDataTypeName(1), true, out System.Data.SqlDbType mySqlDbTypeEnum);
        

        用于从String 获取System.Data.SqlDbType,并忽略字母大小写,例如如果dr.GetDataTypeName(1) 返回"VARCHAR",则System.Data.SqlDbType 枚举值为System.Data.SqlDbType.VarChar

        然后,您可以通过使用以下代码检查 SQL 列元数据来获取数据类型的大小(例如 VARCHAR(15))(来源 MSDN):

        ... (continuation)
        DataTable schemaTable;
        // Retrieve column schema into a DataTable.
        schemaTable = dr.GetSchemaTable();
        // For each field in the table...
        foreach (DataRow myField in schemaTable.Rows)
        {
           // For each property of the field...
           foreach (DataColumn myProperty in schemaTable.Columns)
           {
              // Display the field name and value.
              Console.WriteLine(myProperty.ColumnName + " = " + myField[myProperty].ToString());
           }
           Console.WriteLine();
           // Pause.
           //Console.ReadLine();
        }
        

        ColumnSize 属性给出了大小信息。

        【讨论】:

          【解决方案7】:

          如果您使用的是 DataReader -

          SqlDataReader reader = cmd.ExecuteReader(); reader.GetDataTypeName(int ordinal)

          如果你想要列的 SQL 数据类型应该可以工作

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-07-07
            • 1970-01-01
            • 1970-01-01
            • 2019-01-07
            • 1970-01-01
            • 2021-10-16
            • 1970-01-01
            • 2023-01-19
            相关资源
            最近更新 更多