Как да получа SqlType на колона в DataTable?

Имам DataTable, получена от SQL база данни, като тази:

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

Когато се опитам да получа DataType на всяка колона чрез dataColumn.DataType, получавам типовете C# (Int32, Int64, String и т.н.).

ВЪПРОС: Как мога да осъществя достъп до родните SQL типове данни (varchar, nvarchar, bigint...) вместо типовете C#?

Опитах dataColumn.DataType.UnderlyingSystemType и резултатът е същият.


person DarthRoman    schedule 19.09.2011    source източник


Отговори (7)


Не можете, защото System.Data.DataTable (или DataColumn, или DataSet, или DataRow...) е общ .NET контейнер за данни, който работи по същия начин, независимо от конкретната база данни, от която сте заредили вашите данни.

това означава, че при условие, че сте използвали .NET конектор за SQL Server, MySQL, Access, PostgreSQL или нещо друго, класовете DataTable и DataColumn винаги са едни и същи и като ADO.NET обекти са общи за работа с всяка db машина, така че колоните са въведени с типовете .NET, както разбрахте.

person Davide Piras    schedule 19.09.2011

Разбира се, възможно е да вземете SqlDbType на колона, отговорът е тук на SO: връзка.

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"];
person infografnet    schedule 15.03.2012
comment
За съжаление в документацията на SQL Server 2012 има забележка тази функция да не се използва. Вижте msdn.microsoft.com/en-us/library/ms173839.aspx - person Naomi; 11.07.2013
comment
Има и само reader.GetSchemaTable().Rows[x]["ProviderSpecificDataType"] - person Nacht; 21.09.2015
comment
За да избегнете SET FMTONLY ON, можете да използвате TOP 0 в израза select - person Piotr; 02.04.2020

Друг подход е да оставите 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);
}
person chaos10    schedule 04.03.2016
comment
Това просто ще върне низовата версия на SqlDataTypes. OP търси System.Data.SqlDbType enum. - person JBond; 04.10.2016

Както казва Дейвид ... вие сте в .NET, така че типовете ще бъдат .NET типове. Това е списък със съпоставяния на типове от SQL Server към .Net, който ви показва какъв .NET тип ще получите в крайна сметка за даден тип Sql колона .. надявам се това да помогне ..

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

person iDevForFun    schedule 19.09.2011

Ако използвате DataReader -

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

трябва да работи, ако искате SQL типа данни на колона

person ManJan    schedule 18.08.2015

Въз основа на отговора на Madhukar Krishna, ако имате SQLDataReader или MySQLDataReader обект, можете да получите метаданните за типа SQL за дадена колона (в кода получаваме метаданните на колона с индекс 1), като използвате следния код (пример за работа за 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);

се използва за получаване на System.Data.SqlDbType от String и пренебрегване на главните букви, напр. ако dr.GetDataTypeName(1) върне "VARCHAR", тогава стойността на System.Data.SqlDbType enum е System.Data.SqlDbType.VarChar.

След това можете да получите размера на типа данни (например VARCHAR(15)), като проверите метаданните на SQL колоните със следния код (източник 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 дава информация за размера.

person Nuno Leite    schedule 07.04.2018

person    schedule
comment
Здравей Madhukar и добре дошъл в StackOverflow. Помислете дали да не добавите словесно описание какво прави вашият код. Това ще повиши качеството на вашия отговор, ще помогне по-добре на другите, които ще го прочетат в бъдеще, и ще ви даде повече гласове за. Вижте Как да отговорите за повече подробности. - person bytebuster; 14.10.2012
comment
Използването на SqlDataReader.GetDataTypeName() връща родния тип на SQL Server. SqlDataReader.GetFieldType() връща типа .NET Framework. Намерих първото полезно, когато трябваше да създам T-SQL израз, за ​​да променя типовете или размерите на колоните на базата данни. - person Paul J; 23.03.2013