Recuperare il tipo dei dati sulla colonna di un DB ACCESS

venerdì 30 dicembre 2005 - 12.55

alessandro.rossi Profilo | Newbie

E' da diversi giorni che cerco di trovare una procedura che mi permetta di recuperare il tipo dei dati contenuti nelle colonne delle tabelle di un DB Access usando il framework dotNET. Sono riuscito ad ottenere l'ID del tipo ( un Int32 ) grazie al campo DATA_TYPE ottenuto con getSchemaTable usando come guid Columns ma non riesco a trovare una corrispondenza tra quest'ID ed i tipi usati da access.

Vi ringrazio
Alessandro

Brainkiller Profilo | Guru

>E' da diversi giorni che cerco di trovare una procedura che
>mi permetta di recuperare il tipo dei dati contenuti nelle colonne
>delle tabelle di un DB Access usando il framework dotNET. Sono
>riuscito ad ottenere l'ID del tipo ( un Int32 ) grazie al campo
>DATA_TYPE ottenuto con getSchemaTable usando come guid Columns
>ma non riesco a trovare una corrispondenza tra quest'ID ed
> i tipi usati da access.

Ciao Alessandro,
la procedura che hai utilizzato è corretta. Non so se è possibile da quell'ID risalire al tipo dati da dentro .NET. Quello che ti consiglio di fare è creare una tabella in Access con varie colonne ognuno con un tipo dati diverso dall'altro in modo da coprirle tutte.

Poi usi il tuo programma e da lì ricavi i vari ID per ogni tipo dati, in modo che riesci ad ottenere un mapping. Una volta fatto questo dentro la tua applicazione puoi fare una funzioncina con un CASE per i vari ID in modo che ti restituisca il tipo dati in formato testuale.

Ciao

David De Giacomi
Microsoft MVP
http://blogs.dotnethell.it/david/

Brainkiller Profilo | Guru

Aggiungo che c'è anche l'enumeratore OleDbType che contiene tutti i vari possibili campi nativi, quindi invece che fare come ti ho consigliato nel post precedente, puoi fare un semplice CASE e comparare l'ID restituito dalla GetOleDbSchemaTable con i diversi valori di OleDbType. Per esempio a OleDbType.WChar corrisponde il valore ID 130. Ciao

David De Giacomi
Microsoft MVP
http://blogs.dotnethell.it/david/

lbenaglia Profilo | Guru

Ciao Alessandro,

> Aggiungo che c'è anche l'enumeratore OleDbType che contiene tutti i vari possibili campi nativi,
> quindi invece che fare come ti ho consigliato nel post precedente, puoi fare un semplice CASE
> e comparare l'ID restituito dalla GetOleDbSchemaTable con i diversi valori di OleDbType.
> Per esempio a OleDbType.WChar corrisponde il valore ID 130.

In base a quanto suggerisce David potresti evitare il case eseguendo un cast esplicito del valore della colonna "ProviderType" a OleDbType.
Ti allego una applicazioncina console in c# che mostra come fare:


using System;
using System.Data;
using System.Data.OleDb;

namespace GetColumnType
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string strCnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Inetpub\\wwwroot\\Nwind.mdb;User Id=admin;Password=;";
OleDbConnection cnNwind = new OleDbConnection(strCnString);
OleDbCommand cmdEmployees = new OleDbCommand("SELECT * FROM Employees", cnNwind);
cnNwind.Open();

OleDbDataReader myReader = cmdEmployees.ExecuteReader(CommandBehavior.KeyInfo);
DataTable myTable = myReader.GetSchemaTable();

foreach(DataRow myRow in myTable.Rows)
{
Console.WriteLine("Nome colonna: {0} - Data Type: {1}", myRow["ColumnName"].ToString(), (OleDbType)myRow["ProviderType"]);
}
Console.ReadLine();

cnNwind.Close();
}
}
}

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alessandro.rossi Profilo | Newbie

Ringrazio a turri per i vostri consigli.

Ho risolto il problema trovando la corrispondenza che cercavo. Questo è il codice manged C++ che risolve il problema il tipo ritornato è quello accettato dall'SQL di ACCESS :


String *OleDbOperation::getFieldType(String *tbName, String *fldName){

conn->Open();
Object* restrictions[] = {0, 0, tbName, fldName};
DataTable* schemaTable = conn->GetOleDbSchemaTable(OleDbSchemaGuid::Columns, restrictions);
conn->Close();
StringBuilder *out = new StringBuilder();
DataRow *row = schemaTable->Rows->Item[0];
// Recupero codice del tipo e lunghezza del dato
Object *dtype = row->get_Item(S"DATA_TYPE");
String *length = row->get_Item(S"CHARACTER_MAXIMUM_LENGTH")->ToString();
conn->Open();

Object *restriction[] = { 0, 0 };
// Richiedo la tabella delle corrispondenze
schemaTable = conn->GetOleDbSchemaTable(OleDbSchemaGuid::Provider_Types, restriction);
conn->Close();
String *tname = NULL;
for ( int i = 0; i < schemaTable->Rows->Count; i++) {
row = schemaTable->Rows->get_Item(i);
// ottengo il match
if ( row->get_Item(S"DATA_TYPE")->Equals(dtype) ) {
tname = row->get_Item(S"TYPE_NAME")->ToString();
}
}

out->Append(tname);
if ( ( length != NULL ) && ( !length->Equals(S"") ) ) {
out->Append(S"(");
out->Append(length);
out->Append(S")");
}
// ritorno il tipo del campo richiesto
return out->ToString();
}


Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5