How to get the SqlType of a column in a DataTable?

浪尽此生 提交于 2019-11-30 14:37:14

问题


I have a DataTable obtained from a SQL DataBase, like this:

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;
    }
}

When I try to get the DataType of each column through dataColumn.DataType , I get the C# types (Int32, Int64, String, etc).

QUESTION: How can I access the native SQL data types (varchar, nvarchar, bigint...) instead of the C# types?

I have tried dataColumn.DataType.UnderlyingSystemType and the result is the same.


回答1:


You cannot because System.Data.DataTable (or DataColumn, or DataSet, or DataRow...) is a generic .NET data container which works the same way regardless on the specific database engine you loaded your data from.

this means that provided you used a .NET Connector for SQL Server, MySQL, Access, PostgreSQL or anything else, the DataTable and DataColumn classes are always the same and being ADO.NET objects are generic to work with any db engine, so the columns are typed with the .NET types as you have found out.




回答2:


Of course it is possible to take SqlDbType of a column, the answer is here on SO: 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"];



回答3:


SqlConnection SqlCon = new SqlConnection("Data Source=(local);Database=  dbname;Integrated Security=SSPI;");

SqlDataReader SqlDr;

SqlCon.Open();
SqlCmd = SqlCon.CreateCommand();

SqlCmd.CommandText = "select * from Tablename";

SqlDr = SqlCmd.ExecuteReader();
SqlDr.Read();
int i=0;
while (i < SqlDr.FieldCount)
{ MessageBox.Show(SqlDr.GetDataTypeName(i)); i++;}'



回答4:


Another approach is to let SQL do the work for you:

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);
}



回答5:


As David says ... you are in .NET so the types will be .NET types. This is a listing of type mappings from SQL Server to .Net that shows you what .NET type you will end up with for a given Sql column type .. hope this helps ..

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




回答6:


If you are using DataReader -

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

should work if you want the SQL data type of a column




回答7:


Building upon Madhukar Krishna's answer, if you have a SQLDataReader or a MySQLDataReader object you can obtain the SQL type metadata for a given column (in the code, we obtain the metadata of column with index 1) using the following code (example working for MySQLDataReader object):

...
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);

The line:

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

is used to obtain the System.Data.SqlDbType from a String, and ignoring the letter case, e.g. if dr.GetDataTypeName(1) returns "VARCHAR" then the System.Data.SqlDbType enum value is System.Data.SqlDbType.VarChar.

Then, you can get get the size of the data type (for instance VARCHAR(15)) by inspecting the SQL columns metadata with the following code (source 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();
}

The property ColumnSize gives the size information.



来源:https://stackoverflow.com/questions/7470258/how-to-get-the-sqltype-of-a-column-in-a-datatable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!