3

I want to know how to check if a specific column (e.g: date) exists in a specific table(e.g: myTable) in an Access database.

I've read this answer which offers a query which results in another query.

IF NOT EXISTS(SELECT * 
              FROM sys.columns 
              WHERE [name] = N'columnName' 
                AND [object_id] = OBJECT_ID(N'tableName'))
BEGIN
    ALTER TABLE ADD COLUMN MYCOLUMN
END

But what I need is a true/false result.

UPDATE 1

How can I do that in my C# application?

Maybe using SqlCommand.ExecuteScalar() or something else?

Community
  • 1
  • 1
Alex Jolig
  • 12,826
  • 19
  • 125
  • 158
  • @marc_s I get `Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'.` error using `ExecuteScalar` or `ExecuteNonQuery` – Alex Jolig Nov 21 '15 at 09:33
  • Here's an answer for determining if a table exists in Access from C#. Maybe it will point you in a more helpful direction than SQL Server code: http://stackoverflow.com/a/4793675/121544 – Shannon Severance Nov 21 '15 at 09:35
  • 1
    Yes, you didn't mention in your original question that this was for **MS Access** ........ `SqlCommand` and this T-SQL code only works for SQL Server ..... – marc_s Nov 21 '15 at 09:39

6 Answers6

3

As Andre451 mentions in his answer, you can use Access DAO to inspect the Fields collection of the relevant TableDef object, like this:

// test data
string dbFileSpec = @"C:\Users\Public\Database1.accdb";
string tblName = "Clients";
string colName = "LastName";

// COM reference required for project:
// Microsoft Office 14.0 Access Database Engine Object Library
//
var dbe = new Microsoft.Office.Interop.Access.Dao.DBEngine();
Microsoft.Office.Interop.Access.Dao.Database db = dbe.OpenDatabase(dbFileSpec);
Microsoft.Office.Interop.Access.Dao.TableDef tbd = db.TableDefs[tblName];
bool colExists = false;
foreach (Microsoft.Office.Interop.Access.Dao.Field fld in tbd.Fields)
{
    if (fld.Name.Equals(colName, StringComparison.InvariantCultureIgnoreCase))
    {
        colExists = true;
        break;
    }
}
db.Close();

Console.WriteLine("Column " + (colExists ? "exists" : "does not exist"));
Community
  • 1
  • 1
Gord Thompson
  • 107,466
  • 28
  • 191
  • 387
3

Thanks to everyone who offered a solution, gathering up some of the answers, I came up with my own version of solution. Maybe it's not the best solution around, but at least I don't need an extra dll to add to the references or deal with some stored procedures Access won't support.

OleDbConnection con = new OleDbConnection("my database address");
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT TOP 1 date FROM myTable";
con.Open();
bool exists = true;
try
{
  var x = cmd.ExecuteScalar();
}
catch (Exception e)
{
  exists = false;
}
con.Close();
Alex Jolig
  • 12,826
  • 19
  • 125
  • 158
2

Try this:

BEGIN

IF NOT EXISTS(SELECT * FROM sys.columns 
        WHERE [name] = N'columnName' AND [object_id] = OBJECT_ID(N'tableName'))
SELECT 0
ELSE
SELECT 1 
END

To use in c#:

SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "StoredProcedure3";
con.Open();
var x = cmd.ExecuteScalar();
MessageBox.Show(x.ToString());
con.Close();

To use without stored procedure:

SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "IF NOT EXISTS(SELECT * FROM sys.columns WHERE [name] = N'columnName' AND [object_id] = OBJECT_ID(N'tableName')) SELECT 0 ELSE SELECT 1 ";
con.Open();
var x = (int)cmd.ExecuteScalar();
MessageBox.Show(x.ToString());
con.Close();
marc_s
  • 704,970
  • 168
  • 1,303
  • 1,425
Salah Akbari
  • 38,126
  • 10
  • 70
  • 102
1

In Access VBA you could use the TableDef.Fields collection. Don't know if you can use these objects from c#.

Why don't you simply do (pseudocode)

columnExists = True
try
    ExecuteSql "SELECT TOP 1 [Date] FROM myTable"
catch
    // Error: column doesn't exist
    columnExists = False
Andre
  • 25,063
  • 6
  • 31
  • 72
  • 1
    programming by errors? why do i find this not acceptable – webs Jun 12 '20 at 12:20
  • If the alternative is a loop over all fields (since the fields collection does not have an .Exists method), I find it perfectly acceptable. – Andre Nov 20 '20 at 11:31
1

In case anyone requires this in the future, below is the method I use on my Access databases.

void CheckTableFields(OleDbConnection con)
{
    var table = "Company";
    var field = "Location";
    var sSQL = $"SELECT TOP 1 * FROM [{table}]";

    using (OleDbConnection con = new OleDbConnection("MsJetOledbConnectionString"))
    {
        con.Open();
        using (var cmd = new OleDbCommand(sSQL, con))
        {
            try
            {
                DataTable dtGen = new DataTable();
                dtGen.Load(cmd.ExecuteReader());

                System.Data.DataColumnCollection columns = dtGen.Columns;

                if (!columns.Contains(field))
                {
                    //Field NOT found - add new 'Location2' column
                    cmd.CommandText = $"ALTER TABLE [{table}] ADD COLUMN {field} TEXT(50)";
                    var result = cmd.ExecuteNonQuery();

                    WriteLine($"{DateTime.Now}:   Table Column {{{field}}} added successfully");
                }
                else
                {
                    WriteLine($"{DateTime.Now}:   Table Column {{{field}}}  already exists");
                }
            }
            catch (Exception ex)
            {
                WriteLine($"[DataService.CheckCompanyTableFields]  Error - {{{ex.Message}}}");
            }
        }
    }
}
PaulM8
  • 11
  • 3
  • Works perfectly except last line, I removed the false. ` WriteLine($"[DataService.CheckCompanyTableFields] Error - {{{ex.Message}}}", `false`); ` – Shane.A Apr 08 '22 at 04:08
0

Simple by:

select true

Complete Code:

IF NOT EXISTS(SELECT * FROM sys.columns 
        WHERE [name] = N'columnName' AND [object_id] = OBJECT_ID(N'tableName'))
    BEGIN
        select true
    END

ELSE

    BEGIN
        select false
    END
Shaharyar
  • 11,749
  • 4
  • 46
  • 62