Come posso ottenere i nomi dei campi di una tabella del database MS Access?Come posso ottenere i nomi dei campi di una tabella di database?
Esiste una query SQL che posso utilizzare oppure esiste il codice C# per eseguire questa operazione?
Come posso ottenere i nomi dei campi di una tabella del database MS Access?Come posso ottenere i nomi dei campi di una tabella di database?
Esiste una query SQL che posso utilizzare oppure esiste il codice C# per eseguire questa operazione?
questo funziona su sql server 2005 e fino:
select * from INFORMATION_SCHEMA.COLUMNS
where TABLE_Name='YourTableName'
order by ORDINAL_POSITION
ma lavoro in Access, e in accesso non funziona – Gold
@Gold, aggiungi il tag "accesso" alla domanda! –
Non funziona in accesso. Puoi spiegare cos'è INFORMATION_SCHEMA? –
A seconda del motore DB vostro usando si può facilmente interrogare le tabelle di sistema DB per le informazioni
Per l'accesso non riesco a trovare la risposta che so che can see the sys tables nell'accesso e da lì si poteva cercare di determinare dove questa informazione è, ma non sono davvero sicuro di come fare questa parte. ho provato ad usare un esempio, ma ora ho capito dove
MSysObjects contiene l'elenco di tabelle, purtroppo non ci sono equivalenti per i campi. –
Stai chiedendo come puoi ottenere i nomi delle colonne di una tabella in un Database?
Se così dipende completamente dal server database che si sta utilizzando.
In SQL 2005 è possibile selezionare dalla INFORMATION_SCHEMA.COLUMNS View
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
IN SQL 2000 è possibile partecipare a SysObjects SysColumns per avere le informazioni
SELECT
dbo.sysobjects.name As TableName
, dbo.syscolumns.name AS FieldName
FROM
dbo.sysobjects
INNER JOIN dbo.syscolumns
ON dbo.sysobjects.id = dbo.syscolumns.id
WHERE
dbo.sysobjects.name = 'MyTable'
Come si applica la tua risposta ad Access/Jet? –
-1 Chiede informazioni su MS Access. –
Scusa, riprendo il mio -1, la domanda originale non era chiara su questo punto. –
eseguita questa interrogazione:
select top 1 *
From foo
e quindi accedere ai campi dell'elenco (e ai valori restituiti) nel set di risultati per ottenere i nomi dei campi.
Se tutto ciò di cui hai bisogno è colonna * nomi *, allora questo approccio rapido e sporco è valido IMO. Nota è possibile aggiungere WHERE 0 = 1 (o simile) per garantire che nessun dato venga restituito. – onedaywhen
Questo non funziona se sono state definite didascalie. Mostra invece la didascalia. – jpmc26
Utilizzare le classi di automazione DAO. Potresti già avere una libreria di interoperabilità per l'installazione di Visual Studio. In caso contrario, è abbastanza facile crearne uno; basta aggiungere un riferimento alla libreria COM DAO.
using dao;
...
DBEngineClass dbengine = new DBEngineClass();
dbengine.OpenDatabase(path, null, null, null);
Database database = dbengine.Workspaces[0].Databases[0];
List<string> fieldnames = new List<string>();
TableDef tdf = database.TableDefs[tableName];
for (int i = 0; i < tdf.Fields.Count; i++)
{
fieldnames.Add(tdf.Fields[i].Name);
}
database.Close();
dbengine.Workspaces[0].Close();
Questo è altrettanto facile come l'interrogazione di una tabella di sistema (che ho trovato per essere problematico in Access), e si può ottenere un sacco di informazioni aggiuntive in questo modo.
EDIT: Ho modificato il codice da quello che ho postato ieri, che avevo appena tradotto dal VB.NET, e che mancava un paio di pezzi. L'ho riscritto e testato in C# in VS2008.
Da C#, le funzioni del Catalogo ADO potrebbero essere più semplici. –
IIRC le chiamate a OpenSchema per ottenere le VISIONI SCHEMA INFORMAZIONI non sono semplici per C# e potrebbero non valerne la pena solo per i nomi delle colonne. – onedaywhen
Usa IDataReader.GetSchemaTable()
Ecco un esempio reale che accede lo schema della tabella e lo stampa pianura e in XML (solo per vedere quali sono le informazioni che si ottiene):
class AccessTableSchemaTest
{
public static DbConnection GetConnection()
{
return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\\Test.mdb");
}
static void Main(string[] args)
{
using (DbConnection conn = GetConnection())
{
conn.Open();
DbCommand command = conn.CreateCommand();
// (1) we're not interested in any data
command.CommandText = "select * from Test where 1 = 0";
command.CommandType = CommandType.Text;
DbDataReader reader = command.ExecuteReader();
// (2) get the schema of the result set
DataTable schemaTable = reader.GetSchemaTable();
conn.Close();
}
PrintSchemaPlain(schemaTable);
Console.WriteLine(new string('-', 80));
PrintSchemaAsXml(schemaTable);
Console.Read();
}
private static void PrintSchemaPlain(DataTable schemaTable)
{
foreach (DataRow row in schemaTable.Rows)
{
Console.WriteLine("{0}, {1}, {2}",
row.Field<string>("ColumnName"),
row.Field<Type>("DataType"),
row.Field<int>("ColumnSize"));
}
}
private static void PrintSchemaAsXml(DataTable schemaTable)
{
StringWriter stringWriter = new StringWriter();
schemaTable.WriteXml(stringWriter);
Console.WriteLine(stringWriter.ToString());
}
}
Punti di interesse:
Per la mia tabella di prova l'output era:
ID, System.Int32, 4
Field1, System.String, 50
Field2, System.Int32, 4
Field3, System.DateTime, 8
--------------------------------------------------------------------------------
<DocumentElement>
<SchemaTable>
<ColumnName>ID</ColumnName>
<ColumnOrdinal>0</ColumnOrdinal>
<ColumnSize>4</ColumnSize>
<NumericPrecision>10</NumericPrecision>
<NumericScale>255</NumericScale>
<DataType>System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</DataType>
<ProviderType>3</ProviderType>
<IsLong>false</IsLong>
<AllowDBNull>true</AllowDBNull>
<IsReadOnly>false</IsReadOnly>
<IsRowVersion>false</IsRowVersion>
<IsUnique>false</IsUnique>
<IsKey>false</IsKey>
<IsAutoIncrement>false</IsAutoIncrement>
</SchemaTable>
[...]
</DocumentElement>
Non è 'rid.Close()' ridondante, poiché la connessione viene creata all'interno di un costrutto 'using', che chiuderà la connessione quando l'esecuzione esiste comunque il costrutto? –
per Microsoft SQL in C# è possibile effettuare le seguenti operazioni:
Dictionary<string, int> map =
(from DataRow row in Schema.Rows
let columnName = (string)row["ColumnName"]
select columnName)
.Distinct(StringComparer.InvariantCulture)
.Select((columnName, index) => new { Key = columnName, Value = index })
.ToDictionary(pair => pair.Key, pair => pair.Value);
crea così una mappa di nome della colonna nella sua indice che può essere utilizzato come segue:
internal sealed class ColumnToIndexMap
{
private const string NameOfColumn = "ColumnName";
private DataTable Schema { get; set; }
private Dictionary<string, int> Map { get; set; }
public ColumnToIndexMap(DataTable schema)
{
if (schema == null) throw new ArgumentNullException("schema");
Schema = schema;
Map = (from DataRow row in Schema.Rows
let columnName = (string)row[NameOfColumn]
select columnName)
.Distinct(StringComparer.InvariantCulture)
.Select((columnName, index) => new { Key = columnName, Value = index })
.ToDictionary(pair => pair.Key, pair => pair.Value);
}
int this[string name]
{
get { return Map[name]; }
}
string this[int index]
{
get { return Schema.Rows[index][NameOfColumn].ToString(); }
}
}
Ho avuto fortuna con la proprietà GetSchema di OleDb.Connection:
Una classe per fornire dati di colonna. Ciò restituisce TUTTE le colonne nel database. Il DataTable risultante può essere filtrato da nomi delle colonne che corrispondono (per lo più) a quelle che si trovano in un INFORMATION_SCHEMA standard (che MS Access non fornisce per noi):
class JetMetaData
{
/// <summary>
/// Returns a datatable containing MetaData for all user-columns
/// in the current JET Database.
/// </summary>
/// <returns></returns>
public static DataTable AllColumns(String ConnectionString)
{
DataTable dt;
using (OleDbConnection cn = new OleDbConnection(ConnectionString))
{
cn.Open();
dt = cn.GetSchema("Columns");
cn.Close();
}
return dt;
}
}
Quindi, consumando la classe in un piuttosto grezzo e non-così-elegante esempio, e filtraggio su TABLE_NAME:
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = JetMetaData.AllColumns("", Properties.Settings.Default.JetConnection);
String RowFilter = "TABLE_NAME = 'YourTableName'";
DataView drv = dt.DefaultView;
drv.RowFilter = RowFilter;
DataGridView dgv = this.dataGridView1;
dgv.DataSource = drv;
}
nota che io non pretendo che questo è tutto bene, anche se fuori il codice. È solo un esempio Ma ho usato qualcosa di simile in diverse occasioni, e in effetti ho persino creato un'applicazione per creare un intero database MS Access (contrappesi e tutto) usando metodi simili.
Mentre ho visto gli altri in questo thread menzionare lo schema get, sembra che alcune implementazioni siano eccessivamente complicate. . .
Spero che questo aiuti!
Questo codice stamperà tutti i nome di colonna di una tabella come classe con getter
proprietà di tutti i nomi delle colonne che può essere poi utilizzato in c#
codice
declare @TableName sysname = '<EnterTableName>'
declare @Result varchar(max) = 'public class ' + @TableName + '
{'
select @Result = @Result + '
public static string ' + ColumnName + ' { get { return "'+ColumnName+'"; } }
'
from
(
select
replace(col.name, ' ', '_') ColumnName,
column_id ColumnId
from sys.columns col
join sys.types typ on
col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
where object_id = object_id(@TableName)
) t
order by ColumnId
set @Result = @Result + '
}'
print @Result
uscita:
public class tblPracticeTestSections
{
public static string column1 { get { return "column1"; } }
public static string column2{ get { return "column2"; } }
public static string column3{ get { return "column3"; } }
public static string column4{ get { return "column4"; } }
}
mio la soluzione suggerita non è limitata ai database MS Access. – VVS