web-dev-qa-db-fra.com

Comment obtenir le SqlType d'une colonne dans un DataTable?

J'ai un DataTable obtenu à partir d'une base de données SQL, comme ceci:

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

Lorsque j'essaie d'obtenir le type de données de chaque colonne via dataColumn.DataType, j'obtiens les types C # (Int32, Int64, String, etc.).

QUESTION: Comment puis-je accéder aux types de données SQL natifs (varchar, nvarchar, bigint ...) au lieu des types C #?

J'ai essayé dataColumn.DataType.UnderlyingSystemType et le résultat est le même.

15
DarthRoman

Vous ne pouvez pas parce que System.Data.DataTable (ou DataColumn, ou DataSet ou DataRow...) est un conteneur de données générique .NET qui fonctionne de la même manière quel que soit le moteur de base de données spécifique à partir duquel vous avez chargé vos données.

cela signifie que si vous avez utilisé un connecteur .NET pour SQL Server, MySQL, Access, PostgreSQL ou autre, les classes DataTable et DataColumn sont toujours les mêmes et les objets ADO.NET étant génériques pour fonctionner avec tout moteur de base de données, les colonnes sont tapés avec les types .NET comme vous l’avez découvert.

10
Davide Piras

Bien sûr, il est possible de prendre SqlDbType d'une colonne, la réponse est ici sur 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"];
31
infografnet
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++;}'
8
Madhukar Krishna

Une autre approche consiste à laisser SQL faire le travail pour vous:

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

Comme David le dit ... vous êtes dans .NET, les types seront donc des types .NET. Voici une liste des mappages de types de SQL Server vers .Net, qui indique le type .NET que vous obtiendrez pour un type de colonne Sql donné. 

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

2
iDevForFun

En vous basant sur la réponse de Madhukar Krishna, si vous avez un objet SQLDataReader ou MySQLDataReader, vous pouvez obtenir les métadonnées de type SQL pour une colonne donnée (dans le code, nous obtenons les métadonnées de la colonne d’index 1) en utilisant le code suivant (exemple de travail pour MySQLDataReader objet):

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

La ligne:

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

est utilisé pour obtenir le System.Data.SqlDbType à partir d'une String et en ignorant le casse des lettres, par exemple. Si dr.GetDataTypeName(1) renvoie "VARCHAR", la valeur de System.Data.SqlDbType enum est System.Data.SqlDbType.VarChar.

Ensuite, vous pouvez obtenir la taille du type de données (par exemple, VARCHAR (15)) en inspectant les métadonnées des colonnes SQL avec le code suivant (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();
}

La propriété ColumnSize donne les informations de taille.

0
Nuno Leite

Si vous utilisez DataReader - 

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

devrait fonctionner si vous voulez le type de données SQL d'une colonne

0
ManJan