5

I need to be able to determine from the DataTable returned by DbConnection.GetSchema() whether a particular column in a SQL Server table is identity/auto-increment or not. I cannot resort to querying the system tables directly.

Oddly, if I connect to SQL Server via ODBC, the returned datatype for such a column is returned as "int identity" (or "bigint identity", etc.) but if I use the native SQL Server driver, there appears to be no distinction between an "int" column and an "int identity" column. Is there some other way I can deduce that information?

Dan Hermann
  • 1,107
  • 1
  • 13
  • 27
  • It doesn't look like that piece of information is available in the GetSchema() collections. Why can't you query the system catalog views?? Those would definitely hold that information! – marc_s Jan 29 '11 at 07:54
  • I need a database-independent way of doing it. It appears that querying each individual table and examining the output of the DatabaseReader.GetSchemaTable() is the only reliable way of doing that. – Dan Hermann Jan 31 '11 at 15:56

3 Answers3

5

DataTable has Columns property and DataColumn has a property indicating auto-increment:

bool isAutoIncrement = dataTable.Columns[iCol].AutoIncrement
kelloti
  • 8,705
  • 5
  • 46
  • 82
  • He needs to get it from `GetSchema()` which returns a `DataTable` with *information* about the schema, not the schema itself. – Adam Robinson Jan 29 '11 at 02:01
  • Right, I guess the assumption is that making a small query of the table to get a `DataTable` with this information is a bad idea. But if it's really coming down to it, perhaps it's not a bad idea? – kelloti Jan 29 '11 at 02:05
5

See This StackOverflow thread

The GetSchema() function will not return the info that you want. Nor will examining the DataTable schema properties. You'll have to go to a lower level and that will depend on the DBMS and likely its version.

The member below retrieves all tables with identity columns and then looks to match a specific table passed as an argument. The code can be modified to either return all the tables or the query optimized to look only for the table of interest.

// see: https://stackoverflow.com/questions/87747/how-do-you-determine-what-sql-tables-have-an-identity-column-programatically
private static string GetIdentityColumnName(SqlConnection sqlConnection, Tuple<string, string> table)
{
    string columnName = string.Empty;

    const string commandString =
         "select TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS "
       + "where TABLE_SCHEMA = 'dbo' and COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 "
       + "order by TABLE_NAME";

    DataSet dataSet = new DataSet();
    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
    sqlDataAdapter.SelectCommand = new SqlCommand(commandString, sqlConnection);
    sqlDataAdapter.Fill(dataSet);

    if (dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0)
    {
        foreach (DataRow row in dataSet.Tables[0].Rows)
        {
            // compare name first
            if (string.Compare(table.Item2, row[1] as string, true) == 0)
            {
                // if the schema as specified, we need to match it, too
                if (string.IsNullOrWhiteSpace(table.Item1) || string.Compare(table.Item1, row[0] as string) == 0)
                {
                    columnName = row[2] as string;
                    break;
                }
            }
        }
    }
    return columnName;
}
Community
  • 1
  • 1
Scott Howard
  • 236
  • 5
  • 10
0

I have run into the same. As far as I discovered here "An auto increment column is implemented differently depending upon the type of database you are working with. It isn't exposed via GetOleDbSchema.".

I didn't find any other way than @kelloti mentioned. So at the moment I'm fine with this solution because at the moment I need to know if column is .AutoIncrement. I already have the table in memory so I don't need to query the database again.

@pesaak Please convert this answer into a comment now that you should have enough reputation.

Chad
  • 1,531
  • 3
  • 20
  • 46
pesaak
  • 131
  • 2
  • 10