private unsafe ArrayList GetPrimaryKeysBySQLStatistics (string catalog, string schema, string table)
{
ArrayList keys = new ArrayList ();
IntPtr handle = IntPtr.Zero;
OdbcReturn ret;
try {
ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt,
command.Connection.hDbc, ref handle);
if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
throw Connection.CreateOdbcException (
OdbcHandleType.Dbc, Connection.hDbc);
ret = libodbc.SQLStatistics (handle, catalog, -3,
schema, -3,
table, -3,
libodbc.SQL_INDEX_UNIQUE,
libodbc.SQL_QUICK);
if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
throw Connection.CreateOdbcException (OdbcHandleType.Stmt, handle);
// NON_UNIQUE
int nonUniqueLength = 0;
short nonUnique = libodbc.SQL_FALSE;
ret = libodbc.SQLBindCol (handle, 4, SQL_C_TYPE.SHORT, ref nonUnique, sizeof (short), ref nonUniqueLength);
if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
throw Connection.CreateOdbcException (OdbcHandleType.Stmt, handle);
// COLUMN_NAME
int length = 0;
byte [] colName = new byte [255];
ret = libodbc.SQLBindCol (handle, 9, SQL_C_TYPE.CHAR, colName, colName.Length, ref length);
if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
throw Connection.CreateOdbcException (OdbcHandleType.Stmt, handle);
while (true) {
ret = libodbc.SQLFetch (handle);
if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
break;
if (nonUnique == libodbc.SQL_TRUE) {
string pkey = Encoding.Default.GetString (colName, 0, length);
keys.Add (pkey);
break;
}
}
} finally {
if (handle != IntPtr.Zero) {
ret = libodbc.SQLFreeStmt (handle, libodbc.SQLFreeStmtOptions.Close);
if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
throw Connection.CreateOdbcException (OdbcHandleType.Stmt, handle);
ret = libodbc.SQLFreeHandle ((ushort) OdbcHandleType.Stmt, handle);
if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo))
throw Connection.CreateOdbcException (OdbcHandleType.Stmt, handle);
}
}
return keys;
}