Wie kann ich die Feldnamen einer MS Access-Datenbanktabelle erhalten?Wie bekomme ich die Feldnamen einer Datenbanktabelle?
Gibt es eine SQL-Abfrage, die ich verwenden kann, oder gibt es dafür C# -Code?
Wie kann ich die Feldnamen einer MS Access-Datenbanktabelle erhalten?Wie bekomme ich die Feldnamen einer Datenbanktabelle?
Gibt es eine SQL-Abfrage, die ich verwenden kann, oder gibt es dafür C# -Code?
diese auf SQL Server arbeiten 2005 und up:
select * from INFORMATION_SCHEMA.COLUMNS
where TABLE_Name='YourTableName'
order by ORDINAL_POSITION
aber ich arbeite in Access, und im Zugriff ist es nicht Arbeit – Gold
@Gold, fügen Sie "Zugriff" Tag zu Frage! –
Dies funktioniert nicht im Zugriff. Können Sie erklären, was INFORMATION_SCHEMA ist? –
am Motor DB Je Ihr können Sie ganz einfach die DB Systemtabellen für diese
Für Zugriffsinformationen abfragen ich nicht die Antwort finden kann ich wissen Sie can see the sys tables beim Zugang und von dort können Sie versuchen, und zu bestimmen, wo diese Information ist aber ich bin nicht wirklich sicher, wie man diesen Teil macht. versucht, ein Beispiel zu verwenden, aber jetzt wo
MSysObjects enthält die Liste der Tabellen, es gibt leider keine Entsprechung für Felder. –
Fragen Sie, wie Sie die Spaltennamen einer Tabelle in einer Datenbank erhalten können?
Wenn ja, hängt es vollständig von dem Datenbankserver ab, den Sie verwenden.
In SQL 2005 Sie von der INFORMATION_SCHEMA.COLUMNS Ansicht auswählen können
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
IN SQL 2000 Sie SysObjects zu SysColumns beitreten können die Informationen zu erhalten
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'
Wie trifft Ihre Antwort auf Access/Jet zu? –
-1 Er fragt nach MS Access. –
Sorry, ich nehme meine -1 zurück, die ursprüngliche Frage war zu diesem Punkt nicht klar. –
diese Abfrage ausführen:
select top 1 *
From foo
und gehen Sie dann die Listenfelder (und zurückgegebene Werte) in der Ergebnismenge, um die Feldnamen zu erhalten.
Wenn alles, was Sie brauchen, ist Spalte * Namen * dann ist diese schnelle und dreckige Ansatz in Ordnung IMO. Beachten Sie, dass Sie WHERE 0 = 1 (oder ähnlich) hinzufügen können, um sicherzustellen, dass keine Daten zurückgegeben werden. – onedaywhen
Dies funktioniert nicht, wenn Sie Untertitel definiert haben. Es zeigt stattdessen die Beschriftung an. – jpmc26
Verwenden Sie die DAO-Automatisierungsklassen. Möglicherweise haben Sie bereits eine Interop-Bibliothek in Ihrer Visual Studio-Installation dafür. Wenn nicht, ist es einfach genug, eins zu erstellen. Fügen Sie einfach einen Verweis auf die DAO-COM-Bibliothek hinzu.
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();
Dies ist genauso einfach wie eine Systemtabelle Abfragen (die ich gefunden habe, in Access problematisch zu sein), und Sie können eine Menge von zusätzlichen Informationen auf diese Weise erhalten.
EDIT: ich den Code geändert haben von dem, was ich gestern geschrieben, was ich gerade von VB.NET übersetzt hatte, und die ein paar Stücke fehlte. Ich habe es neu geschrieben und getestet in C# in VS2008.
Von C# aus sind die ADO-Katalogfunktionen möglicherweise einfacher. –
IIRC die Aufrufe von OpenSchema, um die Informationen SCHEMA Ansichten sind nicht einfach für C# und möglicherweise nicht nur für Spaltennamen Wert. – onedaywhen
Verwenden IDataReader.GetSchemaTable()
Hier ist ein aktuelles Beispiel, das das Tabellenschema und druckt greift es schlicht und in XML (nur um zu sehen, welche Informationen Sie erhalten):
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());
}
}
Points of Interest:
Für meinen Test-Tabelle war die Ausgabe:
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>
Ist 'conn.Close()' nicht redundant, da die Verbindung innerhalb eines 'using'-Konstrukts erstellt wird, das die Verbindung schließt, wenn das Konstrukt trotzdem existiert? –
für Microsoft SQL in C# Sie folgendes tun:
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);
schafft so eine Karte von Spaltennamen in seine Index, der wie folgt verwendet werden kann:
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(); }
}
}
Ich hatte viel Glück mit der GetSchema-Eigenschaft der OleDb.Connection:
Eine Klasse, um Spaltendaten bereitzustellen. Dies gibt ALLE Spalten in der Datenbank zurück. Die sich ergebende Datentabelle kann dann durch Spaltennamen gefiltert werden, die (meist) entsprechen denen in einem Standard-INFORMATION_SCHEMA gefunden (die MS Access für uns nicht vorgesehen):
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;
}
}
Dann die Klasse Konsumieren in einem ziemlich grob und nicht so elegant Beispiel und Filterung auf 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;
}
Bitte beachte, dass ich behaupte nicht, dass dies alles gut, obwohl out-Code ist. Es ist nur ein Beispiel. Aber ich habe so etwas mehrmals benutzt und sogar eine Anwendung erstellt, um eine ganze MS Access Datenbank (Contraints und alle) mit ähnlichen Methoden zu erstellen.
Während ich gesehen habe andere in diesem Thread erwähnen das Schema, es scheint, dass einige der Implementierung übermäßig kompliziert war. . .
Hoffe, dass hilft!
Dieser Kodex wird alle Spaltennamen einer Tabelle als eine Klasse mit getter
Eigenschaft aller Spaltennamen drucken, die dann in c#
Code verwendet werden kann
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
Ausgang:
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"; } }
}
Meine Die vorgeschlagene Lösung ist nicht auf MS Access-Datenbanken beschränkt. – VVS