#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

namespace Vanara.PInvoke;

public static partial class Odbc32
{
	public const int SQL_API_ALL_FUNCTIONS_SIZE = 100;
	public const int SQL_API_ODBC3_ALL_FUNCTIONS_SIZE = 250;
	private const int SIGNED_OFFSET = -20;    // SQL_SIGNED_OFFSET
	private const int UNSIGNED_OFFSET = -22;    // SQL_UNSIGNED_OFFSET

	[Flags]
	public enum SQL_AD : uint
	{
		SQL_AD_CONSTRAINT_NAME_DEFINITION = 0x00000001,
		SQL_AD_ADD_DOMAIN_CONSTRAINT = 0x00000002,
		SQL_AD_DROP_DOMAIN_CONSTRAINT = 0x00000004,
		SQL_AD_ADD_DOMAIN_DEFAULT = 0x00000008,
		SQL_AD_DROP_DOMAIN_DEFAULT = 0x00000010,
		SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020,
		SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040,
		SQL_AD_ADD_CONSTRAINT_DEFERRABLE = 0x00000080,
		SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE = 0x00000100
	}

	[Flags]
	public enum SQL_AF : uint
	{
		SQL_AF_AVG = 0x00000001,
		SQL_AF_COUNT = 0x00000002,
		SQL_AF_MAX = 0x00000004,
		SQL_AF_MIN = 0x00000008,
		SQL_AF_SUM = 0x00000010,
		SQL_AF_DISTINCT = 0x00000020,
		SQL_AF_ALL = 0x00000040
	}

	public enum SQL_AM : uint
	{
		SQL_AM_NONE = 0,
		SQL_AM_CONNECTION = 1,
		SQL_AM_STATEMENT = 2,
	}

	[PInvokeData("sql.h")]
	public enum SQL_API
	{
		SQL_API_ODBC3_ALL_FUNCTIONS = 999,
		SQL_API_ALL_FUNCTIONS = 0,
		SQL_API_SQLALLOCCONNECT = 1,
		SQL_API_SQLALLOCENV = 2,
		SQL_API_SQLALLOCHANDLE = 1001,
		SQL_API_SQLALLOCSTMT = 3,
		SQL_API_SQLBINDCOL = 4,
		SQL_API_SQLBINDPARAM = 1002,
		SQL_API_SQLCANCEL = 5,
		SQL_API_SQLCLOSECURSOR = 1003,
		SQL_API_SQLCOLATTRIBUTE = 6,
		SQL_API_SQLCOLUMNS = 40,
		SQL_API_SQLCONNECT = 7,
		SQL_API_SQLCOPYDESC = 1004,
		SQL_API_SQLDATASOURCES = 57,
		SQL_API_SQLDESCRIBECOL = 8,
		SQL_API_SQLDISCONNECT = 9,
		SQL_API_SQLENDTRAN = 1005,
		SQL_API_SQLERROR = 10,
		SQL_API_SQLEXECDIRECT = 11,
		SQL_API_SQLEXECUTE = 12,
		SQL_API_SQLFETCH = 13,
		SQL_API_SQLFETCHSCROLL = 1021,
		SQL_API_SQLFREECONNECT = 14,
		SQL_API_SQLFREEENV = 15,
		SQL_API_SQLFREEHANDLE = 1006,
		SQL_API_SQLFREESTMT = 16,
		SQL_API_SQLGETCONNECTATTR = 1007,
		SQL_API_SQLGETCONNECTOPTION = 42,
		SQL_API_SQLGETCURSORNAME = 17,
		SQL_API_SQLGETDATA = 43,
		SQL_API_SQLGETDESCFIELD = 1008,
		SQL_API_SQLGETDESCREC = 1009,
		SQL_API_SQLGETDIAGFIELD = 1010,
		SQL_API_SQLGETDIAGREC = 1011,
		SQL_API_SQLGETENVATTR = 1012,
		SQL_API_SQLGETFUNCTIONS = 44,
		SQL_API_SQLGETINFO = 45,
		SQL_API_SQLGETSTMTATTR = 1014,
		SQL_API_SQLGETSTMTOPTION = 46,
		SQL_API_SQLGETTYPEINFO = 47,
		SQL_API_SQLNUMRESULTCOLS = 18,
		SQL_API_SQLPARAMDATA = 48,
		SQL_API_SQLPREPARE = 19,
		SQL_API_SQLPUTDATA = 49,
		SQL_API_SQLROWCOUNT = 20,
		SQL_API_SQLSETCONNECTATTR = 1016,
		SQL_API_SQLSETCONNECTOPTION = 50,
		SQL_API_SQLSETCURSORNAME = 21,
		SQL_API_SQLSETDESCFIELD = 1017,
		SQL_API_SQLSETDESCREC = 1018,
		SQL_API_SQLSETENVATTR = 1019,
		SQL_API_SQLSETPARAM = 22,
		SQL_API_SQLSETSTMTATTR = 1020,
		SQL_API_SQLSETSTMTOPTION = 51,
		SQL_API_SQLSPECIALCOLUMNS = 52,
		SQL_API_SQLSTATISTICS = 53,
		SQL_API_SQLTABLES = 54,
		SQL_API_SQLTRANSACT = 23,
		SQL_API_SQLCANCELHANDLE = 1550,
		SQL_API_SQLCOMPLETEASYNC = 1551,
	}

	// possible values for SQL_ASYNC_DBC_FUNCTIONS
	public enum SQL_ASYNC_DBC : uint
	{
		SQL_ASYNC_DBC_NOT_CAPABLE = 0x00000000,
		SQL_ASYNC_DBC_CAPABLE = 0x00000001
	}

	// Possible values for SQL_ASYNC_NOTIFICATION
	public enum SQL_ASYNC_NOTIFICATION : uint
	{
		SQL_ASYNC_NOTIFICATION_NOT_CAPABLE = 0x00000000,
		SQL_ASYNC_NOTIFICATION_CAPABLE = 0x00000001
	}

	[PInvokeData("sqlext.h")]
	[Flags]
	public enum SQL_AT
	{
		SQL_AT_ADD_COLUMN = 0x00000001,
		SQL_AT_DROP_COLUMN = 0x00000002,
		SQL_AT_ADD_CONSTRAINT = 0x00000008,
		SQL_AT_ADD_COLUMN_SINGLE = 0x00000020,
		SQL_AT_ADD_COLUMN_DEFAULT = 0x00000040,
		SQL_AT_ADD_COLUMN_COLLATION = 0x00000080,
		SQL_AT_SET_COLUMN_DEFAULT = 0x00000100,
		SQL_AT_DROP_COLUMN_DEFAULT = 0x00000200,
		SQL_AT_DROP_COLUMN_CASCADE = 0x00000400,
		SQL_AT_DROP_COLUMN_RESTRICT = 0x00000800,
		SQL_AT_ADD_TABLE_CONSTRAINT = 0x00001000,
		SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE = 0x00002000,
		SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT = 0x00004000,
		SQL_AT_CONSTRAINT_NAME_DEFINITION = 0x00008000,
		SQL_AT_CONSTRAINT_INITIALLY_DEFERRED = 0x00010000,
		SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00020000,
		SQL_AT_CONSTRAINT_DEFERRABLE = 0x00040000,
		SQL_AT_CONSTRAINT_NON_DEFERRABLE = 0x00080000,
	}

	[PInvokeData("sql.h")]
	public enum SQL_ATTR
	{
		[CorrespondingType(typeof(SQL_BOOL))]
		SQL_ATTR_OUTPUT_NTS = 10001,

		SQL_ATTR_AUTO_IPD = 10001,
		SQL_ATTR_APP_ROW_DESC = 10010,              // (ODBC 3.0)
		SQL_ATTR_APP_PARAM_DESC = 10011,              // (ODBC 3.0)
		SQL_ATTR_IMP_ROW_DESC = 10012,              // (ODBC 3.0)
		SQL_ATTR_IMP_PARAM_DESC = 10013,              // (ODBC 3.0)
		SQL_ATTR_METADATA_ID = 10014,              // (ODBC 3.0)

		SQL_ATTR_ACCESS_MODE = 101,
		SQL_ATTR_AUTOCOMMIT = 102,
		SQL_ATTR_CONNECTION_TIMEOUT = 113,
		SQL_ATTR_CURRENT_CATALOG = 109,
		SQL_ATTR_DISCONNECT_BEHAVIOR = 114,
		SQL_ATTR_ENLIST_IN_DTC = 1207,
		SQL_ATTR_ENLIST_IN_XA = 1208,
		SQL_ATTR_LOGIN_TIMEOUT = 103,
		SQL_ATTR_ODBC_CURSORS = 110,
		SQL_ATTR_PACKET_SIZE = 112,
		SQL_ATTR_QUIET_MODE = 111,
		SQL_ATTR_TRACE = 104,
		SQL_ATTR_TRACEFILE = 105,
		SQL_ATTR_TRANSLATE_LIB = 106,
		SQL_ATTR_TRANSLATE_OPTION = 107,
		SQL_ATTR_TXN_ISOLATION = 108,
		SQL_ATTR_CONNECTION_DEAD = 1209,
		SQL_ATTR_ANSI_APP = 115,
		SQL_ATTR_RESET_CONNECTION = 116,
		SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE = 117,
		SQL_ATTR_ASYNC_DBC_EVENT = 119,

		SQL_ATTR_ASYNC_ENABLE = 4,
		SQL_ATTR_CONCURRENCY = 7,
		SQL_ATTR_CURSOR_TYPE = 6,
		SQL_ATTR_ENABLE_AUTO_IPD = 15,
		SQL_ATTR_FETCH_BOOKMARK_PTR = 16,
		SQL_ATTR_KEYSET_SIZE = 8,
		SQL_ATTR_MAX_LENGTH = 3,
		SQL_ATTR_MAX_ROWS = 1,
		SQL_ATTR_NOSCAN = 2,
		SQL_ATTR_PARAM_BIND_OFFSET_PTR = 17,
		SQL_ATTR_PARAM_BIND_TYPE = 18,
		SQL_ATTR_PARAM_OPERATION_PTR = 19,
		SQL_ATTR_PARAM_STATUS_PTR = 20,
		SQL_ATTR_PARAMS_PROCESSED_PTR = 21,
		SQL_ATTR_PARAMSET_SIZE = 22,
		SQL_ATTR_QUERY_TIMEOUT = 0,
		SQL_ATTR_RETRIEVE_DATA = 11,
		SQL_ATTR_ROW_BIND_OFFSET_PTR = 23,
		SQL_ATTR_ROW_BIND_TYPE = 5,
		SQL_ATTR_ROW_NUMBER = 14,
		SQL_ATTR_ROW_OPERATION_PTR = 24,
		SQL_ATTR_ROW_STATUS_PTR = 25,
		SQL_ATTR_ROWS_FETCHED_PTR = 26,
		SQL_ATTR_ROW_ARRAY_SIZE = 27,
		SQL_ATTR_SIMULATE_CURSOR = 10,
		SQL_ATTR_USE_BOOKMARKS = 12,
		SQL_ATTR_ASYNC_STMT_EVENT = 29,

		[CorrespondingType(typeof(SQL_OV))]
		SQL_ATTR_ODBC_VERSION = 200,

		[CorrespondingType(typeof(SQL_CP))]
		SQL_ATTR_CONNECTION_POOLING = 201,

		[CorrespondingType(typeof(SQL_CP_MATCH))]
		SQL_ATTR_CP_MATCH = 202,

		SQL_ATTR_APPLICATION_KEY = 203,

		// from sqlncli.h
		SQL_COPT_SS_BASE = 1200,

		SQL_COPT_SS_ENLIST_IN_DTC = SQL_COPT_SS_BASE + 7,
		SQL_COPT_SS_TXN_ISOLATION = SQL_COPT_SS_BASE + 27, // Used to set/get any driver-specific or ODBC-defined TXN iso level
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_BOOL
	{
		SQL_FALSE = 0,
		SQL_TRUE = 1,
	}

	[Flags]
	public enum SQL_BP : uint
	{
		SQL_BP_CLOSE = 0x00000001,
		SQL_BP_DELETE = 0x00000002,
		SQL_BP_DROP = 0x00000004,
		SQL_BP_TRANSACTION = 0x00000008,
		SQL_BP_UPDATE = 0x00000010,
		SQL_BP_OTHER_HSTMT = 0x00000020,
		SQL_BP_SCROLL = 0x00000040
	}

	[Flags]
	public enum SQL_BRC : uint
	{
		SQL_BRC_PROCEDURES = 0x0000001,
		SQL_BRC_EXPLICIT = 0x0000002,
		SQL_BRC_ROLLED_UP = 0x0000004
	}

	[Flags]
	public enum SQL_BS : uint
	{
		SQL_BS_SELECT_EXPLICIT = 0x00000001,
		SQL_BS_ROW_COUNT_EXPLICIT = 0x00000002,
		SQL_BS_SELECT_PROC = 0x00000004,
		SQL_BS_ROW_COUNT_PROC = 0x00000008
	}

	public enum SQL_C : short
	{
		[CorrespondingType(typeof(string), EncodingType = typeof(ASCIIEncoding))]
		SQL_C_CHAR = 1,                     //SQL_C_CHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(UnicodeEncoding))]
		SQL_C_WCHAR = -8,                     //SQL_C_WCHAR

		[CorrespondingType(typeof(int))]
		SQL_C_SLONG = 4 + SIGNED_OFFSET,     //SQL_C_LONG+SQL_SIGNED_OFFSET

		[CorrespondingType(typeof(uint))]
		SQL_C_ULONG = 4 + UNSIGNED_OFFSET,   //SQL_C_LONG+SQL_UNSIGNED_OFFSET

		[CorrespondingType(typeof(short))]
		SQL_C_SSHORT = 5 + SIGNED_OFFSET,     //SQL_C_SSHORT+SQL_SIGNED_OFFSET

		[CorrespondingType(typeof(short))]
		SQL_C_USHORT = 5 + UNSIGNED_OFFSET,   //SQL_C_USHORT+SQL_UNSIGNED_OFFSET

		[CorrespondingType(typeof(Single))]
		SQL_C_REAL = 7,                     //SQL_C_REAL

		[CorrespondingType(typeof(double))]
		SQL_C_DOUBLE = 8,                     //SQL_C_DOUBLE

		[CorrespondingType(typeof(bool))]
		SQL_C_BIT = -7,                     //SQL_C_BIT

		[CorrespondingType(typeof(sbyte))]
		SQL_C_STINYINT = -6 + SIGNED_OFFSET,     //SQL_C_STINYINT+SQL_SIGNED_OFFSET

		[CorrespondingType(typeof(byte))]
		SQL_C_UTINYINT = -6 + UNSIGNED_OFFSET,   //SQL_C_UTINYINT+SQL_UNSIGNED_OFFSET

		[CorrespondingType(typeof(long))]
		SQL_C_SBIGINT = -5 + SIGNED_OFFSET,     //SQL_C_SBIGINT+SQL_SIGNED_OFFSET

		[CorrespondingType(typeof(ulong))]
		SQL_C_UBIGINT = -5 + UNSIGNED_OFFSET,   //SQL_C_UBIGINT+SQL_UNSIGNED_OFFSET

		[CorrespondingType(typeof(byte[]))]
		SQL_C_BINARY = -2,                     //SQL_C_BINARY

		[CorrespondingType(typeof(byte[]))]
		SQL_C_TIMESTAMP = 11,                     //SQL_C_TIMESTAMP

		[CorrespondingType(typeof(DateTime))]
		SQL_C_TYPE_DATE = 91,                     //SQL_C_TYPE_DATE

		[CorrespondingType(typeof(TimeSpan))]
		SQL_C_TYPE_TIME = 92,                     //SQL_C_TYPE_TIME

		[CorrespondingType(typeof(TIMESTAMP_STRUCT))]
		SQL_C_TYPE_TIMESTAMP = 93,                     //SQL_C_TYPE_TIMESTAMP

		[CorrespondingType(typeof(decimal))]
		SQL_C_NUMERIC = 2,                     //SQL_C_NUMERIC

		[CorrespondingType(typeof(Guid))]
		SQL_C_GUID = -11,                    //SQL_C_GUID

		SQL_C_DEFAULT = 99,                     //SQL_C_DEFAULT
		SQL_C_ARD_TYPE = -99,                    //SQL_ARD_TYPE
	}

	[Flags]
	public enum SQL_CA : uint
	{
		SQL_CA_CREATE_ASSERTION = 0x00000001,
		SQL_CA_CONSTRAINT_INITIALLY_DEFERRED = 0x00000010,
		SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000020,
		SQL_CA_CONSTRAINT_DEFERRABLE = 0x00000040,
		SQL_CA_CONSTRAINT_NON_DEFERRABLE = 0x00000080
	}

	[Flags]
	public enum SQL_CA1 : uint
	{
		SQL_CA1_NEXT = 0x00000001,
		SQL_CA1_ABSOLUTE = 0x00000002,
		SQL_CA1_RELATIVE = 0x00000004,
		SQL_CA1_BOOKMARK = 0x00000008,
		SQL_CA1_LOCK_NO_CHANGE = 0x00000040,
		SQL_CA1_LOCK_EXCLUSIVE = 0x00000080,
		SQL_CA1_LOCK_UNLOCK = 0x00000100,
		SQL_CA1_POS_POSITION = 0x00000200,
		SQL_CA1_POS_UPDATE = 0x00000400,
		SQL_CA1_POS_DELETE = 0x00000800,
		SQL_CA1_POS_REFRESH = 0x00001000,
		SQL_CA1_POSITIONED_UPDATE = 0x00002000,
		SQL_CA1_POSITIONED_DELETE = 0x00004000,
		SQL_CA1_SELECT_FOR_UPDATE = 0x00008000,
		SQL_CA1_BULK_ADD = 0x00010000,
		SQL_CA1_BULK_UPDATE_BY_BOOKMARK = 0x00020000,
		SQL_CA1_BULK_DELETE_BY_BOOKMARK = 0x00040000,
		SQL_CA1_BULK_FETCH_BY_BOOKMARK = 0x00080000
	}

	[Flags]
	public enum SQL_CA2 : uint
	{
		SQL_CA2_READ_ONLY_CONCURRENCY = 0x00000001,
		SQL_CA2_LOCK_CONCURRENCY = 0x00000002,
		SQL_CA2_OPT_ROWVER_CONCURRENCY = 0x00000004,
		SQL_CA2_OPT_VALUES_CONCURRENCY = 0x00000008,
		SQL_CA2_SENSITIVITY_ADDITIONS = 0x00000010,
		SQL_CA2_SENSITIVITY_DELETIONS = 0x00000020,
		SQL_CA2_SENSITIVITY_UPDATES = 0x00000040,
		SQL_CA2_MAX_ROWS_SELECT = 0x00000080,
		SQL_CA2_MAX_ROWS_INSERT = 0x00000100,
		SQL_CA2_MAX_ROWS_DELETE = 0x00000200,
		SQL_CA2_MAX_ROWS_UPDATE = 0x00000400,
		SQL_CA2_MAX_ROWS_CATALOG = 0x00000800,
		SQL_CA2_MAX_ROWS_AFFECTS_ALL = SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG,
		SQL_CA2_CRC_EXACT = 0x00001000,
		SQL_CA2_CRC_APPROXIMATE = 0x00002000,
		SQL_CA2_SIMULATE_NON_UNIQUE = 0x00004000,
		SQL_CA2_SIMULATE_TRY_UNIQUE = 0x00008000,
		SQL_CA2_SIMULATE_UNIQUE = 0x00010000
	}

	public enum SQL_CB : uint
	{
		SQL_CB_NULL = 0x0000,
		SQL_CB_NON_NULL = 0x0001
	}

	public enum SQL_CCB : uint
	{
		SQL_CB_DELETE = 0,
		SQL_CB_CLOSE = 1,
		SQL_CB_PRESERVE = 2,
	}

	[Flags]
	public enum SQL_CCOL : uint
	{
		SQL_CCOL_CREATE_COLLATION = 0x00000001
	}

	[Flags]
	public enum SQL_CCS : uint
	{
		SQL_CCS_CREATE_CHARACTER_SET = 0x00000001,
		SQL_CCS_COLLATE_CLAUSE = 0x00000002,
		SQL_CCS
	}

	[Flags]
	public enum SQL_CDO : uint
	{
		SQL_CDO_CREATE_DOMAIN = 0x00000001,
		SQL_CDO_DEFAULT = 0x00000002,
		SQL_CDO_CONSTRAINT = 0x00000004,
		SQL_CDO_COLLATION = 0x00000008,
		SQL_CDO_CONSTRAINT_NAME_DEFINITION = 0x00000010,
		SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020,
		SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040,
		SQL_CDO_CONSTRAINT_DEFERRABLE = 0x00000080,
		SQL_CDO_CONSTRAINT_NON_DEFERRABLE = 0x00000100
	}

	public enum SQL_CL : uint
	{
		SQL_CL_START = SQL_QL.SQL_QL_START,
		SQL_CL_END = SQL_QL.SQL_QL_END
	}

	public enum SQL_CN : uint
	{
		SQL_CN_NONE = 0x0000,
		SQL_CN_DIFFERENT = 0x0001,
		SQL_CN_ANY = 0x0002
	}

	/// <summary>Column types and scopes in SQLSpecialColumns.</summary>
	public enum SQL_COLID : short
	{
		SQL_BEST_ROWID = 1,
		SQL_ROWVER = 2
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_COLUMN
	{
		SQL_COLUMN_COUNT = 0,
		SQL_COLUMN_NAME = 1,
		SQL_COLUMN_TYPE = 2,
		SQL_COLUMN_LENGTH = 3,
		SQL_COLUMN_PRECISION = 4,
		SQL_COLUMN_SCALE = 5,
		SQL_COLUMN_DISPLAY_SIZE = 6,
		SQL_COLUMN_NULLABLE = 7,
		SQL_COLUMN_UNSIGNED = 8,
		SQL_COLUMN_MONEY = 9,
		SQL_COLUMN_UPDATABLE = 10,
		SQL_COLUMN_AUTO_INCREMENT = 11,
		SQL_COLUMN_CASE_SENSITIVE = 12,
		SQL_COLUMN_SEARCHABLE = 13,
		SQL_COLUMN_TYPE_NAME = 14,
		SQL_COLUMN_TABLE_NAME = 15,
		SQL_COLUMN_OWNER_NAME = 16,
		SQL_COLUMN_QUALIFIER_NAME = 17,
		SQL_COLUMN_LABEL = 18,
		SQL_COLATT_OPT_MAX = SQL_COLUMN_LABEL,
		SQL_COLUMN_DRIVER_START = 1000,
	}

	[PInvokeData("sql.h")]
	public enum SQL_COMMIT : short
	{
		SQL_COMMIT = 0,
		SQL_ROLLBACK = 1,
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_CP
	{
		SQL_CP_OFF = 0,
		SQL_CP_ONE_PER_DRIVER = 1,
		SQL_CP_ONE_PER_HENV = 2,
		SQL_CP_DRIVER_AWARE = 3,
		SQL_CP_DEFAULT = SQL_CP_OFF,
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_CP_MATCH
	{
		SQL_CP_STRICT_MATCH = 0,
		SQL_CP_RELAXED_MATCH = 1,
		SQL_CP_MATCH_DEFAULT = SQL_CP_STRICT_MATCH
	}

	[Flags]
	public enum SQL_CS : uint
	{
		SQL_CS_CREATE_SCHEMA = 0x00000001,
		SQL_CS_AUTHORIZATION = 0x00000002,
		SQL_CS_DEFAULT_CHARACTER_SET = 0x00000004
	}

	[Flags]
	public enum SQL_CT : uint
	{
		SQL_CT_CREATE_TABLE = 0x00000001,
		SQL_CT_COMMIT_PRESERVE = 0x00000002,
		SQL_CT_COMMIT_DELETE = 0x00000004,
		SQL_CT_GLOBAL_TEMPORARY = 0x00000008,
		SQL_CT_LOCAL_TEMPORARY = 0x00000010,
		SQL_CT_CONSTRAINT_INITIALLY_DEFERRED = 0x00000020,
		SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE = 0x00000040,
		SQL_CT_CONSTRAINT_DEFERRABLE = 0x00000080,
		SQL_CT_CONSTRAINT_NON_DEFERRABLE = 0x00000100,
		SQL_CT_COLUMN_CONSTRAINT = 0x00000200,
		SQL_CT_COLUMN_DEFAULT = 0x00000400,
		SQL_CT_COLUMN_COLLATION = 0x00000800,
		SQL_CT_TABLE_CONSTRAINT = 0x00001000,
		SQL_CT_CONSTRAINT_NAME_DEFINITION = 0x00002000
	}

	[Flags]
	public enum SQL_CTR : uint
	{
		SQL_CTR_CREATE_TRANSLATION = 0x00000001
	}

	[Flags]
	public enum SQL_CU : uint
	{
		SQL_CU_DML_STATEMENTS = SQL_QU.SQL_QU_DML_STATEMENTS,
		SQL_CU_PROCEDURE_INVOCATION = SQL_QU.SQL_QU_PROCEDURE_INVOCATION,
		SQL_CU_TABLE_DEFINITION = SQL_QU.SQL_QU_TABLE_DEFINITION,
		SQL_CU_INDEX_DEFINITION = SQL_QU.SQL_QU_INDEX_DEFINITION,
		SQL_CU_PRIVILEGE_DEFINITION = SQL_QU.SQL_QU_PRIVILEGE_DEFINITION
	}

	public enum SQL_CURSOR : uint
	{
		SQL_UNSPECIFIED = 0,
		SQL_INSENSITIVE = 1,
		SQL_SENSITIVE = 2
	}

	[Flags]
	public enum SQL_CV : uint
	{
		SQL_CV_CREATE_VIEW = 0x00000001,
		SQL_CV_CHECK_OPTION = 0x00000002,
		SQL_CV_CASCADED = 0x00000004,
		SQL_CV_LOCAL = 0x00000008
	}

	[PInvokeData("sqlext.h")]
	[Flags]
	public enum SQL_CVT : uint
	{
		SQL_CVT_CHAR = 0x00000001,
		SQL_CVT_NUMERIC = 0x00000002,
		SQL_CVT_DECIMAL = 0x00000004,
		SQL_CVT_INTEGER = 0x00000008,
		SQL_CVT_SMALLINT = 0x00000010,
		SQL_CVT_FLOAT = 0x00000020,
		SQL_CVT_REAL = 0x00000040,
		SQL_CVT_DOUBLE = 0x00000080,
		SQL_CVT_VARCHAR = 0x00000100,
		SQL_CVT_LONGVARCHAR = 0x00000200,
		SQL_CVT_BINARY = 0x00000400,
		SQL_CVT_VARBINARY = 0x00000800,
		SQL_CVT_BIT = 0x00001000,
		SQL_CVT_TINYINT = 0x00002000,
		SQL_CVT_BIGINT = 0x00004000,
		SQL_CVT_DATE = 0x00008000,
		SQL_CVT_TIME = 0x00010000,
		SQL_CVT_TIMESTAMP = 0x00020000,
		SQL_CVT_LONGVARBINARY = 0x00040000,
		SQL_CVT_INTERVAL_YEAR_MONTH = 0x00080000,
		SQL_CVT_INTERVAL_DAY_TIME = 0x00100000,
		SQL_CVT_WCHAR = 0x00200000,
		SQL_CVT_WLONGVARCHAR = 0x00400000,
		SQL_CVT_WVARCHAR = 0x00800000,
		SQL_CVT_GUID = 0x01000000,
	}

	[Flags]
	public enum SQL_DA : uint
	{
		SQL_DA_DROP_ASSERTION = 0x00000001
	}

	[Flags]
	public enum SQL_DC : uint
	{
		SQL_DC_DROP_COLLATION = 0x00000001
	}

	[Flags]
	public enum SQL_DCS : uint
	{
		SQL_DCS_DROP_CHARACTER_SET = 0x00000001
	}

	[Flags]
	public enum SQL_DD : uint
	{
		SQL_DD_DROP_DOMAIN = 0x00000001,
		SQL_DD_RESTRICT = 0x00000002,
		SQL_DD_CASCADE = 0x00000004
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_DESC : short
	{
		SQL_DESC_COUNT = 1001,
		SQL_DESC_TYPE = 1002,
		SQL_DESC_LENGTH = 1003,
		SQL_DESC_OCTET_LENGTH_PTR = 1004,
		SQL_DESC_PRECISION = 1005,
		SQL_DESC_SCALE = 1006,
		SQL_DESC_DATETIME_INTERVAL_CODE = 1007,
		SQL_DESC_NULLABLE = 1008,
		SQL_DESC_INDICATOR_PTR = 1009,
		SQL_DESC_DATA_PTR = 1010,
		SQL_DESC_NAME = 1011,
		SQL_DESC_UNNAMED = 1012,
		SQL_DESC_OCTET_LENGTH = 1013,
		SQL_DESC_ALLOC_TYPE = 1099,
		SQL_DESC_ARRAY_SIZE = 20,
		SQL_DESC_ARRAY_STATUS_PTR = 21,
		SQL_DESC_AUTO_UNIQUE_VALUE = SQL_COLUMN.SQL_COLUMN_AUTO_INCREMENT,
		SQL_DESC_BASE_COLUMN_NAME = 22,
		SQL_DESC_BASE_TABLE_NAME = 23,
		SQL_DESC_BIND_OFFSET_PTR = 24,
		SQL_DESC_BIND_TYPE = 25,
		SQL_DESC_CASE_SENSITIVE = SQL_COLUMN.SQL_COLUMN_CASE_SENSITIVE,
		SQL_DESC_CATALOG_NAME = SQL_COLUMN.SQL_COLUMN_QUALIFIER_NAME,
		SQL_DESC_CONCISE_TYPE = SQL_COLUMN.SQL_COLUMN_TYPE,
		SQL_DESC_DATETIME_INTERVAL_PRECISION = 26,
		SQL_DESC_DISPLAY_SIZE = SQL_COLUMN.SQL_COLUMN_DISPLAY_SIZE,
		SQL_DESC_FIXED_PREC_SCALE = SQL_COLUMN.SQL_COLUMN_MONEY,
		SQL_DESC_LABEL = SQL_COLUMN.SQL_COLUMN_LABEL,
		SQL_DESC_LITERAL_PREFIX = 27,
		SQL_DESC_LITERAL_SUFFIX = 28,
		SQL_DESC_LOCAL_TYPE_NAME = 29,
		SQL_DESC_MAXIMUM_SCALE = 30,
		SQL_DESC_MINIMUM_SCALE = 31,
		SQL_DESC_NUM_PREC_RADIX = 32,
		SQL_DESC_PARAMETER_TYPE = 33,
		SQL_DESC_ROWS_PROCESSED_PTR = 34,
		SQL_DESC_ROWVER = 35,
		SQL_DESC_SCHEMA_NAME = SQL_COLUMN.SQL_COLUMN_OWNER_NAME,
		SQL_DESC_SEARCHABLE = SQL_COLUMN.SQL_COLUMN_SEARCHABLE,
		SQL_DESC_TYPE_NAME = SQL_COLUMN.SQL_COLUMN_TYPE_NAME,
		SQL_DESC_TABLE_NAME = SQL_COLUMN.SQL_COLUMN_TABLE_NAME,
		SQL_DESC_UNSIGNED = SQL_COLUMN.SQL_COLUMN_UNSIGNED,
		SQL_DESC_UPDATABLE = SQL_COLUMN.SQL_COLUMN_UPDATABLE,
	}

	[Flags]
	public enum SQL_DI : uint
	{
		SQL_DI_CREATE_INDEX = 0x00000001,
		SQL_DI_DROP_INDEX = 0x00000002
	}

	[PInvokeData("sql.h")]
	public enum SQL_DIAG_ID : short
	{
		[CorrespondingType(typeof(string))]
		SQL_DIAG_CLASS_ORIGIN = 8,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_CONNECTION_NAME = 10,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_DYNAMIC_FUNCTION = 7,

		[CorrespondingType(typeof(SQL_FCODE))]
		SQL_DIAG_DYNAMIC_FUNCTION_CODE = 12,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_MESSAGE_TEXT = 6,

		[CorrespondingType(typeof(int))]
		SQL_DIAG_NATIVE = 5,

		[CorrespondingType(typeof(int))]
		SQL_DIAG_NUMBER = 2,

		[CorrespondingType(typeof(SQLRETURN))]
		SQL_DIAG_RETURNCODE = 1,

		[CorrespondingType(typeof(nuint))]
		SQL_DIAG_ROW_COUNT = 3,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_SERVER_NAME = 11,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_SQLSTATE = 4,

		[CorrespondingType(typeof(string))]
		SQL_DIAG_SUBCLASS_ORIGIN = 9,

		SQL_DIAG_CURSOR_ROW_COUNT = -1249,

		[CorrespondingType(typeof(nuint))]
		SQL_DIAG_ROW_NUMBER = -1248,

		[CorrespondingType(typeof(nuint))]
		SQL_DIAG_COLUMN_NUMBER = -1247,
	}

	[Flags]
	public enum SQL_DL : uint
	{
		SQL_DL_SQL92_DATE = 0x00000001,
		SQL_DL_SQL92_TIME = 0x00000002,
		SQL_DL_SQL92_TIMESTAMP = 0x00000004,
		SQL_DL_SQL92_INTERVAL_YEAR = 0x00000008,
		SQL_DL_SQL92_INTERVAL_MONTH = 0x00000010,
		SQL_DL_SQL92_INTERVAL_DAY = 0x00000020,
		SQL_DL_SQL92_INTERVAL_HOUR = 0x00000040,
		SQL_DL_SQL92_INTERVAL_MINUTE = 0x00000080,
		SQL_DL_SQL92_INTERVAL_SECOND = 0x00000100,
		SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH = 0x00000200,
		SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR = 0x00000400,
		SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE = 0x00000800,
		SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND = 0x00001000,
		SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE = 0x00002000,
		SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND = 0x00004000,
		SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND = 0x00008000,
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_DRIVER
	{
		SQL_DRIVER_NOPROMPT = 0,
		SQL_DRIVER_COMPLETE = 1,
		SQL_DRIVER_PROMPT = 2,
		SQL_DRIVER_COMPLETE_REQUIRED = 3,
	}

	public enum SQL_DRIVER_AWARE_POOLING : uint
	{
		SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE = 0x00000000,
		SQL_DRIVER_AWARE_POOLING_CAPABLE = 0x00000001
	}

	[Flags]
	public enum SQL_DS : uint
	{
		SQL_DS_DROP_SCHEMA = 0x00000001,
		SQL_DS_RESTRICT = 0x00000002,
		SQL_DS_CASCADE = 0x00000004
	}

	[Flags]
	public enum SQL_DT : uint
	{
		SQL_DT_DROP_TABLE = 0x00000001,
		SQL_DT_RESTRICT = 0x00000002,
		SQL_DT_CASCADE = 0x00000004
	}

	[Flags]
	public enum SQL_DTC : uint
	{
		SQL_DTC_ENLIST_EXPENSIVE = 0x00000001,
		SQL_DTC_UNENLIST_EXPENSIVE = 0x00000002
	}

	[Flags]
	public enum SQL_DTR : uint
	{
		SQL_DTR_DROP_TRANSLATION = 0x00000001
	}

	[Flags]
	public enum SQL_DV : uint
	{
		SQL_DV_DROP_VIEW = 0x00000001,
		SQL_DV_RESTRICT = 0x00000002,
		SQL_DV_CASCADE = 0x00000004
	}

	[PInvokeData("sql.h")]
	public enum SQL_FCODE
	{
		SQL_DIAG_ALTER_DOMAIN = 3,
		SQL_DIAG_ALTER_TABLE = 4,
		SQL_DIAG_CALL = 7,
		SQL_DIAG_CREATE_ASSERTION = 6,
		SQL_DIAG_CREATE_CHARACTER_SET = 8,
		SQL_DIAG_CREATE_COLLATION = 10,
		SQL_DIAG_CREATE_DOMAIN = 23,
		SQL_DIAG_CREATE_INDEX = -1,
		SQL_DIAG_CREATE_SCHEMA = 64,
		SQL_DIAG_CREATE_TABLE = 77,
		SQL_DIAG_CREATE_TRANSLATION = 79,
		SQL_DIAG_CREATE_VIEW = 84,
		SQL_DIAG_DELETE_WHERE = 19,
		SQL_DIAG_DROP_ASSERTION = 24,
		SQL_DIAG_DROP_CHARACTER_SET = 25,
		SQL_DIAG_DROP_COLLATION = 26,
		SQL_DIAG_DROP_DOMAIN = 27,
		SQL_DIAG_DROP_INDEX = -2,
		SQL_DIAG_DROP_SCHEMA = 31,
		SQL_DIAG_DROP_TABLE = 32,
		SQL_DIAG_DROP_TRANSLATION = 33,
		SQL_DIAG_DROP_VIEW = 36,
		SQL_DIAG_DYNAMIC_DELETE_CURSOR = 38,
		SQL_DIAG_DYNAMIC_UPDATE_CURSOR = 81,
		SQL_DIAG_GRANT = 48,
		SQL_DIAG_INSERT = 50,
		SQL_DIAG_REVOKE = 59,
		SQL_DIAG_SELECT_CURSOR = 85,
		SQL_DIAG_UNKNOWN_STATEMENT = 0,
		SQL_DIAG_UPDATE_WHERE = 82,
	}

	[Flags]
	public enum SQL_FD : uint
	{
		SQL_FD_FETCH_NEXT = 0x00000001,
		SQL_FD_FETCH_FIRST = 0x00000002,
		SQL_FD_FETCH_LAST = 0x00000004,
		SQL_FD_FETCH_PRIOR = 0x00000008,
		SQL_FD_FETCH_ABSOLUTE = 0x00000010,
		SQL_FD_FETCH_RELATIVE = 0x00000020,
	}

	[PInvokeData("sql.h")]
	public enum SQL_FETCH
	{
		SQL_FETCH_NEXT = 1,
		SQL_FETCH_FIRST = 2,
	}

	[PInvokeData("sql.h")]
	public enum SQL_FETCH_DIRECTION : short
	{
		SQL_FETCH_NEXT = 1,
		SQL_FETCH_FIRST = 2,
		SQL_FETCH_LAST = 3,
		SQL_FETCH_PRIOR = 4,
		SQL_FETCH_ABSOLUTE = 5,
		SQL_FETCH_RELATIVE = 6,
	}

	public enum SQL_FILE : uint
	{
		SQL_FILE_NOT_SUPPORTED = 0x0000,
		SQL_FILE_TABLE = 0x0001,
		SQL_FILE_QUALIFIER = 0x0002,
		SQL_FILE_CATALOG = SQL_FILE_QUALIFIER
	}

	[PInvokeData("sqlext.h")]
	[Flags]
	public enum SQL_FN_CVT : uint
	{
		SQL_FN_CVT_CONVERT = 0x00000001,
		SQL_FN_CVT_CAST = 0x00000002
	}

	[Flags]
	public enum SQL_FN_NUM : uint
	{
		SQL_FN_NUM_ABS = 0x00000001,
		SQL_FN_NUM_ACOS = 0x00000002,
		SQL_FN_NUM_ASIN = 0x00000004,
		SQL_FN_NUM_ATAN = 0x00000008,
		SQL_FN_NUM_ATAN2 = 0x00000010,
		SQL_FN_NUM_CEILING = 0x00000020,
		SQL_FN_NUM_COS = 0x00000040,
		SQL_FN_NUM_COT = 0x00000080,
		SQL_FN_NUM_EXP = 0x00000100,
		SQL_FN_NUM_FLOOR = 0x00000200,
		SQL_FN_NUM_LOG = 0x00000400,
		SQL_FN_NUM_MOD = 0x00000800,
		SQL_FN_NUM_SIGN = 0x00001000,
		SQL_FN_NUM_SIN = 0x00002000,
		SQL_FN_NUM_SQRT = 0x00004000,
		SQL_FN_NUM_TAN = 0x00008000,
		SQL_FN_NUM_PI = 0x00010000,
		SQL_FN_NUM_RAND = 0x00020000,
		SQL_FN_NUM_DEGREES = 0x00040000,
		SQL_FN_NUM_LOG10 = 0x00080000,
		SQL_FN_NUM_POWER = 0x00100000,
		SQL_FN_NUM_RADIANS = 0x00200000,
		SQL_FN_NUM_ROUND = 0x00400000,
		SQL_FN_NUM_TRUNCATE = 0x00800000
	}

	[Flags]
	public enum SQL_FN_STR : uint
	{
		SQL_FN_STR_CONCAT = 0x00000001,
		SQL_FN_STR_INSERT = 0x00000002,
		SQL_FN_STR_LEFT = 0x00000004,
		SQL_FN_STR_LTRIM = 0x00000008,
		SQL_FN_STR_LENGTH = 0x00000010,
		SQL_FN_STR_LOCATE = 0x00000020,
		SQL_FN_STR_LCASE = 0x00000040,
		SQL_FN_STR_REPEAT = 0x00000080,
		SQL_FN_STR_REPLACE = 0x00000100,
		SQL_FN_STR_RIGHT = 0x00000200,
		SQL_FN_STR_RTRIM = 0x00000400,
		SQL_FN_STR_SUBSTRING = 0x00000800,
		SQL_FN_STR_UCASE = 0x00001000,
		SQL_FN_STR_ASCII = 0x00002000,
		SQL_FN_STR_CHAR = 0x00004000,
		SQL_FN_STR_DIFFERENCE = 0x00008000,
		SQL_FN_STR_LOCATE_2 = 0x00010000,
		SQL_FN_STR_SOUNDEX = 0x00020000,
		SQL_FN_STR_SPACE = 0x00040000,
		SQL_FN_STR_BIT_LENGTH = 0x00080000,
		SQL_FN_STR_CHAR_LENGTH = 0x00100000,
		SQL_FN_STR_CHARACTER_LENGTH = 0x00200000,
		SQL_FN_STR_OCTET_LENGTH = 0x00400000,
		SQL_FN_STR_POSITION = 0x00800000
	}

	[Flags]
	public enum SQL_FN_SYS : uint
	{
		SQL_FN_SYS_USERNAME = 0x00000001,
		SQL_FN_SYS_DBNAME = 0x00000002,
		SQL_FN_SYS_IFNULL = 0x00000004
	}

	[Flags]
	public enum SQL_FN_TD : uint
	{
		SQL_FN_TD_NOW = 0x00000001,
		SQL_FN_TD_CURDATE = 0x00000002,
		SQL_FN_TD_DAYOFMONTH = 0x00000004,
		SQL_FN_TD_DAYOFWEEK = 0x00000008,
		SQL_FN_TD_DAYOFYEAR = 0x00000010,
		SQL_FN_TD_MONTH = 0x00000020,
		SQL_FN_TD_QUARTER = 0x00000040,
		SQL_FN_TD_WEEK = 0x00000080,
		SQL_FN_TD_YEAR = 0x00000100,
		SQL_FN_TD_CURTIME = 0x00000200,
		SQL_FN_TD_HOUR = 0x00000400,
		SQL_FN_TD_MINUTE = 0x00000800,
		SQL_FN_TD_SECOND = 0x00001000,
		SQL_FN_TD_TIMESTAMPADD = 0x00002000,
		SQL_FN_TD_TIMESTAMPDIFF = 0x00004000,
		SQL_FN_TD_DAYNAME = 0x00008000,
		SQL_FN_TD_MONTHNAME = 0x00010000,
		SQL_FN_TD_CURRENT_DATE = 0x00020000,
		SQL_FN_TD_CURRENT_TIME = 0x00040000,
		SQL_FN_TD_CURRENT_TIMESTAMP = 0x00080000,
		SQL_FN_TD_EXTRACT = 0x00100000
	}

	[Flags]
	public enum SQL_FN_TSI : uint
	{
		SQL_FN_TSI_FRAC_SECOND = 0x00000001,
		SQL_FN_TSI_SECOND = 0x00000002,
		SQL_FN_TSI_MINUTE = 0x00000004,
		SQL_FN_TSI_HOUR = 0x00000008,
		SQL_FN_TSI_DAY = 0x00000010,
		SQL_FN_TSI_WEEK = 0x00000020,
		SQL_FN_TSI_MONTH = 0x00000040,
		SQL_FN_TSI_QUARTER = 0x00000080,
		SQL_FN_TSI_YEAR = 0x00000100
	}

	public enum SQL_GB : uint
	{
		SQL_GB_NOT_SUPPORTED = 0x0000,
		SQL_GB_GROUP_BY_EQUALS_SELECT = 0x0001,
		SQL_GB_GROUP_BY_CONTAINS_SELECT = 0x0002,
		SQL_GB_NO_RELATION = 0x0003,
		SQL_GB_COLLATE = 0x0004
	}

	[Flags]
	public enum SQL_GD : uint
	{
		SQL_GD_ANY_COLUMN = 0x00000001,
		SQL_GD_ANY_ORDER = 0x00000002,
		SQL_GD_BLOCK = 0x00000004,
		SQL_GD_BOUND = 0x00000008,
		SQL_GD_OUTPUT_PARAMS = 0x00000010
	}

	public enum SQL_HANDLE : short
	{
		SQL_HANDLE_ENV = 1,
		SQL_HANDLE_DBC = 2,
		SQL_HANDLE_STMT = 3,
		SQL_HANDLE_DESC = 4,
		SQL_HANDLE_DBC_INFO_TOKEN = 6,
	}

	public enum SQL_IC : uint
	{
		SQL_IC_UPPER = 1,
		SQL_IC_LOWER = 2,
		SQL_IC_SENSITIVE = 3,
		SQL_IC_MIXED = 4,
	}

	[Flags]
	public enum SQL_IK : uint
	{
		SQL_IK_NONE = 0x00000000,
		SQL_IK_ASC = 0x00000001,
		SQL_IK_DESC = 0x00000002,
		SQL_IK_ALL = SQL_IK_ASC | SQL_IK_DESC
	}

	/// <summary>Reserved values for UNIQUE argument of SQLStatistics()</summary>
	public enum SQL_INDEX
	{
		SQL_INDEX_UNIQUE = 0,
		SQL_INDEX_ALL = 1
	}

	/// <summary>Values that may appear in the result set of SQLStatistics()</summary>
	public enum SQL_INDEX_TYPE
	{
		SQL_TABLE_STAT = 0,
		SQL_INDEX_CLUSTERED = 1,
		SQL_INDEX_HASHED = 2,
		SQL_INDEX_OTHER = 3
	}

	public enum SQL_INFO : uint
	{
		[CorrespondingType(typeof(string))]
		SQL_ACCESSIBLE_PROCEDURES = 20,

		[CorrespondingType(typeof(string))]
		SQL_ACCESSIBLE_TABLES = 19,

		[CorrespondingType(typeof(ushort))]
		SQL_ACTIVE_CONNECTIONS = 0,

		[CorrespondingType(typeof(ushort))]
		SQL_ACTIVE_ENVIRONMENTS = SQL_MAX_DRIVER_CONNECTIONS,

		[CorrespondingType(typeof(ushort))]
		SQL_ACTIVE_STATEMENTS = SQL_MAX_CONCURRENT_ACTIVITIES,

		[CorrespondingType(typeof(SQL_AF))]
		SQL_AGGREGATE_FUNCTIONS = 169,

		[CorrespondingType(typeof(SQL_AD))]
		SQL_ALTER_DOMAIN = 117,

		[CorrespondingType(typeof(SQL_AT))]
		SQL_ALTER_TABLE = 86,

		[CorrespondingType(typeof(SQL_ASYNC_DBC))]
		SQL_ASYNC_DBC_FUNCTIONS = 10023,

		[CorrespondingType(typeof(SQL_AM))]
		SQL_ASYNC_MODE = 10021,

		[CorrespondingType(typeof(SQL_ASYNC_NOTIFICATION))]
		SQL_ASYNC_NOTIFICATION = 10025,

		[CorrespondingType(typeof(SQL_BRC))]
		SQL_BATCH_ROW_COUNT = 120,

		[CorrespondingType(typeof(SQL_BS))]
		SQL_BATCH_SUPPORT = 121,

		[CorrespondingType(typeof(SQL_BP))]
		SQL_BOOKMARK_PERSISTENCE = 82,

		[CorrespondingType(typeof(SQL_CL))]
		SQL_CATALOG_LOCATION = SQL_QUALIFIER_LOCATION,

		[CorrespondingType(typeof(string))]
		SQL_CATALOG_NAME = 10003,

		[CorrespondingType(typeof(string))]
		SQL_CATALOG_NAME_SEPARATOR = SQL_QUALIFIER_NAME_SEPARATOR,

		[CorrespondingType(typeof(string))]
		SQL_CATALOG_TERM = SQL_QUALIFIER_TERM,

		[CorrespondingType(typeof(SQL_CU))]
		SQL_CATALOG_USAGE = SQL_QUALIFIER_USAGE,

		[CorrespondingType(typeof(string))]
		SQL_COLLATION_SEQ = 10004,

		[CorrespondingType(typeof(string))]
		SQL_COLUMN_ALIAS = 87,

		[CorrespondingType(typeof(SQL_CB))]
		SQL_CONCAT_NULL_BEHAVIOR = 22,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_BIGINT = 53,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_BINARY = 54,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_BIT = 55,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_CHAR = 56,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_DATE = 57,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_DECIMAL = 58,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_DOUBLE = 59,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_FLOAT = 60,

		[CorrespondingType(typeof(SQL_FN_CVT))]
		SQL_CONVERT_FUNCTIONS = 48,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_GUID = 173,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_INTEGER = 61,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_INTERVAL_DAY_TIME = 123,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_INTERVAL_YEAR_MONTH = 124,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_LONGVARBINARY = 71,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_LONGVARCHAR = 62,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_NUMERIC = 63,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_REAL = 64,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_SMALLINT = 65,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_TIME = 66,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_TIMESTAMP = 67,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_TINYINT = 68,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_VARBINARY = 69,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_VARCHAR = 70,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_WCHAR = 122,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_WLONGVARCHAR = 125,

		[CorrespondingType(typeof(SQL_CVT))]
		SQL_CONVERT_WVARCHAR = 126,

		[CorrespondingType(typeof(SQL_CN))]
		SQL_CORRELATION_NAME = 74,

		[CorrespondingType(typeof(SQL_CA))]
		SQL_CREATE_ASSERTION = 127,

		[CorrespondingType(typeof(SQL_CCS))]
		SQL_CREATE_CHARACTER_SET = 128,

		[CorrespondingType(typeof(SQL_CCOL))]
		SQL_CREATE_COLLATION = 129,

		[CorrespondingType(typeof(SQL_CDO))]
		SQL_CREATE_DOMAIN = 130,

		[CorrespondingType(typeof(SQL_CS))]
		SQL_CREATE_SCHEMA = 131,

		[CorrespondingType(typeof(SQL_CT))]
		SQL_CREATE_TABLE = 132,

		[CorrespondingType(typeof(SQL_CTR))]
		SQL_CREATE_TRANSLATION = 133,

		[CorrespondingType(typeof(SQL_CV))]
		SQL_CREATE_VIEW = 134,

		[CorrespondingType(typeof(SQL_CCB))]
		SQL_CURSOR_COMMIT_BEHAVIOR = 23,

		[CorrespondingType(typeof(SQL_CCB))]
		SQL_CURSOR_ROLLBACK_BEHAVIOR = 24,

		[CorrespondingType(typeof(SQL_CURSOR))]
		SQL_CURSOR_SENSITIVITY = 10001,

		[CorrespondingType(typeof(string))]
		SQL_DATA_SOURCE_NAME = 2,

		[CorrespondingType(typeof(string))]
		SQL_DATA_SOURCE_READ_ONLY = 25,

		[CorrespondingType(typeof(string))]
		SQL_DATABASE_NAME = 16,

		[CorrespondingType(typeof(SQL_DL))]
		SQL_DATETIME_LITERALS = 119,

		[CorrespondingType(typeof(string))]
		SQL_DBMS_NAME = 17,

		[CorrespondingType(typeof(string))]
		SQL_DBMS_VER = 18,

		[CorrespondingType(typeof(SQL_DI))]
		SQL_DDL_INDEX = 170,

		[CorrespondingType(typeof(SQL_TXN))]
		SQL_DEFAULT_TXN_ISOLATION = 26,

		[CorrespondingType(typeof(string))]
		SQL_DESCRIBE_PARAMETER = 10002,

		[CorrespondingType(typeof(string))]
		SQL_DM_VER = 171,

		[CorrespondingType(typeof(SQL_DRIVER_AWARE_POOLING))]
		SQL_DRIVER_AWARE_POOLING_SUPPORTED = 10024,

		[CorrespondingType(typeof(nuint))]
		SQL_DRIVER_HDBC = 3,

		[CorrespondingType(typeof(nuint))]
		SQL_DRIVER_HDESC = 135,

		[CorrespondingType(typeof(nuint))]
		SQL_DRIVER_HENV = 4,

		[CorrespondingType(typeof(nuint))]
		SQL_DRIVER_HLIB = 76,

		[CorrespondingType(typeof(nuint))]
		SQL_DRIVER_HSTMT = 5,

		[CorrespondingType(typeof(string))]
		SQL_DRIVER_NAME = 6,

		[CorrespondingType(typeof(string))]
		SQL_DRIVER_ODBC_VER = 77,

		[CorrespondingType(typeof(string))]
		SQL_DRIVER_VER = 7,

		[CorrespondingType(typeof(SQL_DA))]
		SQL_DROP_ASSERTION = 136,

		[CorrespondingType(typeof(SQL_DCS))]
		SQL_DROP_CHARACTER_SET = 137,

		[CorrespondingType(typeof(SQL_DC))]
		SQL_DROP_COLLATION = 138,

		[CorrespondingType(typeof(SQL_DD))]
		SQL_DROP_DOMAIN = 139,

		[CorrespondingType(typeof(SQL_DS))]
		SQL_DROP_SCHEMA = 140,

		[CorrespondingType(typeof(SQL_DT))]
		SQL_DROP_TABLE = 141,

		[CorrespondingType(typeof(SQL_DTR))]
		SQL_DROP_TRANSLATION = 142,

		[CorrespondingType(typeof(SQL_DV))]
		SQL_DROP_VIEW = 143,

		[CorrespondingType(typeof(SQL_CA1))]
		SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144,

		[CorrespondingType(typeof(SQL_CA2))]
		SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145,

		[CorrespondingType(typeof(string))]
		SQL_EXPRESSIONS_IN_ORDERBY = 27,

		//[CorrespondingType(typeof())]
		//SQL_FETCH_DIRECTION = 8,
		[CorrespondingType(typeof(SQL_FILE))]
		SQL_FILE_USAGE = 84,

		[CorrespondingType(typeof(SQL_CA1))]
		SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146,

		[CorrespondingType(typeof(SQL_CA2))]
		SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147,

		[CorrespondingType(typeof(SQL_GD))]
		SQL_GETDATA_EXTENSIONS = 81,

		[CorrespondingType(typeof(SQL_GB))]
		SQL_GROUP_BY = 88,

		[CorrespondingType(typeof(SQL_IC))]
		SQL_IDENTIFIER_CASE = 28,

		[CorrespondingType(typeof(string))]
		SQL_IDENTIFIER_QUOTE_CHAR = 29,

		[CorrespondingType(typeof(SQL_IK))]
		SQL_INDEX_KEYWORDS = 148,

		//[CorrespondingType(typeof())]
		//SQL_INFO_FIRST = 0,
		[CorrespondingType(typeof(SQL_ISV))]
		SQL_INFO_SCHEMA_VIEWS = 149,

		[CorrespondingType(typeof(SQL_IS))]
		SQL_INSERT_STATEMENT = 172,

		[CorrespondingType(typeof(string))]
		SQL_INTEGRITY = 73,

		[CorrespondingType(typeof(SQL_CA1))]
		SQL_KEYSET_CURSOR_ATTRIBUTES1 = 150,

		[CorrespondingType(typeof(SQL_CA2))]
		SQL_KEYSET_CURSOR_ATTRIBUTES2 = 151,

		[CorrespondingType(typeof(string))]
		SQL_KEYWORDS = 89,

		[CorrespondingType(typeof(string))]
		SQL_LIKE_ESCAPE_CLAUSE = 113,

		//[CorrespondingType(typeof())]
		//SQL_LOCK_TYPES = 78,
		[CorrespondingType(typeof(uint))]
		SQL_MAX_ASYNC_CONCURRENT_STATEMENTS = 10022,

		[CorrespondingType(typeof(uint))]
		SQL_MAX_BINARY_LITERAL_LEN = 112,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_CATALOG_NAME_LEN = 34,

		[CorrespondingType(typeof(uint))]
		SQL_MAX_CHAR_LITERAL_LEN = 108,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMN_NAME_LEN = 30,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMNS_IN_GROUP_BY = 97,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMNS_IN_INDEX = 98,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMNS_IN_ORDER_BY = 99,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMNS_IN_SELECT = 100,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_COLUMNS_IN_TABLE = 101,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_CONCURRENT_ACTIVITIES = 1,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_CURSOR_NAME_LEN = 31,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_DRIVER_CONNECTIONS = 0,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_IDENTIFIER_LEN = 10005,

		[CorrespondingType(typeof(uint))]
		SQL_MAX_INDEX_SIZE = 102,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_OWNER_NAME_LEN = 32,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_PROCEDURE_NAME_LEN = 33,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_QUALIFIER_NAME_LEN = 34,

		[CorrespondingType(typeof(uint))]
		SQL_MAX_ROW_SIZE = 104,

		[CorrespondingType(typeof(string))]
		SQL_MAX_ROW_SIZE_INCLUDES_LONG = 103,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_SCHEMA_NAME_LEN = 32,

		[CorrespondingType(typeof(uint))]
		SQL_MAX_STATEMENT_LEN = 105,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_TABLE_NAME_LEN = 35,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_TABLES_IN_SELECT = 106,

		[CorrespondingType(typeof(ushort))]
		SQL_MAX_USER_NAME_LEN = 107,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_CATALOG_NAME_LENGTH = SQL_MAX_CATALOG_NAME_LEN,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_COLUMN_NAME_LENGTH = SQL_MAX_COLUMN_NAME_LEN,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_COLUMNS_IN_GROUP_BY = SQL_MAX_COLUMNS_IN_GROUP_BY,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_COLUMNS_IN_INDEX = SQL_MAX_COLUMNS_IN_INDEX,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_COLUMNS_IN_ORDER_BY = SQL_MAX_COLUMNS_IN_ORDER_BY,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_COLUMNS_IN_SELECT = SQL_MAX_COLUMNS_IN_SELECT,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_CONCURRENT_ACTIVITIES = SQL_MAX_CONCURRENT_ACTIVITIES,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_CURSOR_NAME_LENGTH = SQL_MAX_CURSOR_NAME_LEN,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_DRIVER_CONNECTIONS = SQL_MAX_DRIVER_CONNECTIONS,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_IDENTIFIER_LENGTH = SQL_MAX_IDENTIFIER_LEN,

		[CorrespondingType(typeof(uint))]
		SQL_MAXIMUM_INDEX_SIZE = SQL_MAX_INDEX_SIZE,

		[CorrespondingType(typeof(uint))]
		SQL_MAXIMUM_ROW_SIZE = SQL_MAX_ROW_SIZE,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_SCHEMA_NAME_LENGTH = SQL_MAX_SCHEMA_NAME_LEN,

		[CorrespondingType(typeof(uint))]
		SQL_MAXIMUM_STATEMENT_LENGTH = SQL_MAX_STATEMENT_LEN,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_TABLES_IN_SELECT = SQL_MAX_TABLES_IN_SELECT,

		[CorrespondingType(typeof(ushort))]
		SQL_MAXIMUM_USER_NAME_LENGTH = SQL_MAX_USER_NAME_LEN,

		[CorrespondingType(typeof(string))]
		SQL_MULT_RESULT_SETS = 36,

		[CorrespondingType(typeof(string))]
		SQL_MULTIPLE_ACTIVE_TXN = 37,

		[CorrespondingType(typeof(string))]
		SQL_NEED_LONG_DATA_LEN = 111,

		[CorrespondingType(typeof(SQL_NNC))]
		SQL_NON_NULLABLE_COLUMNS = 75,

		[CorrespondingType(typeof(SQL_NC))]
		SQL_NULL_COLLATION = 85,

		[CorrespondingType(typeof(SQL_FN_NUM))]
		SQL_NUMERIC_FUNCTIONS = 49,

		[CorrespondingType(typeof(SQL_OAC))]
		SQL_ODBC_API_CONFORMANCE = 9,

		[CorrespondingType(typeof(SQL_OIC))]
		SQL_ODBC_INTERFACE_CONFORMANCE = 152,

		SQL_ODBC_SAG_CLI_CONFORMANCE = 12,
		SQL_ODBC_SQL_CONFORMANCE = 15,
		SQL_ODBC_SQL_OPT_IEF = 73,

		[CorrespondingType(typeof(string))]
		SQL_ODBC_VER = 10,

		[CorrespondingType(typeof(SQL_OJ))]
		SQL_OJ_CAPABILITIES = 115,

		[CorrespondingType(typeof(string))]
		SQL_ORDER_BY_COLUMNS_IN_SELECT = 90,

		[CorrespondingType(typeof(SQL_OJ))]
		SQL_OUTER_JOIN_CAPABILITIES = SQL_OJ_CAPABILITIES,

		[CorrespondingType(typeof(string))]
		SQL_OUTER_JOINS = 38,

		[CorrespondingType(typeof(string))]
		SQL_OWNER_TERM = 39,

		[CorrespondingType(typeof(SQL_SU))]
		SQL_OWNER_USAGE = 91,

		[CorrespondingType(typeof(SQL_PARC))]
		SQL_PARAM_ARRAY_ROW_COUNTS = 153,

		[CorrespondingType(typeof(SQL_PAS))]
		SQL_PARAM_ARRAY_SELECTS = 154,

		[CorrespondingType(typeof(SQL_POS))]
		SQL_POS_OPERATIONS = 79,

		[CorrespondingType(typeof(SQL_PS))]
		SQL_POSITIONED_STATEMENTS = 80,

		[CorrespondingType(typeof(string))]
		SQL_PROCEDURE_TERM = 40,

		[CorrespondingType(typeof(string))]
		SQL_PROCEDURES = 21,

		[CorrespondingType(typeof(SQL_IC))]
		SQL_QUALIFIER_LOCATION = 114,

		[CorrespondingType(typeof(string))]
		SQL_QUALIFIER_NAME_SEPARATOR = 41,

		[CorrespondingType(typeof(string))]
		SQL_QUALIFIER_TERM = 42,

		[CorrespondingType(typeof(SQL_CU))]
		SQL_QUALIFIER_USAGE = 92,

		[CorrespondingType(typeof(SQL_IC))]
		SQL_QUOTED_IDENTIFIER_CASE = 93,

		[CorrespondingType(typeof(string))]
		SQL_ROW_UPDATES = 11,

		[CorrespondingType(typeof(string))]
		SQL_SCHEMA_TERM = SQL_OWNER_TERM,

		[CorrespondingType(typeof(SQL_SU))]
		SQL_SCHEMA_USAGE = SQL_OWNER_USAGE,

		[CorrespondingType(typeof(SQL_SCCO))]
		SQL_SCROLL_CONCURRENCY = 43,

		[CorrespondingType(typeof(SQL_SO))]
		SQL_SCROLL_OPTIONS = 44,

		[CorrespondingType(typeof(string))]
		SQL_SEARCH_PATTERN_ESCAPE = 14,

		[CorrespondingType(typeof(string))]
		SQL_SERVER_NAME = 13,

		[CorrespondingType(typeof(string))]
		SQL_SPECIAL_CHARACTERS = 94,

		[CorrespondingType(typeof(SQL_SC))]
		SQL_SQL_CONFORMANCE = 118,

		[CorrespondingType(typeof(SQL_SDF))]
		SQL_SQL92_DATETIME_FUNCTIONS = 155,

		[CorrespondingType(typeof(SQL_SFKD))]
		SQL_SQL92_FOREIGN_KEY_DELETE_RULE = 156,

		[CorrespondingType(typeof(SQL_SFKU))]
		SQL_SQL92_FOREIGN_KEY_UPDATE_RULE = 157,

		[CorrespondingType(typeof(SQL_SG))]
		SQL_SQL92_GRANT = 158,

		[CorrespondingType(typeof(SQL_SNVF))]
		SQL_SQL92_NUMERIC_VALUE_FUNCTIONS = 159,

		[CorrespondingType(typeof(SQL_SP))]
		SQL_SQL92_PREDICATES = 160,

		[CorrespondingType(typeof(SQL_SRJO))]
		SQL_SQL92_RELATIONAL_JOIN_OPERATORS = 161,

		[CorrespondingType(typeof(SQL_SR))]
		SQL_SQL92_REVOKE = 162,

		[CorrespondingType(typeof(SQL_SR))]
		SQL_SQL92_ROW_VALUE_CONSTRUCTOR = 163,

		[CorrespondingType(typeof(SQL_SSF))]
		SQL_SQL92_STRING_FUNCTIONS = 164,

		[CorrespondingType(typeof(SQL_SVE))]
		SQL_SQL92_VALUE_EXPRESSIONS = 165,

		[CorrespondingType(typeof(SQL_SCC))]
		SQL_STANDARD_CLI_CONFORMANCE = 166,

		[CorrespondingType(typeof(SQL_CA1))]
		SQL_STATIC_CURSOR_ATTRIBUTES1 = 167,

		[CorrespondingType(typeof(SQL_CA2))]
		SQL_STATIC_CURSOR_ATTRIBUTES2 = 168,

		//SQL_STATIC_SENSITIVITY = 83,
		[CorrespondingType(typeof(SQL_FN_STR))]
		SQL_STRING_FUNCTIONS = 50,

		[CorrespondingType(typeof(SQL_SQ))]
		SQL_SUBQUERIES = 95,

		[CorrespondingType(typeof(SQL_FN_SYS))]
		SQL_SYSTEM_FUNCTIONS = 51,

		[CorrespondingType(typeof(string))]
		SQL_TABLE_TERM = 45,

		[CorrespondingType(typeof(SQL_FN_TSI))]
		SQL_TIMEDATE_ADD_INTERVALS = 109,

		[CorrespondingType(typeof(SQL_FN_TSI))]
		SQL_TIMEDATE_DIFF_INTERVALS = 110,

		[CorrespondingType(typeof(SQL_FN_TD))]
		SQL_TIMEDATE_FUNCTIONS = 52,

		[CorrespondingType(typeof(SQL_TC))]
		SQL_TRANSACTION_CAPABLE = SQL_TXN_CAPABLE,

		[CorrespondingType(typeof(SQL_TXN))]
		SQL_TRANSACTION_ISOLATION_OPTION = SQL_TXN_ISOLATION_OPTION,

		[CorrespondingType(typeof(SQL_TC))]
		SQL_TXN_CAPABLE = 46,

		[CorrespondingType(typeof(SQL_TXN))]
		SQL_TXN_ISOLATION_OPTION = 72,

		[CorrespondingType(typeof(SQL_U))]
		SQL_UNION = 96,

		[CorrespondingType(typeof(SQL_U))]
		SQL_UNION_STATEMENT = SQL_UNION,

		[CorrespondingType(typeof(string))]
		SQL_USER_NAME = 47,

		[CorrespondingType(typeof(string))]
		SQL_XOPEN_CLI_YEAR = 10000,
	}

	[Flags]
	public enum SQL_IS : uint
	{
		SQL_IS_INSERT_LITERALS = 0x00000001,
		SQL_IS_INSERT_SEARCHED = 0x00000002,
		SQL_IS_SELECT_INTO = 0x00000004
	}

	[Flags]
	public enum SQL_ISV : uint
	{
		SQL_ISV_ASSERTIONS = 0x00000001,
		SQL_ISV_CHARACTER_SETS = 0x00000002,
		SQL_ISV_CHECK_CONSTRAINTS = 0x00000004,
		SQL_ISV_COLLATIONS = 0x00000008,
		SQL_ISV_COLUMN_DOMAIN_USAGE = 0x00000010,
		SQL_ISV_COLUMN_PRIVILEGES = 0x00000020,
		SQL_ISV_COLUMNS = 0x00000040,
		SQL_ISV_CONSTRAINT_COLUMN_USAGE = 0x00000080,
		SQL_ISV_CONSTRAINT_TABLE_USAGE = 0x00000100,
		SQL_ISV_DOMAIN_CONSTRAINTS = 0x00000200,
		SQL_ISV_DOMAINS = 0x00000400,
		SQL_ISV_KEY_COLUMN_USAGE = 0x00000800,
		SQL_ISV_REFERENTIAL_CONSTRAINTS = 0x00001000,
		SQL_ISV_SCHEMATA = 0x00002000,
		SQL_ISV_SQL_LANGUAGES = 0x00004000,
		SQL_ISV_TABLE_CONSTRAINTS = 0x00008000,
		SQL_ISV_TABLE_PRIVILEGES = 0x00010000,
		SQL_ISV_TABLES = 0x00020000,
		SQL_ISV_TRANSLATIONS = 0x00040000,
		SQL_ISV_USAGE_PRIVILEGES = 0x00080000,
		SQL_ISV_VIEW_COLUMN_USAGE = 0x00100000,
		SQL_ISV_VIEW_TABLE_USAGE = 0x00200000,
		SQL_ISV_VIEWS = 0x00400000,
	}

	[Flags]
	public enum SQL_LCK : uint
	{
		SQL_LCK_NO_CHANGE = 0x00000001,
		SQL_LCK_EXCLUSIVE = 0x00000002,
		SQL_LCK_UNLOCK = 0x00000004
	}

	/// <summary>Lock options in SQLSetPos</summary>
	[PInvokeData("sql.h")]
	public enum SQL_LOCK : uint
	{
		SQL_LOCK_NO_CHANGE = 0, /* 1.0 FALSE */
		SQL_LOCK_EXCLUSIVE = 1, /* 1.0 TRUE */
		SQL_LOCK_UNLOCK = 2
	}

	[Flags]
	public enum SQL_NC : uint
	{
		SQL_NC_HIGH = 0,
		SQL_NC_LOW = 1,
		SQL_NC_START = 0x0002,
		SQL_NC_END = 0x0004
	}

	public enum SQL_NNC : uint
	{
		SQL_NNC_NULL = 0x0000,
		SQL_NNC_NON_NULL = 0x0001
	}

	public enum SQL_NULLABILITY : ushort
	{
		SQL_NO_NULLS = 0,                // SQL_NO_NULLS
		SQL_NULLABLE = 1,                // SQL_NULLABLE
		SQL_NULLABLE_UNKNOWN = 2,        // SQL_NULLABLE_UNKNOWN
	}

	public enum SQL_OAC : uint
	{
		SQL_OAC_NONE = 0x0000,
		SQL_OAC_LEVEL1 = 0x0001,
		SQL_OAC_LEVEL2 = 0x0002
	}

	public enum SQL_OIC : uint
	{
		SQL_OIC_CORE = 1,
		SQL_OIC_LEVEL1 = 2,
		SQL_OIC_LEVEL2 = 3
	}

	[Flags]
	public enum SQL_OJ : uint
	{
		SQL_OJ_LEFT = 0x00000001,
		SQL_OJ_RIGHT = 0x00000002,
		SQL_OJ_FULL = 0x00000004,
		SQL_OJ_NESTED = 0x00000008,
		SQL_OJ_NOT_ORDERED = 0x00000010,
		SQL_OJ_INNER = 0x00000020,
		SQL_OJ_ALL_COMPARISON_OPS = 0x00000040,
	}

	public enum SQL_OSC : uint
	{
		SQL_OSC_MINIMUM = 0x0000,
		SQL_OSC_CORE = 0x0001,
		SQL_OSC_EXTENDED = 0x0002
	}

	public enum SQL_OSCC : uint
	{
		SQL_OSCC_NOT_COMPLIANT = 0x0000,
		SQL_OSCC_COMPLIANT = 0x0001
	}

	[Flags]
	public enum SQL_OU : uint
	{
		SQL_OU_DML_STATEMENTS = 0x00000001,
		SQL_OU_PROCEDURE_INVOCATION = 0x00000002,
		SQL_OU_TABLE_DEFINITION = 0x00000004,
	}

	[PInvokeData("sqlext.h")]
	public enum SQL_OV
	{
		SQL_OV_ODBC2 = 2,
		SQL_OV_ODBC3 = 3,
	}

	public enum SQL_PARC : uint
	{
		SQL_PARC_BATCH = 1,
		SQL_PARC_NO_BATCH = 2
	}

	public enum SQL_PAS : uint
	{
		SQL_PAS_BATCH = 1,
		SQL_PAS_NO_BATCH = 2,
		SQL_PAS_NO_SELECT = 3
	}

	[Flags]
	public enum SQL_POS : uint
	{
		SQL_POS_POSITION = 0x00000001,
		SQL_POS_REFRESH = 0x00000002,
		SQL_POS_UPDATE = 0x00000004,
		SQL_POS_DELETE = 0x00000008,
		SQL_POS_ADD = 0x00000010
	}

	[Flags]
	public enum SQL_PS : uint
	{
		SQL_PS_POSITIONED_DELETE = 0x00000001,
		SQL_PS_POSITIONED_UPDATE = 0x00000002,
		SQL_PS_SELECT_FOR_UPDATE = 0x00000004
	}

	public enum SQL_QL : uint
	{
		SQL_QL_START = 0x0001,
		SQL_QL_END = 0x0002
	}

	[Flags]
	public enum SQL_QU : uint
	{
		SQL_QU_DML_STATEMENTS = 0x00000001,
		SQL_QU_PROCEDURE_INVOCATION = 0x00000002,
		SQL_QU_TABLE_DEFINITION = 0x00000004,
		SQL_QU_INDEX_DEFINITION = 0x00000008,
		SQL_QU_PRIVILEGE_DEFINITION = 0x00000010
	}

	/// <summary>Defines for SQLStatistics</summary>
	public enum SQL_RES
	{
		SQL_QUICK = 0,
		SQL_ENSURE = 1,
	}

	[Flags]
	public enum SQL_SC : uint
	{
		SQL_SC_SQL92_ENTRY = 0x00000001,
		SQL_SC_FIPS127_2_TRANSITIONAL = 0x00000002,
		SQL_SC_SQL92_INTERMEDIATE = 0x00000004,
		SQL_SC_SQL92_FULL = 0x00000008
	}

	[Flags]
	public enum SQL_SCC : uint
	{
		SQL_SCC_XOPEN_CLI_VERSION1 = 0x00000001,
		SQL_SCC_ISO92_CLI = 0x00000002
	}

	[Flags]
	public enum SQL_SCCO : uint
	{
		SQL_SCCO_READ_ONLY = 0x00000001,
		SQL_SCCO_LOCK = 0x00000002,
		SQL_SCCO_OPT_ROWVER = 0x00000004,
		SQL_SCCO_OPT_VALUES = 0x00000008,
	}

	/// <summary>Values that may appear in the result set of SQLSpecialColumns()</summary>
	public enum SQL_SCOPE : short
	{
		SQL_SCOPE_CURROW = 0,
		SQL_SCOPE_TRANSACTION = 1,
		SQL_SCOPE_SESSION = 2
	}

	[Flags]
	public enum SQL_SDF : uint
	{
		SQL_SDF_CURRENT_DATE = 0x00000001,
		SQL_SDF_CURRENT_TIME = 0x00000002,
		SQL_SDF_CURRENT_TIMESTAMP = 0x00000004
	}

	[Flags]
	public enum SQL_SFKD : uint
	{
		SQL_SFKD_CASCADE = 0x00000001,
		SQL_SFKD_NO_ACTION = 0x00000002,
		SQL_SFKD_SET_DEFAULT = 0x00000004,
		SQL_SFKD_SET_NULL = 0x00000008
	}

	[Flags]
	public enum SQL_SFKU : uint
	{
		SQL_SFKU_CASCADE = 0x00000001,
		SQL_SFKU_NO_ACTION = 0x00000002,
		SQL_SFKU_SET_DEFAULT = 0x00000004,
		SQL_SFKU_SET_NULL = 0x00000008
	}

	[Flags]
	public enum SQL_SG : uint
	{
		SQL_SG_USAGE_ON_DOMAIN = 0x00000001,
		SQL_SG_USAGE_ON_CHARACTER_SET = 0x00000002,
		SQL_SG_USAGE_ON_COLLATION = 0x00000004,
		SQL_SG_USAGE_ON_TRANSLATION = 0x00000008,
		SQL_SG_WITH_GRANT_OPTION = 0x00000010,
		SQL_SG_DELETE_TABLE = 0x00000020,
		SQL_SG_INSERT_TABLE = 0x00000040,
		SQL_SG_INSERT_COLUMN = 0x00000080,
		SQL_SG_REFERENCES_TABLE = 0x00000100,
		SQL_SG_REFERENCES_COLUMN = 0x00000200,
		SQL_SG_SELECT_TABLE = 0x00000400,
		SQL_SG_UPDATE_TABLE = 0x00000800,
		SQL_SG_UPDATE_COLUMN = 0x00001000
	}

	[Flags]
	public enum SQL_SNVF : uint
	{
		SQL_SNVF_BIT_LENGTH = 0x00000001,
		SQL_SNVF_CHAR_LENGTH = 0x00000002,
		SQL_SNVF_CHARACTER_LENGTH = 0x00000004,
		SQL_SNVF_EXTRACT = 0x00000008,
		SQL_SNVF_OCTET_LENGTH = 0x00000010,
		SQL_SNVF_POSITION = 0x00000020
	}

	[Flags]
	public enum SQL_SO : uint
	{
		SQL_SO_FORWARD_ONLY = 0x00000001,
		SQL_SO_KEYSET_DRIVEN = 0x00000002,
		SQL_SO_DYNAMIC = 0x00000004,
		SQL_SO_MIXED = 0x00000008,
		SQL_SO_STATIC = 0x00000010
	}

	[Flags]
	public enum SQL_SP : uint
	{
		SQL_SP_EXISTS = 0x00000001,
		SQL_SP_ISNOTNULL = 0x00000002,
		SQL_SP_ISNULL = 0x00000004,
		SQL_SP_MATCH_FULL = 0x00000008,
		SQL_SP_MATCH_PARTIAL = 0x00000010,
		SQL_SP_MATCH_UNIQUE_FULL = 0x00000020,
		SQL_SP_MATCH_UNIQUE_PARTIAL = 0x00000040,
		SQL_SP_OVERLAPS = 0x00000080,
		SQL_SP_UNIQUE = 0x00000100,
		SQL_SP_LIKE = 0x00000200,
		SQL_SP_IN = 0x00000400,
		SQL_SP_BETWEEN = 0x00000800,
		SQL_SP_COMPARISON = 0x00001000,
		SQL_SP_QUANTIFIED_COMPARISON = 0x00002000
	}

	[Flags]
	public enum SQL_SQ : uint
	{
		SQL_SQ_COMPARISON = 0x00000001,
		SQL_SQ_EXISTS = 0x00000002,
		SQL_SQ_IN = 0x00000004,
		SQL_SQ_QUANTIFIED = 0x00000008,
		SQL_SQ_CORRELATED_SUBQUERIES = 0x00000010
	}

	[Flags]
	public enum SQL_SR : uint
	{
		SQL_SR_USAGE_ON_DOMAIN = 0x00000001,
		SQL_SR_USAGE_ON_CHARACTER_SET = 0x00000002,
		SQL_SR_USAGE_ON_COLLATION = 0x00000004,
		SQL_SR_USAGE_ON_TRANSLATION = 0x00000008,
		SQL_SR_WITH_GRANT_OPTION = 0x00000010,
		SQL_SR_CASCADE = 0x00000020,
		SQL_SR_RESTRICT = 0x00000040,
		SQL_SR_DELETE_TABLE = 0x00000080,
		SQL_SR_INSERT_TABLE = 0x00000100,
		SQL_SR_INSERT_COLUMN = 0x00000200,
		SQL_SR_REFERENCES_TABLE = 0x00000400,
		SQL_SR_REFERENCES_COLUMN = 0x00000800,
		SQL_SR_SELECT_TABLE = 0x00001000,
		SQL_SR_UPDATE_TABLE = 0x00002000,
		SQL_SR_UPDATE_COLUMN = 0x00004000
	}

	[Flags]
	public enum SQL_SRJO : uint
	{
		SQL_SRJO_CORRESPONDING_CLAUSE = 0x00000001,
		SQL_SRJO_CROSS_JOIN = 0x00000002,
		SQL_SRJO_EXCEPT_JOIN = 0x00000004,
		SQL_SRJO_FULL_OUTER_JOIN = 0x00000008,
		SQL_SRJO_INNER_JOIN = 0x00000010,
		SQL_SRJO_INTERSECT_JOIN = 0x00000020,
		SQL_SRJO_LEFT_OUTER_JOIN = 0x00000040,
		SQL_SRJO_NATURAL_JOIN = 0x00000080,
		SQL_SRJO_RIGHT_OUTER_JOIN = 0x00000100,
		SQL_SRJO_UNION_JOIN = 0x00000200
	}

	[Flags]
	public enum SQL_SRVC : uint
	{
		SQL_SRVC_VALUE_EXPRESSION = 0x00000001,
		SQL_SRVC_NULL = 0x00000002,
		SQL_SRVC_DEFAULT = 0x00000004,
		SQL_SRVC_ROW_SUBQUERY = 0x00000008
	}

	[Flags]
	public enum SQL_SS : uint
	{
		SQL_SS_ADDITIONS = 0x00000001,
		SQL_SS_DELETIONS = 0x00000002,
		SQL_SS_UPDATES = 0x00000004
	}

	[Flags]
	public enum SQL_SSF : uint
	{
		SQL_SSF_CONVERT = 0x00000001,
		SQL_SSF_LOWER = 0x00000002,
		SQL_SSF_UPPER = 0x00000004,
		SQL_SSF_SUBSTRING = 0x00000008,
		SQL_SSF_TRANSLATE = 0x00000010,
		SQL_SSF_TRIM_BOTH = 0x00000020,
		SQL_SSF_TRIM_LEADING = 0x00000040,
		SQL_SSF_TRIM_TRAILING = 0x00000080
	}

	[PInvokeData("sql.h")]
	public enum SQL_STMT
	{
		SQL_CLOSE = 0,
		SQL_DROP = 1,
		SQL_UNBIND = 2,
		SQL_RESET_PARAMS = 3,
	}

	[Flags]
	public enum SQL_SU : uint
	{
		SQL_SU_DML_STATEMENTS = SQL_OU.SQL_OU_DML_STATEMENTS,
		SQL_SU_PROCEDURE_INVOCATION = SQL_OU.SQL_OU_PROCEDURE_INVOCATION,
		SQL_SU_TABLE_DEFINITION = SQL_OU.SQL_OU_TABLE_DEFINITION,
		SQL_SU_INDEX_DEFINITION = 0x00000008,
		SQL_SU_PRIVILEGE_DEFINITION = 0x00000010
	}

	[Flags]
	public enum SQL_SVE : uint
	{
		SQL_SVE_CASE = 0x00000001,
		SQL_SVE_CAST = 0x00000002,
		SQL_SVE_COALESCE = 0x00000004,
		SQL_SVE_NULLIF = 0x00000008
	}

	public enum SQL_TC : uint
	{
		SQL_TC_NONE = 0,
		SQL_TC_DML = 1,
		SQL_TC_ALL = 2,
		SQL_TC_DDL_COMMIT = 3,
		SQL_TC_DDL_IGNORE = 4,
	}

	[Flags]
	public enum SQL_TXN : uint
	{
		SQL_TXN_READ_UNCOMMITTED = 0x00000001,
		SQL_TXN_READ_COMMITTED = 0x00000002,
		SQL_TXN_REPEATABLE_READ = 0x00000004,
		SQL_TXN_SERIALIZABLE = 0x00000008,
	}

	//SQL Data Types - returned as column types (SQLColAttribute)
	public enum SQL_TYPE : short
	{
		[CorrespondingType(typeof(string), EncodingType = typeof(ASCIIEncoding))]
		SQL_CHAR = SQL_C.SQL_C_CHAR,             //SQL_CHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(ASCIIEncoding))]
		SQL_VARCHAR = 12,                     //SQL_VARCHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(ASCIIEncoding))]
		SQL_LONGVARCHAR = -1,                     //SQL_LONGVARCHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(UnicodeEncoding))]
		SQL_WCHAR = SQL_C.SQL_C_WCHAR,            //SQL_WCHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(UnicodeEncoding))]
		SQL_WVARCHAR = -9,                     //SQL_WVARCHAR

		[CorrespondingType(typeof(string), EncodingType = typeof(UnicodeEncoding))]
		SQL_WLONGVARCHAR = -10,                    //SQL_WLONGVARCHAR

		[CorrespondingType(typeof(decimal))]
		SQL_DECIMAL = 3,                      //SQL_DECIMAL

		[CorrespondingType(typeof(decimal))]
		SQL_NUMERIC = SQL_C.SQL_C_NUMERIC,          //SQL_NUMERIC

		[CorrespondingType(typeof(short))]
		SQL_SMALLINT = 5,                      //SQL_SMALLINT

		[CorrespondingType(typeof(int))]
		SQL_INTEGER = 4,                      //SQL_INTEGER

		[CorrespondingType(typeof(Single))]
		SQL_REAL = SQL_C.SQL_C_REAL,             //SQL_REAL

		[CorrespondingType(typeof(float))]
		SQL_FLOAT = 6,                      //SQL_FLOAT

		[CorrespondingType(typeof(double))]
		SQL_DOUBLE = SQL_C.SQL_C_DOUBLE,           //SQL_DOUBLE

		[CorrespondingType(typeof(bool))]
		SQL_BIT = SQL_C.SQL_C_BIT,              //SQL_BIT

		[CorrespondingType(typeof(byte))]
		SQL_TINYINT = -6,                     //SQL_TINYINT

		[CorrespondingType(typeof(long))]
		SQL_BIGINT = -5,                     //SQL_BIGINT

		[CorrespondingType(typeof(byte[]))]
		SQL_BINARY = SQL_C.SQL_C_BINARY,           //SQL_BINARY

		[CorrespondingType(typeof(byte[]))]
		SQL_VARBINARY = -3,                     //SQL_VARBINARY

		[CorrespondingType(typeof(byte[]))]
		SQL_LONGVARBINARY = -4,                     //SQL_LONGVARBINARY

		// DATE = 9, //SQL_DATE
		SQL_TYPE_DATE = SQL_C.SQL_C_TYPE_DATE,        //SQL_TYPE_DATE

		SQL_TYPE_TIME = SQL_C.SQL_C_TYPE_TIME,        //SQL_TYPE_TIME
		SQL_TIMESTAMP = SQL_C.SQL_C_TIMESTAMP,        //SQL_TIMESTAMP

		[CorrespondingType(typeof(TIMESTAMP_STRUCT))]
		SQL_TYPE_TIMESTAMP = SQL_C.SQL_C_TYPE_TIMESTAMP,   //SQL_TYPE_TIMESTAMP

		[CorrespondingType(typeof(Guid))]
		SQL_GUID = SQL_C.SQL_C_GUID,             //SQL_GUID

		// from odbcss.h in mdac 9.0 sources! Driver specific SQL type defines. Microsoft has -150 thru -199 reserved for Microsoft SQL
		// Server driver usage.
		SS_VARIANT = -150,

		SS_UDT = -151,
		SS_XML = -152,
		SS_UTCDATETIME = -153,
		SS_TIME_EX = -154,
	}

	[Flags]
	public enum SQL_U : uint
	{
		SQL_U_UNION = 0x00000001,
		SQL_U_UNION_ALL = 0x00000002
	}

	[Flags]
	public enum SQL_US : uint
	{
		SQL_US_UNION = SQL_U.SQL_U_UNION,
		SQL_US_UNION_ALL = SQL_U.SQL_U_UNION_ALL
	}

	public enum SQLBulkOperation : ushort
	{
		SQL_ADD = 4,
		SQL_UPDATE_BY_BOOKMARK = 5,
		SQL_DELETE_BY_BOOKMARK = 6,
		SQL_FETCH_BY_BOOKMARK = 7,
	}

	public interface ISQLHANDLE : IHandle
	{ }

	public static SQL_C SQL_C_TCHAR() => Marshal.SystemDefaultCharSize == 1 ? SQL_C.SQL_C_CHAR : SQL_C.SQL_C_WCHAR;

	/* SQL_CURSOR_COMMIT_BEHAVIOR values */
	/* SQL_CONCAT_NULL_BEHAVIOR values */
	/* SQL_GETDATA_EXTENSIONS bitmasks */

	/// <summary>
	/// The SQL_FUNC_EXISTS(SupportedPtr, FunctionID) macro is used to determine support of ODBC 3*.x* or earlier functions after
	/// SQLGetFunctions has been called with a FunctionId argument of SQL_API_ODBC3_ALL_FUNCTIONS.
	/// </summary>
	/// <param name="pfExists">The SupportedPtr argument set to the SupportedPtr passed in SQLGetFunctions.</param>
	/// <param name="uwAPI">The <see cref="SQL_API"/> value of the function to evaluate.</param>
	/// <returns>SQL_FUNC_EXISTS returns <see langword="true"/> if the function is supported, and <see langword="false"/> otherwise.</returns>
	[PInvokeData("sqlext.h")]
	public static bool SQL_FUNC_EXISTS(ushort[] pfExists, SQL_API uwAPI)
	{
		unsafe
		{
			fixed (ushort* p = pfExists)
				return (*(p + (((ushort)uwAPI) >> 4)) & (1 << (((ushort)uwAPI) & 0x000F))) != 0;
		}
	}

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLAllocHandle</c> allocates an environment, connection, statement, or descriptor handle.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// This function is a generic function for allocating handles that replaces the ODBC 2.0 functions <c>SQLAllocConnect</c>,
	/// <c>SQLAllocEnv</c>, and <c>SQLAllocStmt</c>. To allow applications calling <c>SQLAllocHandle</c> to work with ODBC 2.x drivers, a
	/// call to <c>SQLAllocHandle</c> is mapped in the Driver Manager to <c>SQLAllocConnect</c>, <c>SQLAllocEnv</c>, or <c>SQLAllocStmt</c>,
	/// as appropriate. For more information, see "Comments." For more information about what the Driver Manager maps this function to when
	/// an ODBC 3.x application is working with an ODBC 2.x driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="HandleType">
	/// <para>[Input] The type of handle to be allocated by <c>SQLAllocHandle</c>. Must be one of the following values:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC_INFO_TOKEN</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DESC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_ENV</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_STMT</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// SQL_HANDLE_DBC_INFO_TOKEN handle is used only by the Driver Manager and driver. Applications should not use this handle type. For
	/// more information about SQL_HANDLE_DBC_INFO_TOKEN, see Developing Connection-Pool Awareness in an ODBC Driver.
	/// </para>
	/// </param>
	/// <param name="InputHandle">
	/// [Input] The input handle in whose context the new handle is to be allocated. If HandleType is SQL_HANDLE_ENV, this is
	/// SQL_NULL_HANDLE. If HandleType is SQL_HANDLE_DBC, this must be an environment handle, and if it is SQL_HANDLE_STMT or
	/// SQL_HANDLE_DESC, it must be a connection handle.
	/// </param>
	/// <param name="OutputHandlePtr">[Output] Pointer to a buffer in which to return the handle to the newly allocated data structure.</param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.</para>
	/// <para>
	/// When allocating a handle other than an environment handle, if <c>SQLAllocHandle</c> returns SQL_ERROR, it sets OutputHandlePtr to
	/// SQL_NULL_HDBC, SQL_NULL_HSTMT, or SQL_NULL_HDESC, depending on the value of HandleType, unless the output argument is a null pointer.
	/// The application can then obtain additional information from the diagnostic data structure associated with the handle in the
	/// InputHandle argument.
	/// </para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlallochandle-function?view=sql-server-ver16 SQLRETURN SQLAllocHandle(
	// SQL_HANDLE HandleType, IntPtr InputHandle, IntPtr * OutputHandlePtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLAllocHandle(SQL_HANDLE HandleType, [In, Optional] IntPtr InputHandle,
		out IntPtr OutputHandlePtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLAllocHandle</c> allocates an environment, connection, statement, or descriptor handle.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// This function is a generic function for allocating handles that replaces the ODBC 2.0 functions <c>SQLAllocConnect</c>,
	/// <c>SQLAllocEnv</c>, and <c>SQLAllocStmt</c>. To allow applications calling <c>SQLAllocHandle</c> to work with ODBC 2.x drivers, a
	/// call to <c>SQLAllocHandle</c> is mapped in the Driver Manager to <c>SQLAllocConnect</c>, <c>SQLAllocEnv</c>, or <c>SQLAllocStmt</c>,
	/// as appropriate. For more information, see "Comments." For more information about what the Driver Manager maps this function to when
	/// an ODBC 3.x application is working with an ODBC 2.x driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <typeparam name="T">The output handle type.</typeparam>
	/// <param name="InputHandle">
	/// [Input] The input handle in whose context the new handle is to be allocated. If HandleType is SQL_HANDLE_ENV, this is
	/// SQL_NULL_HANDLE. If HandleType is SQL_HANDLE_DBC, this must be an environment handle, and if it is SQL_HANDLE_STMT or
	/// SQL_HANDLE_DESC, it must be a connection handle.
	/// </param>
	/// <param name="OutputHandlePtr">[Output] Pointer to a buffer in which to return the handle to the newly allocated data structure.</param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.</para>
	/// <para>
	/// When allocating a handle other than an environment handle, if <c>SQLAllocHandle</c> returns SQL_ERROR, it sets OutputHandlePtr to
	/// SQL_NULL_HDBC, SQL_NULL_HSTMT, or SQL_NULL_HDESC, depending on the value of HandleType, unless the output argument is a null pointer.
	/// The application can then obtain additional information from the diagnostic data structure associated with the handle in the
	/// InputHandle argument.
	/// </para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlallochandle-function?view=sql-server-ver16 SQLRETURN SQLAllocHandle(
	// SQL_HANDLE HandleType, IntPtr InputHandle, IntPtr * OutputHandlePtr);
	[PInvokeData("sql.h")]
	public static SQLRETURN SQLAllocHandle<T>(out T OutputHandlePtr, [In, Optional] ISQLHANDLE? InputHandle) where T : ISQLHANDLE
	{
		var ret = SQLAllocHandle(GetHandleVal<T>(), InputHandle?.DangerousGetHandle() ?? default, out var ptr);
		OutputHandlePtr = (T)Activator.CreateInstance(typeof(T), ptr)!;
		return ret;
	}

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLAllocHandle</c> allocates an environment, connection, statement, or descriptor handle.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// This function is a generic function for allocating handles that replaces the ODBC 2.0 functions <c>SQLAllocConnect</c>,
	/// <c>SQLAllocEnv</c>, and <c>SQLAllocStmt</c>. To allow applications calling <c>SQLAllocHandle</c> to work with ODBC 2.x drivers, a
	/// call to <c>SQLAllocHandle</c> is mapped in the Driver Manager to <c>SQLAllocConnect</c>, <c>SQLAllocEnv</c>, or <c>SQLAllocStmt</c>,
	/// as appropriate. For more information, see "Comments." For more information about what the Driver Manager maps this function to when
	/// an ODBC 3.x application is working with an ODBC 2.x driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <typeparam name="T">The output handle type.</typeparam>
	/// <param name="InputHandle">
	/// [Input] The input handle in whose context the new handle is to be allocated. If HandleType is SQL_HANDLE_ENV, this is
	/// SQL_NULL_HANDLE. If HandleType is SQL_HANDLE_DBC, this must be an environment handle, and if it is SQL_HANDLE_STMT or
	/// SQL_HANDLE_DESC, it must be a connection handle.
	/// </param>
	/// <returns>[Output] Pointer to a buffer in which to return the handle to the newly allocated data structure.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlallochandle-function?view=sql-server-ver16 SQLRETURN SQLAllocHandle(
	// SQL_HANDLE HandleType, IntPtr InputHandle, IntPtr * OutputHandlePtr);
	[PInvokeData("sql.h")]
	public static T SQLAllocHandle<T>([In, Optional] ISQLHANDLE? InputHandle) where T : SafeHANDLE, ISQLHANDLE
	{
		SQLAllocHandle(GetHandleVal<T>(), InputHandle?.DangerousGetHandle() ?? default, out var ptr).ThrowIfFailed(InputHandle);
		return (T)Activator.CreateInstance(typeof(T), ptr, true)!;
	}

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLBindCol</c> binds application data buffers to columns in the result set.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnNumber">
	/// [Input] Number of the result set column to bind. Columns are numbered in increasing column order starting at 0, where column 0 is the
	/// bookmark column. If bookmarks are not used - that is, the SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_OFF - then
	/// column numbers start at 1.
	/// </param>
	/// <param name="TargetType">
	/// <para>
	/// [Input] The identifier of the C data type of the *TargetValuePtr buffer. When it is retrieving data from the data source with
	/// <c>SQLFetch</c>, <c>SQLFetchScroll</c>, <c>SQLBulkOperations</c>, or <c>SQLSetPos</c>, the driver converts the data to this type;
	/// when it sends data to the data source with <c>SQLBulkOperations</c> or <c>SQLSetPos</c>, the driver converts the data from this type.
	/// For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types.
	/// </para>
	/// <para>
	/// If the TargetType argument is an interval data type, the default interval leading precision (2) and the default interval seconds
	/// precision (6), as set in the SQL_DESC_DATETIME_INTERVAL_PRECISION and SQL_DESC_PRECISION fields of the ARD, respectively, are used
	/// for the data. If the TargetType argument is SQL_C_NUMERIC, the default precision (driver-defined) and default scale (0), as set in
	/// the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the ARD, are used for the data. If any default precision or scale is not
	/// appropriate, the application should explicitly set the appropriate descriptor field by a call to <c>SQLSetDescField</c> or <c>SQLSetDescRec</c>.
	/// </para>
	/// <para>You can also specify an extended C data type. For more information, see C Data Types in ODBC.</para>
	/// </param>
	/// <param name="TargetValuePtr">
	/// <para>
	/// [Deferred Input/Output] Pointer to the data buffer to bind to the column. <c>SQLFetch</c> and <c>SQLFetchScroll</c> return data in
	/// this buffer. <c>SQLBulkOperations</c> returns data in this buffer when Operation is SQL_FETCH_BY_BOOKMARK; it retrieves data from
	/// this buffer when Operation is SQL_ADD or SQL_UPDATE_BY_BOOKMARK. <c>SQLSetPos</c> returns data in this buffer when Operation is
	/// SQL_REFRESH; it retrieves data from this buffer when Operation is SQL_UPDATE.
	/// </para>
	/// <para>
	/// If TargetValuePtr is a null pointer, the driver unbinds the data buffer for the column. An application can unbind all columns by
	/// calling <c>SQLFreeStmt</c> with the SQL_UNBIND option. An application can unbind the data buffer for a column but still have a
	/// length/indicator buffer bound for the column, if the TargetValuePtr argument in the call to <c>SQLBindCol</c> is a null pointer but
	/// the StrLen_or_IndPtr argument is a valid value.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>[Input] Length of the *TargetValuePtr buffer in bytes.</para>
	/// <para>
	/// The driver uses BufferLength to avoid writing past the end of the *TargetValuePtr buffer when it returns variable-length data, such
	/// as character or binary data. Notice that the driver counts the null-termination character when it returns character data to
	/// *TargetValuePtr. *TargetValuePtr must therefore contain space for the null-termination character or the driver will truncate the data.
	/// </para>
	/// <para>
	/// When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the
	/// buffer is large enough to hold the data. Therefore, it is important for the application to allocate a large enough buffer for
	/// fixed-length data or the driver will write past the end of the buffer.
	/// </para>
	/// <para>
	/// <c>SQLBindCol</c> returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength
	/// is 0. However, if TargetType specifies a character type, an application should not set BufferLength to 0, because ISO CLI-compliant
	/// drivers return SQLSTATE HY090 (Invalid string or buffer length) in that case.
	/// </para>
	/// </param>
	/// <param name="StrLen_or_IndPtr">
	/// <para>
	/// [Deferred Input/Output] Pointer to the length/indicator buffer to bind to the column. <c>SQLFetch</c> and <c>SQLFetchScroll</c>
	/// return a value in this buffer. <c>SQLBulkOperations</c> retrieves a value from this buffer when Operation is SQL_ADD,
	/// SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK. <c>SQLBulkOperations</c> returns a value in this buffer when Operation is
	/// SQL_FETCH_BY_BOOKMARK. <c>SQLSetPos</c> returns a value in this buffer when Operation is SQL_REFRESH; it retrieves a value from this
	/// buffer when Operation is SQL_UPDATE.
	/// </para>
	/// <para>
	/// <c>SQLFetch</c>, <c>SQLFetchScroll</c>, <c>SQLBulkOperations</c>, and <c>SQLSetPos</c> can return the following values in the
	/// length/indicator buffer:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The length of the data available to return</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NO_TOTAL</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULL_DATA</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>The application can put the following values in the length/indicator buffer for use with <c>SQLBulkOperations</c> or <c>SQLSetPos</c>:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The length of the data being sent</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NTS</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULL_DATA</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_DATA_AT_EXEC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>The result of the SQL_LEN_DATA_AT_EXEC macro</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_COLUMN_IGNORE</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// If the indicator buffer and the length buffer are separate buffers, the indicator buffer can return only SQL_NULL_DATA, whereas the
	/// length buffer can return all other values.
	/// </para>
	/// <para>For more information, see SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function, and Using Length/Indicator Values.</para>
	/// <para>
	/// If StrLen_or_IndPtr is a null pointer, no length or indicator value is used. This is an error when fetching data and the data is NULL.
	/// </para>
	/// <para>See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindcol-function?view=sql-server-ver16 SQLRETURN SQLBindCol( SQLHSTMT
	// StatementHandle, uint ColumnNumber, short TargetType, IntPtr TargetValuePtr, nint BufferLength, nint * StrLen_or_IndPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLBindCol([In] SQLHSTMT StatementHandle, uint ColumnNumber, SQL_C TargetType,
		[In, Out] IntPtr TargetValuePtr, nint BufferLength, [In, Out, Optional] IntPtr StrLen_or_IndPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLBindCol</c> binds application data buffers to columns in the result set.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnNumber">
	/// [Input] Number of the result set column to bind. Columns are numbered in increasing column order starting at 0, where column 0 is the
	/// bookmark column. If bookmarks are not used - that is, the SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_OFF - then
	/// column numbers start at 1.
	/// </param>
	/// <param name="TargetType">
	/// <para>
	/// [Input] The identifier of the C data type of the *TargetValuePtr buffer. When it is retrieving data from the data source with
	/// <c>SQLFetch</c>, <c>SQLFetchScroll</c>, <c>SQLBulkOperations</c>, or <c>SQLSetPos</c>, the driver converts the data to this type;
	/// when it sends data to the data source with <c>SQLBulkOperations</c> or <c>SQLSetPos</c>, the driver converts the data from this type.
	/// For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types.
	/// </para>
	/// <para>
	/// If the TargetType argument is an interval data type, the default interval leading precision (2) and the default interval seconds
	/// precision (6), as set in the SQL_DESC_DATETIME_INTERVAL_PRECISION and SQL_DESC_PRECISION fields of the ARD, respectively, are used
	/// for the data. If the TargetType argument is SQL_C_NUMERIC, the default precision (driver-defined) and default scale (0), as set in
	/// the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the ARD, are used for the data. If any default precision or scale is not
	/// appropriate, the application should explicitly set the appropriate descriptor field by a call to <c>SQLSetDescField</c> or <c>SQLSetDescRec</c>.
	/// </para>
	/// <para>You can also specify an extended C data type. For more information, see C Data Types in ODBC.</para>
	/// </param>
	/// <param name="TargetValuePtr">
	/// <para>
	/// [Deferred Input/Output] Pointer to the data buffer to bind to the column. <c>SQLFetch</c> and <c>SQLFetchScroll</c> return data in
	/// this buffer. <c>SQLBulkOperations</c> returns data in this buffer when Operation is SQL_FETCH_BY_BOOKMARK; it retrieves data from
	/// this buffer when Operation is SQL_ADD or SQL_UPDATE_BY_BOOKMARK. <c>SQLSetPos</c> returns data in this buffer when Operation is
	/// SQL_REFRESH; it retrieves data from this buffer when Operation is SQL_UPDATE.
	/// </para>
	/// <para>
	/// If TargetValuePtr is a null pointer, the driver unbinds the data buffer for the column. An application can unbind all columns by
	/// calling <c>SQLFreeStmt</c> with the SQL_UNBIND option. An application can unbind the data buffer for a column but still have a
	/// length/indicator buffer bound for the column, if the TargetValuePtr argument in the call to <c>SQLBindCol</c> is a null pointer but
	/// the StrLen_or_IndPtr argument is a valid value.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>[Input] Length of the *TargetValuePtr buffer in bytes.</para>
	/// <para>
	/// The driver uses BufferLength to avoid writing past the end of the *TargetValuePtr buffer when it returns variable-length data, such
	/// as character or binary data. Notice that the driver counts the null-termination character when it returns character data to
	/// *TargetValuePtr. *TargetValuePtr must therefore contain space for the null-termination character or the driver will truncate the data.
	/// </para>
	/// <para>
	/// When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the
	/// buffer is large enough to hold the data. Therefore, it is important for the application to allocate a large enough buffer for
	/// fixed-length data or the driver will write past the end of the buffer.
	/// </para>
	/// <para>
	/// <c>SQLBindCol</c> returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength
	/// is 0. However, if TargetType specifies a character type, an application should not set BufferLength to 0, because ISO CLI-compliant
	/// drivers return SQLSTATE HY090 (Invalid string or buffer length) in that case.
	/// </para>
	/// </param>
	/// <param name="StrLen_or_IndPtr">
	/// <para>
	/// [Deferred Input/Output] Pointer to the length/indicator buffer to bind to the column. <c>SQLFetch</c> and <c>SQLFetchScroll</c>
	/// return a value in this buffer. <c>SQLBulkOperations</c> retrieves a value from this buffer when Operation is SQL_ADD,
	/// SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK. <c>SQLBulkOperations</c> returns a value in this buffer when Operation is
	/// SQL_FETCH_BY_BOOKMARK. <c>SQLSetPos</c> returns a value in this buffer when Operation is SQL_REFRESH; it retrieves a value from this
	/// buffer when Operation is SQL_UPDATE.
	/// </para>
	/// <para>
	/// <c>SQLFetch</c>, <c>SQLFetchScroll</c>, <c>SQLBulkOperations</c>, and <c>SQLSetPos</c> can return the following values in the
	/// length/indicator buffer:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The length of the data available to return</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NO_TOTAL</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULL_DATA</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>The application can put the following values in the length/indicator buffer for use with <c>SQLBulkOperations</c> or <c>SQLSetPos</c>:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The length of the data being sent</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NTS</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULL_DATA</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_DATA_AT_EXEC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>The result of the SQL_LEN_DATA_AT_EXEC macro</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_COLUMN_IGNORE</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// If the indicator buffer and the length buffer are separate buffers, the indicator buffer can return only SQL_NULL_DATA, whereas the
	/// length buffer can return all other values.
	/// </para>
	/// <para>For more information, see SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function, and Using Length/Indicator Values.</para>
	/// <para>
	/// If StrLen_or_IndPtr is a null pointer, no length or indicator value is used. This is an error when fetching data and the data is NULL.
	/// </para>
	/// <para>See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindcol-function?view=sql-server-ver16 SQLRETURN SQLBindCol( SQLHSTMT
	// StatementHandle, uint ColumnNumber, short TargetType, IntPtr TargetValuePtr, nint BufferLength, nint * StrLen_or_IndPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLBindCol([In] SQLHSTMT StatementHandle, uint ColumnNumber, SQL_C TargetType,
		[In, Out] IntPtr TargetValuePtr, nint BufferLength, ref nint StrLen_or_IndPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 2.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLBindParameter</c> binds a buffer to a parameter marker in an SQL statement. <c>SQLBindParameter</c> supports
	/// binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>This function replaces the ODBC 1.0 function <c>SQLSetParam</c>. For more information, see "Comments."</para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ParameterNumber">[Input] Parameter number, ordered sequentially in increasing parameter order, starting at 1.</param>
	/// <param name="InputOutputType">[Input] The type of the parameter. For more information, see "InputOutputType Argument" in "Comments."</param>
	/// <param name="ValueType">[Input] The C data type of the parameter. For more information, see "ValueType Argument" in "Comments."</param>
	/// <param name="ParameterType">[Input] The SQL data type of the parameter. For more information, see "ParameterType Argument" in "Comments."</param>
	/// <param name="ColumnSize">
	/// <para>
	/// [Input] The size of the column or expression of the corresponding parameter marker. For more information, see "ColumnSize Argument"
	/// in "Comments."
	/// </para>
	/// <para>If your application will run on a 64-bit Windows operating system, see ODBC 64-Bit Information.</para>
	/// </param>
	/// <param name="DecimalDigits">
	/// [Input] The decimal digits of the column or expression of the corresponding parameter marker. For more information about column size,
	/// see Column Size, Decimal Digits, Transfer Octet Length, and Display Size.
	/// </param>
	/// <param name="ParameterValuePtr">
	/// [Deferred Input] A pointer to a buffer for the parameter's data. For more information, see "ParameterValuePtr Argument" in "Comments."
	/// </param>
	/// <param name="BufferLength">
	/// <para>[Input/Output] Length of the ParameterValuePtr buffer in bytes. For more information, see "BufferLength Argument" in "Comments."</para>
	/// <para>See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.</para>
	/// </param>
	/// <param name="StrLen_or_IndPtr">
	/// [Deferred Input] A pointer to a buffer for the parameter's length. For more information, see "StrLen_or_IndPtr Argument" in "Comments."
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16 SQLRETURN
	// SQLBindParameter( SQLHSTMT StatementHandle, uint ParameterNumber, short InputOutputType, short ValueType, short ParameterType, nuint
	// ColumnSize, short DecimalDigits, IntPtr ParameterValuePtr, nint BufferLength, nint * StrLen_or_IndPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLBindParameter(SQLHSTMT StatementHandle, uint ParameterNumber,
		short InputOutputType, SQL_C ValueType, short ParameterType, nuint ColumnSize,
		short DecimalDigits, IntPtr ParameterValuePtr, nint BufferLength, ref nint StrLen_or_IndPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 2.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLBindParameter</c> binds a buffer to a parameter marker in an SQL statement. <c>SQLBindParameter</c> supports
	/// binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>This function replaces the ODBC 1.0 function <c>SQLSetParam</c>. For more information, see "Comments."</para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ParameterNumber">[Input] Parameter number, ordered sequentially in increasing parameter order, starting at 1.</param>
	/// <param name="InputOutputType">[Input] The type of the parameter. For more information, see "InputOutputType Argument" in "Comments."</param>
	/// <param name="ValueType">[Input] The C data type of the parameter. For more information, see "ValueType Argument" in "Comments."</param>
	/// <param name="ParameterType">[Input] The SQL data type of the parameter. For more information, see "ParameterType Argument" in "Comments."</param>
	/// <param name="ColumnSize">
	/// <para>
	/// [Input] The size of the column or expression of the corresponding parameter marker. For more information, see "ColumnSize Argument"
	/// in "Comments."
	/// </para>
	/// <para>If your application will run on a 64-bit Windows operating system, see ODBC 64-Bit Information.</para>
	/// </param>
	/// <param name="DecimalDigits">
	/// [Input] The decimal digits of the column or expression of the corresponding parameter marker. For more information about column size,
	/// see Column Size, Decimal Digits, Transfer Octet Length, and Display Size.
	/// </param>
	/// <param name="ParameterValuePtr">
	/// [Deferred Input] A pointer to a buffer for the parameter's data. For more information, see "ParameterValuePtr Argument" in "Comments."
	/// </param>
	/// <param name="BufferLength">
	/// <para>[Input/Output] Length of the ParameterValuePtr buffer in bytes. For more information, see "BufferLength Argument" in "Comments."</para>
	/// <para>See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.</para>
	/// </param>
	/// <param name="StrLen_or_IndPtr">
	/// [Deferred Input] A pointer to a buffer for the parameter's length. For more information, see "StrLen_or_IndPtr Argument" in "Comments."
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16 SQLRETURN
	// SQLBindParameter( SQLHSTMT StatementHandle, uint ParameterNumber, short InputOutputType, short ValueType, short ParameterType, nuint
	// ColumnSize, short DecimalDigits, IntPtr ParameterValuePtr, nint BufferLength, nint * StrLen_or_IndPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLBindParameter(SQLHSTMT StatementHandle, uint ParameterNumber,
		short InputOutputType, SQL_C ValueType, short ParameterType, nuint ColumnSize,
		short DecimalDigits, IntPtr ParameterValuePtr, nint BufferLength, [In, Out, Optional] IntPtr StrLen_or_IndPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLBrowseConnect</c> supports an iterative method of discovering and enumerating the attributes and attribute values
	/// required to connect to a data source. Each call to <c>SQLBrowseConnect</c> returns successive levels of attributes and attribute
	/// values. When all levels have been enumerated, a connection to the data source is completed and a complete connection string is
	/// returned by <c>SQLBrowseConnect</c>. A return code of SQL_SUCCESS or SQL_SUCCESS_WITH_INFO indicates that all connection information
	/// has been specified and the application is now connected to the data source.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="InConnectionString">[Input] Browse request connection string (see "InConnectionString Argument" in "Comments").</param>
	/// <param name="StringLength1">[Input] Length of *InConnectionString in characters.</param>
	/// <param name="OutConnectionString">
	/// <para>
	/// [Output] Pointer to a character buffer in which to return the browse result connection string (see "OutConnectionString Argument" in "Comments").
	/// </para>
	/// <para>
	/// If OutConnectionString is NULL, StringLength2Ptr will still return the total number of characters (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by OutConnectionString.
	/// </para>
	/// </param>
	/// <param name="BufferLength">[Input] Length, in characters, of the *OutConnectionString buffer.</param>
	/// <param name="StringLength2Ptr">
	/// [Output] The total number of characters (excluding null-termination) available to return in *OutConnectionString. If the number of
	/// characters available to return is greater than or equal to BufferLength, the connection string in *OutConnectionString is truncated
	/// to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbrowseconnect-function?view=sql-server-ver16 SQLRETURN
	// SQLBrowseConnect( SQLHDBC ConnectionHandle, byte * InConnectionString, short StringLength1, byte * OutConnectionString, short
	// BufferLength, short * StringLength2Ptr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLBrowseConnect(SQLHDBC ConnectionHandle, string InConnectionString,
		short StringLength1, [Out] StringBuilder? OutConnectionString, short BufferLength,
		out short StringLength2Ptr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLBulkOperations</c> performs bulk insertions and bulk bookmark operations, including update, delete, and fetch by bookmark.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="Operation">
	/// <para>[Input] Operation to perform:</para>
	/// <para>SQL_ADD SQL_UPDATE_BY_BOOKMARK SQL_DELETE_BY_BOOKMARK SQL_FETCH_BY_BOOKMARK</para>
	/// <para>For more information, see "Comments."</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbulkoperations-function?view=sql-server-ver16 SQLRETURN
	// SQLBulkOperations( SQLHSTMT StatementHandle, uint Operation);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLBulkOperations(SQLHSTMT StatementHandle, SQLBulkOperation Operation);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLCancel</c> cancels the processing on a statement.</para>
	/// <para>To cancel processing on a connection or statement, use SQLCancelHandle Function.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcancel-function?view=sql-server-ver16 SQLRETURN SQLCancel( SQLHSTMT StatementHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLCancel(SQLHSTMT StatementHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.8 Standards Compliance: None</para>
	/// <para>
	/// It is expected that most ODBC 3.8 (and later) drivers will implement this function. If a driver does not, a call to
	/// <c>SQLCancelHandle</c> with a connection handle in the Handle parameter will return SQL_ERROR with a SQLSTATE of IM001 and message
	/// 'Driver does not support this function'' A call to <c>SQLCancelHandle</c> with a statement handle as the Handle parameter will be
	/// mapped to a call to <c>SQLCancel</c> by the Driver Manager and can be processed if the driver implements <c>SQLCancel</c>. An
	/// application can use <c>SQLGetFunctions</c> to determine if a driver supports <c>SQLCancelHandle</c>.
	/// </para>
	/// <para>
	/// <c>Summary</c><c>SQLCancelHandle</c> cancels the processing on a connection or statement. The Driver Manager maps a call to
	/// <c>SQLCancelHandle</c> to a call to <c>SQLCancel</c> when HandleType is SQL_HANDLE_STMT.
	/// </para>
	/// </summary>
	/// <param name="HandleType">[Input] The type of the handle on which to cacel processing. Valid values are SQL_HANDLE_DBC or SQL_HANDLE_STMT.</param>
	/// <param name="Handle">
	/// <para>[Input] The handle on which to cancel processing.</para>
	/// <para>If Handle is not a valid handle of the type specified by HandleType, <c>SQLCancelHandle</c> returns SQL_INVALID_HANDLE.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcancelhandle-function?view=sql-server-ver16 SQLRETURN SQLCancelHandle(
	// SQL_HANDLE HandleType, IntPtr Handle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLCancelHandle(SQL_HANDLE HandleType, IntPtr Handle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLCloseCursor</c> closes a cursor that has been opened on a statement and discards pending results.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlclosecursor-function?view=sql-server-ver16 SQLRETURN SQLCloseCursor(
	// SQLHSTMT StatementHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLColAttribute</c> returns descriptor information for a column in a result set. Descriptor information is returned
	/// as a character string, a descriptor-dependent value, or an integer value.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnNumber">
	/// <para>
	/// [Input] The number of the record in the IRD from which the field value is to be retrieved. This argument corresponds to the column
	/// number of result data, ordered sequentially in increasing column order, starting at 1. Columns can be described in any order.
	/// </para>
	/// <para>
	/// Column 0 can be specified in this argument, but all values except SQL_DESC_TYPE and SQL_DESC_OCTET_LENGTH will return undefined values.
	/// </para>
	/// </param>
	/// <param name="FieldIdentifier">
	/// [Input] The descriptor handle. This handle defines which field in the IRD should be queried (for example, SQL_COLUMN_TABLE_NAME).
	/// </param>
	/// <param name="CharacterAttributePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the value in the FieldIdentifier field of the ColumnNumber row of the IRD, if the
	/// field is a character string. Otherwise, the field is unused.
	/// </para>
	/// <para>
	/// If CharacterAttributePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by CharacterAttributePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If FieldIdentifier is an ODBC-defined field and CharacterAttributePtr points to a character string or binary buffer, this
	/// argument should be the length of *CharacterAttributePtr. If FieldIdentifier is an ODBC-defined field and *CharacterAttributePtr is an
	/// integer, this field is ignored. If the *CharacterAttributePtr is a Unicode string (when calling <c>SQLColAttributeW</c>), the
	/// BufferLength argument must be an even number. If FieldIdentifier is a driver-defined field, the application indicates the nature of
	/// the field to the Driver Manager by setting the BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If CharacterAttributePtr is a pointer to a pointer, BufferLength should have the value SQL_IS_POINTER.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If CharacterAttributePtr is a pointer to a character string, the BufferLength is the length of the buffer.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If CharacterAttributePtr is a pointer to a binary buffer, the application places the result of the SQL_LEN_BINARY_ATTR(length) macro
	/// in BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If CharacterAttributePtr is a pointer to a fixed-length data type, BufferLength must be one of the following: SQL_IS_INTEGER,
	/// SQL_IS_UINTEGER, SQL_IS_SMALLINT, or SQL_IS_USMALLINT.
	/// </para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the total number of bytes (excluding the null-termination byte for character data)
	/// available to return in *CharacterAttributePtr.
	/// </para>
	/// <para>
	/// For character data, if the number of bytes available to return is greater than or equal to BufferLength, the descriptor information
	/// in *CharacterAttributePtr is truncated to BufferLength minus the length of a null-termination character and is null-terminated by the driver.
	/// </para>
	/// <para>
	/// For all other types of data, the value of BufferLength is ignored and the driver assumes the size of *CharacterAttributePtr is 32 bits.
	/// </para>
	/// </param>
	/// <param name="NumericAttributePtr">
	/// [Output] Pointer to an integer buffer in which to return the value in the FieldIdentifier field of the ColumnNumber row of the IRD,
	/// if the field is a numeric descriptor type, such as SQL_DESC_COLUMN_LENGTH. Otherwise, the field is unused. Please note that some
	/// drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged. Therefore, applications
	/// should initialize the value to 0 before calling this function.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function?view=sql-server-ver16 SQLRETURN SQLColAttribute (
	// SQLHSTMT StatementHandle, uint ColumnNumber, uint FieldIdentifier, IntPtr CharacterAttributePtr, short BufferLength, short *
	// StringLengthPtr, nint * NumericAttributePtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLColAttribute(SQLHSTMT StatementHandle, ushort ColumnNumber,
		SQL_DESC FieldIdentifier, [Out, Optional] IntPtr CharacterAttributePtr, short BufferLength,
		out short StringLengthPtr, out nint NumericAttributePtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLColAttribute</c> returns descriptor information for a column in a result set. Descriptor information is returned
	/// as a character string, a descriptor-dependent value, or an integer value.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnNumber">
	/// <para>
	/// [Input] The number of the record in the IRD from which the field value is to be retrieved. This argument corresponds to the column
	/// number of result data, ordered sequentially in increasing column order, starting at 1. Columns can be described in any order.
	/// </para>
	/// <para>
	/// Column 0 can be specified in this argument, but all values except SQL_DESC_TYPE and SQL_DESC_OCTET_LENGTH will return undefined values.
	/// </para>
	/// </param>
	/// <param name="FieldIdentifier">
	/// [Input] The descriptor handle. This handle defines which field in the IRD should be queried (for example, SQL_COLUMN_TABLE_NAME).
	/// </param>
	/// <returns>
	/// <para>
	/// [Output] Return the value in the FieldIdentifier field of the ColumnNumber row of the IRD, if the field is a numeric descriptor type,
	/// such as SQL_DESC_COLUMN_LENGTH. Otherwise, the field is unused. Please note that some drivers may only write the lower 32-bit or
	/// 16-bit of a buffer and leave the higher-order bit unchanged.
	/// </para>
	/// <para>OR</para>
	/// <para>[Output] Return the value in the FieldIdentifier field of the ColumnNumber row of the IRD, if the field is a character string.</para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function?view=sql-server-ver16 SQLRETURN SQLColAttribute (
	// SQLHSTMT StatementHandle, uint ColumnNumber, uint FieldIdentifier, IntPtr CharacterAttributePtr, short BufferLength, short *
	// StringLengthPtr, nint * NumericAttributePtr);
	[PInvokeData("sql.h")]
	public static T SQLColAttribute<T>(SQLHSTMT StatementHandle, ushort ColumnNumber, SQL_DESC FieldIdentifier)
	{
		//if (!CorrespondingTypeAttribute.CanGet(FieldIdentifier, typeof(T)))
		//	throw new ArgumentException("Cannot get this type of value from this FieldIdentifier.");
		if (typeof(T) == typeof(string))
		{
			SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, default, 0, out var sz, out _).ThrowIfFailed(StatementHandle);
			using SafeLPTSTR str = new(sz + 1);
			SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, str, (short)str.Size, out _, out _).ThrowIfFailed(StatementHandle);
			return (T)(object)(str.ToString() ?? "");
		}
		else
		{
			SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, default, 0, out _, out var val).ThrowIfFailed(StatementHandle);
			return typeof(T).IsEnum ? (T)Enum.ToObject(typeof(T), val) : (T)Convert.ChangeType((long)val, typeof(T));
		}
	}

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLColumnPrivileges</c> returns a list of columns and associated privileges for the specified table. The driver
	/// returns the information as a result set on the specified StatementHandle.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name. If a driver supports names for some catalogs but not for others,such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") denotes those catalogs that do not have names. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] Schema name. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") denotes those tables that do not have schemas. SchemaName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier. If it is SQL_FALSE,
	/// SchemaName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] Table name. This argument cannot be a null pointer. TableName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <param name="ColumnName">
	/// <para>[Input] String search pattern for column names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ColumnName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, ColumnName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength4">[Input] Length in characters of *ColumnName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumnprivileges-function?view=sql-server-ver16 SQLRETURN
	// SQLColumnPrivileges( SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte *
	// TableName, short NameLength3, byte * ColumnName, short NameLength4);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLColumnPrivileges(SQLHSTMT StatementHandle, string CatalogName,
		short NameLength1, string SchemaName, short NameLength2, string TableName,
		short NameLength3, string ColumnName, short NameLength4);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: Open Group</para>
	/// <para>
	/// <c>Summary</c><c>SQLColumns</c> returns the list of column names in specified tables. The driver returns this information as a result
	/// set on the specified StatementHandle.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") indicates those tables that do not have catalogs. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] String search pattern for schema names. If a driver supports schemas for some tables but not for others, such as when the
	/// driver retrieves data from different DBMSs, an empty string ("") indicates those tables that do not have schemas.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] String search pattern for table names.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <param name="ColumnName">
	/// <para>[Input] String search pattern for column names.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ColumnName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, ColumnName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </para>
	/// </param>
	/// <param name="NameLength4">[Input] Length in characters of *ColumnName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumns-function?view=sql-server-ver16 SQLRETURN SQLColumns( SQLHSTMT
	// StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte * TableName, short NameLength3,
	// byte * ColumnName, short NameLength4);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLColumns(SQLHSTMT StatementHandle, string CatalogName, short NameLength1,
		string SchemaName, short NameLength2, string TableName, short NameLength3,
		string ColumnName, short NameLength4);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLConnect</c> establishes connections to a driver and a data source. The connection handle references storage of
	/// all information about the connection to the data source, including status, transaction state, and error information.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="ServerName">
	/// [Input] Data source name. The data might be located on the same computer as the program, or on another computer somewhere on a
	/// network. For information about how an application chooses a data source, see Choosing a Data Source or Driver.
	/// </param>
	/// <param name="NameLength1">[Input] Length of *ServerName in characters.</param>
	/// <param name="UserName">[Input] User identifier.</param>
	/// <param name="NameLength2">[Input] Length of *UserName in characters.</param>
	/// <param name="Authentication">[Input] Authentication string (typically the password).</param>
	/// <param name="NameLength3">[Input] Length of *Authentication in characters.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconnect-function?view=sql-server-ver16 SQLRETURN SQLConnect( SQLHDBC
	// ConnectionHandle, byte * ServerName, short NameLength1, byte * UserName, short NameLength2, byte * Authentication, short NameLength3);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLConnect(SQLHDBC ConnectionHandle, string ServerName, short NameLength1,
		string UserName, short NameLength2, string Authentication, short NameLength3);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLCopyDesc</c> copies descriptor information from one descriptor handle to another.</para>
	/// </summary>
	/// <param name="SourceDescHandle">[Input] Source descriptor handle.</param>
	/// <param name="TargetDescHandle">
	/// [Input] Target descriptor handle. The TargetDescHandle argument can be a handle to an application descriptor or an IPD.
	/// TargetDescHandle cannot be set to a handle to an IRD, or <c>SQLCopyDesc</c> will return SQLSTATE HY016 (Cannot modify an
	/// implementation row descriptor).
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcopydesc-function?view=sql-server-ver16 SQLRETURN SQLCopyDesc( SQLHDESC
	// SourceDescHandle, SQLHDESC TargetDescHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLDataSources</c> returns information about a data source. This function is implemented only by the Driver Manager.
	/// </para>
	/// </summary>
	/// <param name="EnvironmentHandle">[Input] Environment handle.</param>
	/// <param name="Direction">
	/// <para>[Input] Determines which data source the Driver Manager returns information about. Can be:</para>
	/// <para>
	/// SQL_FETCH_NEXT (to fetch the next data source name in the list), SQL_FETCH_FIRST (to fetch from the beginning of the list),
	/// SQL_FETCH_FIRST_USER (to fetch the first user DSN), or SQL_FETCH_FIRST_SYSTEM (to fetch the first system DSN).
	/// </para>
	/// <para>
	/// When Direction is set to SQL_FETCH_FIRST, subsequent calls to <c>SQLDataSources</c> with Direction set to SQL_FETCH_NEXT return both
	/// user and system DSNs. When Direction is set to SQL_FETCH_FIRST_USER, all subsequent calls to <c>SQLDataSources</c> with Direction set
	/// to SQL_FETCH_NEXT return only user DSNs. When Direction is set to SQL_FETCH_FIRST_SYSTEM, all subsequent calls to
	/// <c>SQLDataSources</c> with Direction set to SQL_FETCH_NEXT return only system DSNs.
	/// </para>
	/// </param>
	/// <param name="ServerName">
	/// <para>[Output] Pointer to a buffer in which to return the data source name.</para>
	/// <para>
	/// If ServerName is NULL, NameLength1Ptr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ServerName.
	/// </para>
	/// </param>
	/// <param name="BufferLength1">
	/// [Input] Length of the *ServerName buffer, in characters; this does not need to be longer than SQL_MAX_DSN_LENGTH plus the
	/// null-termination character.
	/// </param>
	/// <param name="NameLength1Ptr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination character) available
	/// to return in *ServerName. If the number of characters available to return is greater than or equal to BufferLength1, the data source
	/// name in *ServerName is truncated to BufferLength1 minus the length of a null-termination character.
	/// </param>
	/// <param name="Description">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the description of the driver associated with the data source. For example, dBASE or
	/// SQL Server.
	/// </para>
	/// <para>
	/// If Description is NULL, NameLength2Ptr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by Description.
	/// </para>
	/// </param>
	/// <param name="BufferLength2">[Input] Length in characters of the *Description buffer.</param>
	/// <param name="NameLength2Ptr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination character) available
	/// to return in *Description. If the number of characters available to return is greater than or equal to BufferLength2, the driver
	/// description in *Description is truncated to BufferLength2 minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldatasources-function?view=sql-server-ver16 SQLRETURN SQLDataSources(
	// SQLHENV EnvironmentHandle, uint Direction, byte * ServerName, short BufferLength1, short * NameLength1Ptr, byte * Description, short
	// BufferLength2, short * NameLength2Ptr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLDataSources(SQLHENV EnvironmentHandle, uint Direction, string? ServerName,
		short BufferLength1, out short NameLength1Ptr, string? Description, short BufferLength2,
		out short NameLength2Ptr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLDescribeCol</c> returns the result descriptor - column name,type, column size, decimal digits, and nullability -
	/// for one column in the result set. This information also is available in the fields of the IRD.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnNumber">
	/// [Input] Column number of result data, ordered sequentially in increasing column order, starting at 1. The ColumnNumber argument can
	/// also be set to 0 to describe the bookmark column.
	/// </param>
	/// <param name="ColumnName">
	/// <para>
	/// [Output] Pointer to a null-terminated buffer in which to return the column name. This value is read from the SQL_DESC_NAME field of
	/// the IRD. If the column is unnamed or the column name cannot be determined, the driver returns an empty string.
	/// </para>
	/// <para>
	/// If ColumnName is NULL, NameLengthPtr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ColumnName.
	/// </para>
	/// </param>
	/// <param name="BufferLength">[Input] Length of the *ColumnName buffer, in characters.</param>
	/// <param name="NameLengthPtr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the null termination) available to return
	/// in *ColumnName. If the number of characters available to return is greater than or equal to BufferLength, the column name in
	/// *ColumnName is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <param name="DataTypePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the SQL data type of the column. This value is read from the SQL_DESC_CONCISE_TYPE
	/// field of the IRD. This will be one of the values in SQL Data Types, or a driver-specific SQL data type. If the data type cannot be
	/// determined, the driver returns SQL_UNKNOWN_TYPE.
	/// </para>
	/// <para>
	/// In ODBC 3.x, SQL_TYPE_DATE, SQL_TYPE_TIME, or SQL_TYPE_TIMESTAMP is returned in *DataTypePtr for date, time, or timestamp data,
	/// respectively; in ODBC 2.x, SQL_DATE, SQL_TIME, or SQL_TIMESTAMP is returned. The Driver Manager performs the required mappings when
	/// an ODBC 2.x application is working with an ODBC 3.x driver or when an ODBC 3.x application is working with an ODBC 2.x driver.
	/// </para>
	/// <para>
	/// When ColumnNumber is equal to 0 (for a bookmark column), SQL_BINARY is returned in *DataTypePtr for variable-length bookmarks.
	/// (SQL_INTEGER is returned if bookmarks are used by an ODBC 3.x application working with an ODBC 2.x driver or by an ODBC 2.x
	/// application working with an ODBC 3.x driver.)
	/// </para>
	/// <para>
	/// For more information on these data types, see SQL Data Types in Appendix D: Data Types. For information about driver-specific SQL
	/// data types, see the driver's documentation.
	/// </para>
	/// </param>
	/// <param name="ColumnSizePtr">
	/// [Output] Pointer to a buffer in which to return the size (in characters) of the column on the data source. If the column size cannot
	/// be determined, the driver returns 0. For more information on column size, see Column Size, Decimal Digits, Transfer Octet Length, and
	/// Display Size in Appendix D: Data Types.
	/// </param>
	/// <param name="DecimalDigitsPtr">
	/// [Output] Pointer to a buffer in which to return the number of decimal digits of the column on the data source. If the number of
	/// decimal digits cannot be determined or is not applicable, the driver returns 0. For more information on decimal digits, see Column
	/// Size, Decimal Digits, Transfer Octet Length, and Display Size in Appendix D: Data Types.
	/// </param>
	/// <param name="NullablePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return a value that indicates whether the column allows NULL values. This value is read from
	/// the SQL_DESC_NULLABLE field of the IRD. The value is one of the following:
	/// </para>
	/// <para>SQL_NO_NULLS: The column does not allow NULL values.</para>
	/// <para>SQL_NULLABLE: The column allows NULL values.</para>
	/// <para>SQL_NULLABLE_UNKNOWN: The driver cannot determine if the column allows NULL values.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldescribecol-function?view=sql-server-ver16 SQLRETURN SQLDescribeCol(
	// SQLHSTMT StatementHandle, uint ColumnNumber, byte * ColumnName, short BufferLength, short * NameLengthPtr, short * DataTypePtr, nuint
	// * ColumnSizePtr, short * DecimalDigitsPtr, short * NullablePtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLDescribeCol(SQLHSTMT StatementHandle, uint ColumnNumber,
		string? ColumnName, short BufferLength, out short NameLengthPtr, out SQL_TYPE DataTypePtr,
		out nuint ColumnSizePtr, out short DecimalDigitsPtr, out SQL_NULLABILITY NullablePtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLDescribeParam</c> returns the description of a parameter marker associated with a prepared SQL statement. This
	/// information is also available in the fields of the IPD.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ParameterNumber">[Input] Parameter marker number ordered sequentially in increasing parameter order, starting at 1.</param>
	/// <param name="DataTypePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the SQL data type of the parameter. This value is read from the SQL_DESC_CONCISE_TYPE
	/// record field of the IPD. This will be one of the values in the SQL Data Types section of Appendix D: Data Types, or a driver-specific
	/// SQL data type.
	/// </para>
	/// <para>
	/// In ODBC 3.x, SQL_TYPE_DATE, SQL_TYPE_TIME, or SQL_TYPE_TIMESTAMP will be returned in *DataTypePtr for date, time, or timestamp data,
	/// respectively; in ODBC 2.x, SQL_DATE, SQL_TIME, or SQL_TIMESTAMP will be returned. The Driver Manager performs the required mappings
	/// when an ODBC 2.x application is working with an ODBC 3.x driver or when an ODBC 3.x application is working with an ODBC 2.x driver.
	/// </para>
	/// <para>
	/// When ColumnNumber is equal to 0 (for a bookmark column), SQL_BINARY is returned in *DataTypePtr for variable-length bookmarks.
	/// (SQL_INTEGER is returned if bookmarks are used by an ODBC 3.x application working with an ODBC 2.x driver or by an ODBC 2.x
	/// application working with an ODBC 3.x driver.)
	/// </para>
	/// <para>
	/// For more information, see SQL Data Types in Appendix D: Data Types. For information about driver-specific SQL data types, see the
	/// driver's documentation.
	/// </para>
	/// </param>
	/// <param name="ParameterSizePtr">
	/// [Output] Pointer to a buffer in which to return the size, in characters, of the column or expression of the corresponding parameter
	/// marker as defined by the data source. For more information about column size, see Column Size, Decimal Digits, Transfer Octet Length,
	/// and Display Size.
	/// </param>
	/// <param name="DecimalDigitsPtr">
	/// [Output] Pointer to a buffer in which to return the number of decimal digits of the column or expression of the corresponding
	/// parameter as defined by the data source. For more information about decimal digits, see Column Size, Decimal Digits, Transfer Octet
	/// Length, and Display Size.
	/// </param>
	/// <param name="NullablePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return a value that indicates whether the parameter allows NULL values. This value is read
	/// from the SQL_DESC_NULLABLE field of the IPD. One of the following:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>SQL_NO_NULLS: The parameter does not allow NULL values (this is the default value).</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULLABLE: The parameter allows NULL values.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULLABLE_UNKNOWN: The driver cannot determine whether the parameter allows NULL values.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldescribeparam-function?view=sql-server-ver16 SQLRETURN
	// SQLDescribeParam( SQLHSTMT StatementHandle, uint ParameterNumber, short * DataTypePtr, nuint * ParameterSizePtr, short *
	// DecimalDigitsPtr, short * NullablePtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLDescribeParam(SQLHSTMT StatementHandle, uint ParameterNumber,
		out SQL_TYPE DataTypePtr, out nuint ParameterSizePtr, out short DecimalDigitsPtr,
		out SQL_NULLABILITY NullablePtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLDisconnect</c> closes the connection associated with a specific connection handle.</para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldisconnect-function?view=sql-server-ver16 SQLRETURN SQLDisconnect(
	// SQLHDBC ConnectionHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLDriverConnect</c> is an alternative to <c>SQLConnect</c>. It supports data sources that require more connection
	/// information than the three arguments in <c>SQLConnect</c>, dialog boxes to prompt the user for all connection information, and data
	/// sources that are not defined in the system information. For more information, see Connecting with SQLDriverConnect.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="WindowHandle">
	/// [Input] Window handle. The application can pass the handle of the parent window, if applicable, or a null pointer if either the
	/// window handle is not applicable or <c>SQLDriverConnect</c> will not present any dialog boxes.
	/// </param>
	/// <param name="InConnectionString">
	/// [Input] A full connection string (see the syntax in "Comments"), a partial connection string, or an empty string.
	/// </param>
	/// <param name="StringLength1">
	/// [Input] Length of *InConnectionString, in characters if the string is Unicode, or bytes if string is ANSI or DBCS.
	/// </param>
	/// <param name="OutConnectionString">
	/// <para>
	/// [Output] Pointer to a buffer for the completed connection string. Upon successful connection to the target data source, this buffer
	/// contains the completed connection string. Applications should allocate at least 1,024 characters for this buffer.
	/// </para>
	/// <para>
	/// If OutConnectionString is NULL, StringLength2Ptr will still return the total number of characters (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by OutConnectionString.
	/// </para>
	/// </param>
	/// <param name="BufferLength">[Input] Length of the *OutConnectionString buffer, in characters.</param>
	/// <param name="StringLength2Ptr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination character) available
	/// to return in *OutConnectionString. If the number of characters available to return is greater than or equal to BufferLength, the
	/// completed connection string in *OutConnectionString is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <param name="DriverCompletion">
	/// <para>[Input] Flag that indicates whether the Driver Manager or driver must prompt for more connection information:</para>
	/// <para>SQL_DRIVER_PROMPT, SQL_DRIVER_COMPLETE, SQL_DRIVER_COMPLETE_REQUIRED, or SQL_DRIVER_NOPROMPT.</para>
	/// <para>(For additional information, see "Comments.")</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldriverconnect-function?view=sql-server-ver16 SQLRETURN
	// SQLDriverConnect( SQLHDBC ConnectionHandle, SQLHWND WindowHandle, byte * InConnectionString, short StringLength1, byte *
	// OutConnectionString, short BufferLength, short * StringLength2Ptr, uint DriverCompletion);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLDriverConnect(SQLHDBC ConnectionHandle, HWND WindowHandle,
		string InConnectionString, short StringLength1, [Out] StringBuilder? OutConnectionString,
		short BufferLength, out short StringLength2Ptr, SQL_DRIVER DriverCompletion);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 2.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLDrivers</c> lists driver descriptions and driver attribute keywords. This function is implemented only by the
	/// Driver Manager.
	/// </para>
	/// </summary>
	/// <param name="EnvironmentHandle">[Input] Environment handle.</param>
	/// <param name="Direction">
	/// [Input] Determines whether the Driver Manager fetches the next driver description in the list (SQL_FETCH_NEXT) or whether the search
	/// starts from the beginning of the list (SQL_FETCH_FIRST).
	/// </param>
	/// <param name="DriverDescription">
	/// <para>[Output] Pointer to a buffer in which to return the driver description.</para>
	/// <para>
	/// If DriverDescription is NULL, DescriptionLengthPtr will still return the total number of characters (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by DriverDescription.
	/// </para>
	/// </param>
	/// <param name="BufferLength1">[Input] Length of the *DriverDescription buffer, in characters.</param>
	/// <param name="DescriptionLengthPtr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination character) available
	/// to return in *DriverDescription. If the number of characters available to return is greater than or equal to BufferLength1, the
	/// driver description in *DriverDescription is truncated to BufferLength1 minus the length of a null-termination character.
	/// </param>
	/// <param name="DriverAttributes">
	/// <para>[Output] Pointer to a buffer in which to return the list of driver attribute value pairs (see "Comments").</para>
	/// <para>
	/// If DriverAttributes is NULL, AttributesLengthPtr will still return the total number of bytes (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by DriverAttributes.
	/// </para>
	/// </param>
	/// <param name="BufferLength2">
	/// [Input] Length of the *DriverAttributes buffer, in characters. If the *DriverDescription value is a Unicode string (when calling
	/// <c>SQLDriversW</c>), the BufferLength argument must be an even number.
	/// </param>
	/// <param name="AttributesLengthPtr">
	/// [Output] Pointer to a buffer in which to return the total number of bytes (excluding the null-termination byte) available to return
	/// in *DriverAttributes. If the number of bytes available to return is greater than or equal to BufferLength2, the list of attribute
	/// value pairs in *DriverAttributes is truncated to BufferLength2 minus the length of the null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqldrivers-function?view=sql-server-ver16 SQLRETURN SQLDrivers( SQLHENV
	// EnvironmentHandle, uint Direction, byte * DriverDescription, short BufferLength1, short * DescriptionLengthPtr, byte *
	// DriverAttributes, short BufferLength2, short * AttributesLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLDrivers(SQLHENV EnvironmentHandle, SQL_FETCH Direction,
		string? DriverDescription, short BufferLength1, out short DescriptionLengthPtr,
		string? DriverAttributes, short BufferLength2, out short AttributesLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLEndTran</c> requests a commit or rollback operation for all active operations on all statements associated with a
	/// connection. <c>SQLEndTran</c> can also request that a commit or rollback operation be performed for all connections associated with
	/// an environment.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="HandleType">
	/// [Input] Handle type identifier. Contains either SQL_HANDLE_ENV (if Handle is an environment handle) or SQL_HANDLE_DBC (if Handle is a
	/// connection handle).
	/// </param>
	/// <param name="Handle">
	/// [Input] The handle, of the type indicated by HandleType, indicating the scope of the transaction. See "Comments" for more information.
	/// </param>
	/// <param name="CompletionType">
	/// <para>[Input] One of the following two values:</para>
	/// <para>SQL_COMMIT SQL_ROLLBACK</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlendtran-function?view=sql-server-ver16 SQLRETURN SQLEndTran( SQL_HANDLE
	// HandleType, IntPtr Handle, short CompletionType);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLEndTran(SQL_HANDLE HandleType, [In] IntPtr Handle, SQL_COMMIT CompletionType);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLExecDirect</c> executes a preparable statement, using the current values of the parameter marker variables if any
	/// parameters exist in the statement. <c>SQLExecDirect</c> is the fastest way to submit an SQL statement for one-time execution.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="StatementText">[Input] SQL statement to be executed.</param>
	/// <param name="TextLength">[Input] Length of *StatementText in characters.</param>
	/// <returns>
	/// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function?view=sql-server-ver16 SQLRETURN SQLExecDirect(
	// SQLHSTMT StatementHandle, byte * StatementText, int TextLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, string StatementText, int TextLength = SQL_NTS);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLExecute</c> executes a prepared statement, using the current values of the parameter marker variables if any
	/// parameter markers exist in the statement.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <returns>
	/// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecute-function?view=sql-server-ver16 SQLRETURN SQLExecute( SQLHSTMT StatementHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLExecute(SQLHSTMT StatementHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLFetch</c> fetches the next rowset of data from the result set and returns data for all bound columns.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetch-function?view=sql-server-ver16 SQLRETURN SQLFetch( SQLHSTMT StatementHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLFetch(SQLHSTMT StatementHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLFetchScroll</c> fetches the specified rowset of data from the result set and returns data for all bound columns.
	/// Rowsets can be specified at an absolute or relative position or by bookmark.
	/// </para>
	/// <para>
	/// When working with an ODBC 2.x driver, the Driver Manager maps this function to <c>SQLExtendedFetch</c>. For more information, see
	/// Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="FetchOrientation">
	/// <para>[Input]</para>
	/// <para>Type of fetch:</para>
	/// <para>SQL_FETCH_NEXT</para>
	/// <para>SQL_FETCH_PRIOR</para>
	/// <para>SQL_FETCH_FIRST</para>
	/// <para>SQL_FETCH_LAST</para>
	/// <para>SQL_FETCH_ABSOLUTE</para>
	/// <para>SQL_FETCH_RELATIVE</para>
	/// <para>SQL_FETCH_BOOKMARK</para>
	/// <para>For more information, see "Positioning the Cursor" in the "Comments" section.</para>
	/// </param>
	/// <param name="FetchOffset">
	/// <para>[Input]</para>
	/// <para>
	/// Number of the row to fetch. The interpretation of this argument depends on the value of the FetchOrientation argument. For more
	/// information, see "Positioning the Cursor" in the "Comments" section.
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetchscroll-function?view=sql-server-ver16 SQLRETURN SQLFetchScroll(
	// SQLHSTMT StatementHandle, short FetchOrientation, nint FetchOffset);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLFetchScroll(SQLHSTMT StatementHandle, SQL_FETCH_DIRECTION FetchOrientation, nint FetchOffset = 0);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para><c>Summary</c><c>SQLForeignKeys</c> can return:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>A list of foreign keys in the specified table (columns in the specified table that refer to primary keys in other tables).</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>A list of foreign keys in other tables that refer to the primary key in the specified table.</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>The driver returns each list as a result set on the specified statement.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="PKCatalogName">
	/// <para>
	/// [Input] Primary key table catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have catalogs. PKCatalogName cannot
	/// contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, PKCatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, PKCatalogName is an ordinary argument; it is treated literally, and its case is significant. For
	/// more information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length of *PKCatalogName, in characters.</param>
	/// <param name="PKSchemaName">
	/// <para>
	/// [Input] Primary key table schema name. If a driver supports schemas for some tables but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have schemas. PKSchemaName cannot contain
	/// a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, PKSchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, PKSchemaName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length of *PKSchemaName, in characters.</param>
	/// <param name="PKTableName">
	/// <para>[Input] Primary key table name. PKTableName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, PKTableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, PKTableName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length of *PKTableName, in characters.</param>
	/// <param name="FKCatalogName">
	/// <para>
	/// [Input] Foreign key table catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have catalogs. FKCatalogName cannot
	/// contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, FKCatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, FKCatalogName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength4">[Input] Length of *FKCatalogName, in characters.</param>
	/// <param name="FKSchemaName">
	/// <para>
	/// [Input] Foreign key table schema name. If a driver supports schemas for some tables but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have schemas. FKSchemaName cannot contain
	/// a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, FKSchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, FKSchemaName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength5">[Input] Length of *FKSchemaName, in characters.</param>
	/// <param name="FKTableName">
	/// <para>[Input] Foreign key table name. FKTableName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, FKTableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, FKTableName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength6">[Input] Length of *FKTableName, in characters.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function?view=sql-server-ver16 SQLRETURN SQLForeignKeys(
	// SQLHSTMT StatementHandle, byte * PKCatalogName, short NameLength1, byte * PKSchemaName, short NameLength2, byte * PKTableName, short
	// NameLength3, byte * FKCatalogName, short NameLength4, byte * FKSchemaName, short NameLength5, byte * FKTableName, short NameLength6);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLForeignKeys(SQLHSTMT StatementHandle, string PKCatalogName,
		short NameLength1, string PKSchemaName, short NameLength2, string PKTableName,
		short NameLength3, string FKCatalogName, short NameLength4, string FKSchemaName,
		short NameLength5, string FKTableName, short NameLength6);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLFreeHandle</c> frees resources associated with a specific environment, connection, statement, or descriptor handle.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// This function is a generic function for freeing handles. It replaces the ODBC 2.0 functions <c>SQLFreeConnect</c> (for freeing a
	/// connection handle) and <c>SQLFreeEnv</c> (for freeing an environment handle). <c>SQLFreeConnect</c> and <c>SQLFreeEnv</c> are both
	/// deprecated in ODBC 3*.x*. <c>SQLFreeHandle</c> also replaces the ODBC 2.0 function <c>SQLFreeStmt</c> (with the SQL_DROP Option) for
	/// freeing a statement handle. For more information, see "Comments." For more information about what the Driver Manager maps this
	/// function to when an ODBC 3*.x* application is working with an ODBC 2*.x* driver, see Mapping Replacement Functions for Backward
	/// Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="HandleType">
	/// <para>[Input] The type of handle to be freed by <c>SQLFreeHandle</c>. Must be one of the following values:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC_INFO_TOKEN</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DESC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_ENV</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_STMT</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// SQL_HANDLE_DBC_INFO_TOKEN handle is used only by the Driver Manager and driver. Applications should not use this handle type. For
	/// more information about SQL_HANDLE_DBC_INFO_TOKEN, see Developing Connection-Pool Awareness in an ODBC Driver.
	/// </para>
	/// <para>If HandleType is not one of these values, <c>SQLFreeHandle</c> returns SQL_INVALID_HANDLE.</para>
	/// </param>
	/// <param name="Handle">[Input] The handle to be freed.</param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_ERROR, or SQL_INVALID_HANDLE.</para>
	/// <para>If <c>SQLFreeHandle</c> returns SQL_ERROR, the handle is still valid.</para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreehandle-function?view=sql-server-ver16 SQLRETURN SQLFreeHandle(
	// SQL_HANDLE HandleType, IntPtr Handle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLFreeHandle(SQL_HANDLE HandleType, IntPtr Handle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLFreeHandle</c> frees resources associated with a specific environment, connection, statement, or descriptor handle.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// This function is a generic function for freeing handles. It replaces the ODBC 2.0 functions <c>SQLFreeConnect</c> (for freeing a
	/// connection handle) and <c>SQLFreeEnv</c> (for freeing an environment handle). <c>SQLFreeConnect</c> and <c>SQLFreeEnv</c> are both
	/// deprecated in ODBC 3*.x*. <c>SQLFreeHandle</c> also replaces the ODBC 2.0 function <c>SQLFreeStmt</c> (with the SQL_DROP Option) for
	/// freeing a statement handle. For more information, see "Comments." For more information about what the Driver Manager maps this
	/// function to when an ODBC 3*.x* application is working with an ODBC 2*.x* driver, see Mapping Replacement Functions for Backward
	/// Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="Handle">[Input] The handle to be freed.</param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_ERROR, or SQL_INVALID_HANDLE.</para>
	/// <para>If <c>SQLFreeHandle</c> returns SQL_ERROR, the handle is still valid.</para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreehandle-function?view=sql-server-ver16 SQLRETURN SQLFreeHandle(
	// SQL_HANDLE HandleType, IntPtr Handle);
	[PInvokeData("sql.h")]
	public static SQLRETURN SQLFreeHandle(ISQLHANDLE Handle) => SQLFreeHandle(Handle.GetHandleVal(), Handle.DangerousGetHandle());

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLFreeStmt</c> stops processing associated with a specific statement, closes any open cursors associated with the
	/// statement, discards pending results, or, optionally, frees all resources associated with the statement handle.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle</param>
	/// <param name="Option">
	/// <para>[Input] One of the following options:</para>
	/// <para>
	/// SQL_ CLOSE: Closes the cursor associated with StatementHandle (if one was defined) and discards all pending results. The application
	/// can reopen this cursor later by executing a <c>SELECT</c> statement again with the same or different parameter values. If no cursor
	/// is open, this option has no effect for the application. <c>SQLCloseCursor</c> can also be called to close a cursor. For more
	/// information, see Closing the Cursor.
	/// </para>
	/// <para>
	/// SQL_DROP: This option is deprecated. A call to <c>SQLFreeStmt</c> with an Option of SQL_DROP is mapped in the Driver Manager to SQLFreeHandle.
	/// </para>
	/// <para>
	/// SQL_UNBIND: Sets the SQL_DESC_COUNT field of the ARD to 0, releasing all column buffers bound by <c>SQLBindCol</c> for the given
	/// StatementHandle. This does not unbind the bookmark column; to do that, the SQL_DESC_DATA_PTR field of the ARD for the bookmark column
	/// is set to NULL. Notice that if this operation is performed on an explicitly allocated descriptor that is shared by more than one
	/// statement, the operation will affect the bindings of all statements that share the descriptor. For more information, see Overview of
	/// Retrieving Results (Basic).
	/// </para>
	/// <para>
	/// SQL_RESET_PARAMS: Sets the SQL_DESC_COUNT field of the APD to 0, releasing all parameter buffers set by <c>SQLBindParameter</c> for
	/// the given StatementHandle. If this operation is performed on an explicitly allocated descriptor that is shared by more than one
	/// statement, this operation will affect the bindings of all the statements that share the descriptor. For more information, see Binding Parameters.
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreestmt-function?view=sql-server-ver16 SQLRETURN SQLFreeStmt( SQLHSTMT
	// StatementHandle, uint Option);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLFreeStmt(SQLHSTMT StatementHandle, SQL_STMT Option);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetConnectAttr</c> returns the current setting of a connection attribute.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3*.x* application is working with an ODBC 2*.x*
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="Attribute">[Input] Attribute to retrieve.</param>
	/// <param name="ValuePtr">
	/// <para>
	/// [Output] A pointer to memory in which to return the current value of the attribute specified by Attribute. For integer-type
	/// attributes, some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged. Therefore,
	/// applications should use a buffer of nuint and initialize the value to 0 before calling this function.
	/// </para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If Attribute is an ODBC-defined attribute and ValuePtr points to a character string or a binary buffer, this argument should
	/// be the length of *ValuePtr. If Attribute is an ODBC-defined attribute and *ValuePtr is an integer, BufferLength is ignored. If the
	/// value in *ValuePtr is a Unicode string (when calling <c>SQLGetConnectAttrW</c>), the BufferLength argument must be an even number.
	/// </para>
	/// <para>
	/// If Attribute is a driver-defined attribute, the application indicates the nature of the attribute to the Driver Manager by setting
	/// the BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a character string, BufferLength is the length of the string.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a binary buffer, the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a value other than a character string or binary string, BufferLength should have the value SQL_IS_POINTER.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If *ValuePtr contains a fixed-length data type, BufferLength is either SQL_IS_INTEGER or SQL_IS_UINTEGER, as appropriate.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] A pointer to a buffer in which to return the total number of bytes (excluding the null-termination character) available to
	/// return in *ValuePtr. If the attribute value is a character string and the number of bytes available to return is greater than
	/// BufferLength minus the length of the null-termination character, the data in *ValuePtr is truncated to BufferLength minus the length
	/// of the null-termination character and is null-terminated by the driver.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetconnectattr-function?view=sql-server-ver16 SQLRETURN
	// SQLGetConnectAttr( SQLHDBC ConnectionHandle, int Attribute, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQL_ATTR Attribute, IntPtr ValuePtr,
		int BufferLength, out int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetConnectAttr</c> returns the current setting of a connection attribute.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3*.x* application is working with an ODBC 2*.x*
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="Attribute">[Input] Attribute to retrieve.</param>
	/// <param name="ValuePtr">
	/// <para>
	/// [Output] A pointer to memory in which to return the current value of the attribute specified by Attribute. For integer-type
	/// attributes, some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged. Therefore,
	/// applications should use a buffer of nuint and initialize the value to 0 before calling this function.
	/// </para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If Attribute is an ODBC-defined attribute and ValuePtr points to a character string or a binary buffer, this argument should
	/// be the length of *ValuePtr. If Attribute is an ODBC-defined attribute and *ValuePtr is an integer, BufferLength is ignored. If the
	/// value in *ValuePtr is a Unicode string (when calling <c>SQLGetConnectAttrW</c>), the BufferLength argument must be an even number.
	/// </para>
	/// <para>
	/// If Attribute is a driver-defined attribute, the application indicates the nature of the attribute to the Driver Manager by setting
	/// the BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a character string, BufferLength is the length of the string.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a binary buffer, the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a value other than a character string or binary string, BufferLength should have the value SQL_IS_POINTER.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If *ValuePtr contains a fixed-length data type, BufferLength is either SQL_IS_INTEGER or SQL_IS_UINTEGER, as appropriate.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] A pointer to a buffer in which to return the total number of bytes (excluding the null-termination character) available to
	/// return in *ValuePtr. If the attribute value is a character string and the number of bytes available to return is greater than
	/// BufferLength minus the length of the null-termination character, the data in *ValuePtr is truncated to BufferLength minus the length
	/// of the null-termination character and is null-terminated by the driver.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetconnectattr-function?view=sql-server-ver16 SQLRETURN
	// SQLGetConnectAttr( SQLHDBC ConnectionHandle, int Attribute, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQL_ATTR Attribute, string? ValuePtr,
		int BufferLength, out int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetCursorName</c> returns the cursor name associated with a specified statement.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CursorName">
	/// <para>[Output] Pointer to a buffer in which to return the cursor name.</para>
	/// <para>
	/// If CursorName is NULL, NameLengthPtr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by CursorName.
	/// </para>
	/// </param>
	/// <param name="BufferLength">[Input] Length of *CursorName, in characters.</param>
	/// <param name="NameLengthPtr">
	/// [Output] Pointer to memory in which to return the total number of characters (excluding the null-termination character) available to
	/// return in *CursorName. If the number of characters available to return is greater than or equal to BufferLength, the cursor name in
	/// *CursorName is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetcursorname-function?view=sql-server-ver16 SQLRETURN
	// SQLGetCursorName( SQLHSTMT StatementHandle, byte * CursorName, short BufferLength, short * NameLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetCursorName(SQLHSTMT StatementHandle, [Out] StringBuilder? CursorName,
		short BufferLength, out short NameLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetData</c> retrieves data for a single column in the result set or for a single parameter after
	/// <c>SQLParamData</c> returns SQL_PARAM_DATA_AVAILABLE. It can be called multiple times to retrieve variable-length data in parts.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="Col_or_Param_Num">
	/// <para>
	/// [Input] For retrieving column data, it is the number of the column for which to return data. Result set columns are numbered in
	/// increasing column order starting at 1. The bookmark column is column number 0; this can be specified only if bookmarks are enabled.
	/// </para>
	/// <para>For retrieving parameter data, it is the ordinal of the parameter, which starts at 1.</para>
	/// </param>
	/// <param name="TargetType">
	/// <para>
	/// [Input] The type identifier of the C data type of the *TargetValuePtr buffer. For a list of valid C data types and type identifiers,
	/// see the C Data Types section in Appendix D: Data Types.
	/// </para>
	/// <para>
	/// If TargetType is SQL_ARD_TYPE, the driver uses the type identifier specified in the SQL_DESC_CONCISE_TYPE field of the ARD. If
	/// TargetType is SQL_APD_TYPE, <c>SQLGetData</c> will use the same C data type that was specified in <c>SQLBindParameter</c>. Otherwise,
	/// the C data type specified in <c>SQLGetData</c> overrides the C data type specified in <c>SQLBindParameter</c>. If it is
	/// SQL_C_DEFAULT, the driver selects the default C data type based on the SQL data type of the source.
	/// </para>
	/// <para>You can also specify an extended C data type. For more information, see C Data Types in ODBC.</para>
	/// </param>
	/// <param name="TargetValuePtr">
	/// [Output] Pointer to the buffer in which to return the data.
	/// <para><paramref name="TargetValuePtr"/> cannot be NULL.</para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>[Input] Length of the *TargetValuePtr buffer in bytes.</para>
	/// <para>
	/// The driver uses BufferLength to avoid writing past the end of the *TargetValuePtr buffer when returning variable-length data, such as
	/// character or binary data. Note that the driver counts the null-termination character when returning character data to
	/// *TargetValuePtr. *TargetValuePtr must therefore contain space for the null-termination character, or the driver will truncate the data.
	/// </para>
	/// <para>
	/// When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the
	/// buffer is large enough to hold the data. It is therefore important for the application to allocate a large enough buffer for
	/// fixed-length data or the driver will write past the end of the buffer.
	/// </para>
	/// <para>
	/// <c>SQLGetData</c> returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength
	/// is 0.
	/// </para>
	/// </param>
	/// <param name="StrLen_or_IndPtr">
	/// <para>
	/// [Output] Pointer to the buffer in which to return the length or indicator value. If this is a null pointer, no length or indicator
	/// value is returned. This returns an error when the data being fetched is NULL.
	/// </para>
	/// <para><c>SQLGetData</c> can return the following values in the length/indicator buffer:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The length of the data available to return</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NO_TOTAL</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_NULL_DATA</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>For more information, see Using Length/Indicator Values and "Comments" in this topic.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdata-function?view=sql-server-ver16 SQLRETURN SQLGetData( SQLHSTMT
	// StatementHandle, uint Col_or_Param_Num, short TargetType, IntPtr TargetValuePtr, nint BufferLength, nint * StrLen_or_IndPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLGetData(SQLHSTMT StatementHandle, ushort Col_or_Param_Num,
		SQL_C TargetType, [Out] IntPtr TargetValuePtr, nint BufferLength, out nint StrLen_or_IndPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetDescField</c> returns the current setting or value of a single field of a descriptor record.</para>
	/// </summary>
	/// <param name="DescriptorHandle">[Input] Descriptor handle.</param>
	/// <param name="RecNumber">
	/// [Input] Indicates the descriptor record from which the application seeks information. Descriptor records are numbered from 0, with
	/// record number 0 being the bookmark record. If the FieldIdentifier argument indicates a header field, RecNumber is ignored. If
	/// RecNumber is less than or equal to SQL_DESC_COUNT but the row does not contain data for a column or parameter, a call to
	/// <c>SQLGetDescField</c> will return the default values of the fields. (For more information, see "Initialization of Descriptor Fields"
	/// in SQLSetDescField.)
	/// </param>
	/// <param name="FieldIdentifier">
	/// [Input] Indicates the field of the descriptor whose value is to be returned. For more information, see the "FieldIdentifier Argument"
	/// section in SQLSetDescField.
	/// </param>
	/// <param name="ValuePtr">
	/// <para>[Output] Pointer to a buffer in which to return the descriptor information. The data type depends on the value of FieldIdentifier.</para>
	/// <para>
	/// If ValuePtr is integer type, applications should use a buffer of nuint and initialize the value to 0 before calling this function as
	/// some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged.
	/// </para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If FieldIdentifier is an ODBC-defined field and ValuePtr points to a character string or a binary buffer, this argument
	/// should be the length of *ValuePtr. If FieldIdentifier is an ODBC-defined field and *ValuePtr is an integer, BufferLength is ignored.
	/// If the value in *ValuePtr is of a Unicode data type (when calling <c>SQLGetDescFieldW</c>), the BufferLength argument must be an even number.
	/// </para>
	/// <para>
	/// If FieldIdentifier is a driver-defined field, the application indicates the nature of the field to the Driver Manager by setting the
	/// BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a character string, then BufferLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a value other than a character string or binary string, then BufferLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is contains a fixed-length data type, then BufferLength is either SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or
	/// SQL_IS_USMALLINT, as appropriate.
	/// </para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] Pointer to the buffer in which to return the total number of bytes (excluding the number of bytes required for the
	/// null-termination character) available to return in *ValuePtr.
	/// </param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.</para>
	/// <para>SQL_NO_DATA is returned if RecNumber is greater than the current number of descriptor records.</para>
	/// <para>
	/// SQL_NO_DATA is returned if DescriptorHandle is an IRD handle and the statement is in the prepared or executed state but there was no
	/// open cursor associated with it.
	/// </para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescfield-function?view=sql-server-ver16 SQLRETURN SQLGetDescField(
	// SQLHDESC DescriptorHandle, short RecNumber, short FieldIdentifier, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle, short RecNumber,
		SQL_DESC FieldIdentifier, IntPtr ValuePtr, int BufferLength, ref int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetDescField</c> returns the current setting or value of a single field of a descriptor record.</para>
	/// </summary>
	/// <param name="DescriptorHandle">[Input] Descriptor handle.</param>
	/// <param name="RecNumber">
	/// [Input] Indicates the descriptor record from which the application seeks information. Descriptor records are numbered from 0, with
	/// record number 0 being the bookmark record. If the FieldIdentifier argument indicates a header field, RecNumber is ignored. If
	/// RecNumber is less than or equal to SQL_DESC_COUNT but the row does not contain data for a column or parameter, a call to
	/// <c>SQLGetDescField</c> will return the default values of the fields. (For more information, see "Initialization of Descriptor Fields"
	/// in SQLSetDescField.)
	/// </param>
	/// <param name="FieldIdentifier">
	/// [Input] Indicates the field of the descriptor whose value is to be returned. For more information, see the "FieldIdentifier Argument"
	/// section in SQLSetDescField.
	/// </param>
	/// <param name="ValuePtr">
	/// <para>[Output] Pointer to a buffer in which to return the descriptor information. The data type depends on the value of FieldIdentifier.</para>
	/// <para>
	/// If ValuePtr is integer type, applications should use a buffer of nuint and initialize the value to 0 before calling this function as
	/// some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged.
	/// </para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If FieldIdentifier is an ODBC-defined field and ValuePtr points to a character string or a binary buffer, this argument
	/// should be the length of *ValuePtr. If FieldIdentifier is an ODBC-defined field and *ValuePtr is an integer, BufferLength is ignored.
	/// If the value in *ValuePtr is of a Unicode data type (when calling <c>SQLGetDescFieldW</c>), the BufferLength argument must be an even number.
	/// </para>
	/// <para>
	/// If FieldIdentifier is a driver-defined field, the application indicates the nature of the field to the Driver Manager by setting the
	/// BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a character string, then BufferLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a value other than a character string or binary string, then BufferLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is contains a fixed-length data type, then BufferLength is either SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or
	/// SQL_IS_USMALLINT, as appropriate.
	/// </para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] Pointer to the buffer in which to return the total number of bytes (excluding the number of bytes required for the
	/// null-termination character) available to return in *ValuePtr.
	/// </param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.</para>
	/// <para>SQL_NO_DATA is returned if RecNumber is greater than the current number of descriptor records.</para>
	/// <para>
	/// SQL_NO_DATA is returned if DescriptorHandle is an IRD handle and the statement is in the prepared or executed state but there was no
	/// open cursor associated with it.
	/// </para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescfield-function?view=sql-server-ver16 SQLRETURN SQLGetDescField(
	// SQLHDESC DescriptorHandle, short RecNumber, short FieldIdentifier, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle, short RecNumber,
		SQL_DESC FieldIdentifier, string? ValuePtr, int BufferLength, ref int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetDescRec</c> returns the current settings or values of multiple fields of a descriptor record. The fields
	/// returned describe the name, data type, and storage of column or parameter data.
	/// </para>
	/// </summary>
	/// <param name="DescriptorHandle">[Input] Descriptor handle.</param>
	/// <param name="RecNumber">
	/// [Input] Indicates the descriptor record from which the application seeks information. Descriptor records are numbered from 1, with
	/// record number 0 being the bookmark record. The RecNumber argument must be less than or equal to the value of SQL_DESC_COUNT. If
	/// RecNumber is less than or equal to SQL_DESC_COUNT but the row does not contain data for a column or parameter, a call to
	/// <c>SQLGetDescRec</c> will return the default values of the fields. (For more information, see "Initialization of Descriptor Fields"
	/// in SQLSetDescField.)
	/// </param>
	/// <param name="Name">
	/// <para>[Output] A pointer to a buffer in which to return the SQL_DESC_NAME field for the descriptor record.</para>
	/// <para>
	/// If Name is NULL, StringLengthPtr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by Name.
	/// </para>
	/// </param>
	/// <param name="BufferLength">[Input] Length of the *Name buffer, in characters.</param>
	/// <param name="StringLengthPtr">
	/// [Output] A pointer to a buffer in which to return the number of characters of data available to return in the *Name buffer, excluding
	/// the null-termination character. If the number of characters was greater than or equal to BufferLength, the data in *Name is truncated
	/// to BufferLength minus the length of a null-termination character, and is null-terminated by the driver.
	/// </param>
	/// <param name="TypePtr">
	/// [Output] A pointer to a buffer in which to return the value of the SQL_DESC_TYPE field for the descriptor record.
	/// </param>
	/// <param name="SubTypePtr">
	/// [Output] For records whose type is SQL_DATETIME or SQL_INTERVAL, this is a pointer to a buffer in which to return the value of the
	/// SQL_DESC_DATETIME_INTERVAL_CODE field.
	/// </param>
	/// <param name="LengthPtr">
	/// [Output] A pointer to a buffer in which to return the value of the SQL_DESC_OCTET_LENGTH field for the descriptor record.
	/// </param>
	/// <param name="PrecisionPtr">
	/// [Output] A pointer to a buffer in which to return the value of the SQL_DESC_PRECISION field for the descriptor record.
	/// </param>
	/// <param name="ScalePtr">
	/// [Output] A pointer to a buffer in which to return the value of the SQL_DESC_SCALE field for the descriptor record.
	/// </param>
	/// <param name="NullablePtr">
	/// [Output] A pointer to a buffer in which to return the value of the SQL_DESC_NULLABLE field for the descriptor record.
	/// </param>
	/// <returns>
	/// <para>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.</para>
	/// <para>SQL_NO_DATA is returned if RecNumber is greater than the current number of descriptor records.</para>
	/// <para>
	/// SQL_NO_DATA is returned if DescriptorHandle is an IRD handle and the statement is in the prepared or executed state but there was no
	/// open cursor associated with it.
	/// </para>
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescrec-function?view=sql-server-ver16 SQLRETURN SQLGetDescRec(
	// SQLHDESC DescriptorHandle, short RecNumber, byte * Name, short BufferLength, short * StringLengthPtr, short
	// * TypePtr, short * SubTypePtr, nint * LengthPtr, short * PrecisionPtr, short * ScalePtr, short * NullablePtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetDescRec(SQLHDESC DescriptorHandle, short RecNumber, [Out] StringBuilder? Name,
		short BufferLength, out short StringLengthPtr, out SQL_TYPE TypePtr, out short SubTypePtr,
		out nint LengthPtr, out short PrecisionPtr, out short ScalePtr, out SQL_NULLABILITY NullablePtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetDiagField</c> returns the current value of a field of a record of the diagnostic data structure (associated
	/// with a specified handle) that contains error, warning, and status information.
	/// </para>
	/// </summary>
	/// <param name="HandleType">
	/// <para>[Input] A handle type identifier that describes the type of handle for which diagnostics are required. Must be one of the following:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC_INFO_TOKEN</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DESC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_ENV</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_STMT</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// SQL_HANDLE_DBC_INFO_TOKEN handle is used only by the Driver Manager and driver. Applications should not use this handle type. For
	/// more information about SQL_HANDLE_DBC_INFO_TOKEN, see Developing Connection-Pool Awareness in an ODBC Driver.
	/// </para>
	/// </param>
	/// <param name="Handle">
	/// [Input] A handle for the diagnostic data structure, of the type indicated by HandleType. If HandleType is SQL_HANDLE_ENV, Handle can
	/// be either a shared or an unshared environment handle.
	/// </param>
	/// <param name="RecNumber">
	/// [Input] Indicates the status record from which the application seeks information. Status records are numbered from 1. If the
	/// DiagIdentifier argument indicates any field of the diagnostics header, RecNumber is ignored. If not, it should be more than 0.
	/// </param>
	/// <param name="DiagIdentifier">
	/// [Input] Indicates the field of the diagnostic whose value is to be returned. For more information, see the "DiagIdentifier Argument"
	/// section in "Comments."
	/// </param>
	/// <param name="DiagInfoPtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the diagnostic information. The data type depends on the value of DiagIdentifier. If
	/// DiagInfoPtr is an integer type, applications should use a buffer of nuint and initialize the value to 0 before calling this function,
	/// as some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged.
	/// </para>
	/// <para>
	/// If DiagInfoPtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by DiagInfoPtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If DiagIdentifier is an ODBC-defined diagnostic and DiagInfoPtr points to a character string or a binary buffer, this
	/// argument should be the length of *DiagInfoPtr. If DiagIdentifier is an ODBC-defined field and *DiagInfoPtr is an integer,
	/// BufferLength is ignored. If the value in *DiagInfoPtr is a Unicode string (when calling <c>SQLGetDiagFieldW</c>), the BufferLength
	/// argument must be an even number.
	/// </para>
	/// <para>
	/// If DiagIdentifier is a driver-defined field, the application indicates the nature of the field to the Driver Manager by setting the
	/// BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If DiagInfoPtr is a pointer to a character string, BufferLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If DiagInfoPtr is a pointer to a binary buffer, the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If DiagInfoPtr is a pointer to a value other than a character string or binary string, BufferLength should have the value SQL_IS_POINTER.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *DiagInfoPtr contains a fixed-length data type, BufferLength is SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or
	/// SQL_IS_USMALLINT, as appropriate.
	/// </para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] Pointer to a buffer in which to return the total number of bytes (excluding the number of bytes required for the
	/// null-termination character) available to return in *DiagInfoPtr, for character data. If the number of bytes available to return is
	/// greater than or equal to BufferLength, the text in *DiagInfoPtr is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_NO_DATA.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagfield-function?view=sql-server-ver16 SQLRETURN SQLGetDiagField(
	// SQL_HANDLE HandleType, IntPtr Handle, short RecNumber, short DiagIdentifier, IntPtr DiagInfoPtr, short BufferLength, short * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetDiagField(SQL_HANDLE HandleType, IntPtr Handle, short RecNumber,
		SQL_DIAG_ID DiagIdentifier, [In, Out, Optional] IntPtr DiagInfoPtr, short BufferLength, out short StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetDiagRec</c> returns the current values of multiple fields of a diagnostic record that contains error, warning,
	/// and status information. Unlike <c>SQLGetDiagField</c>, which returns one diagnostic field per call, <c>SQLGetDiagRec</c> returns
	/// several commonly used fields of a diagnostic record, including the SQLSTATE, the native error code, and the diagnostic message text.
	/// </para>
	/// </summary>
	/// <param name="HandleType">
	/// <para>[Input] A handle type identifier that describes the type of handle for which diagnostics are required. Must be one of the following:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DBC_INFO_TOKEN</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_DESC</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_ENV</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>SQL_HANDLE_STMT</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// SQL_HANDLE_DBC_INFO_TOKEN handle is used only by the Driver Manager and driver. Applications should not use this handle type. For
	/// more information about SQL_HANDLE_DBC_INFO_TOKEN, see Developing Connection-Pool Awareness in an ODBC Driver.
	/// </para>
	/// </param>
	/// <param name="Handle">
	/// [Input] A handle for the diagnostic data structure, of the type indicated by HandleType. If HandleType is SQL_HANDLE_ENV, Handle can
	/// be either a shared or an unshared environment handle.
	/// </param>
	/// <param name="RecNumber">
	/// [Input] Indicates the status record from which the application seeks information. Status records are numbered from 1.
	/// </param>
	/// <param name="SQLState">
	/// [Output] Pointer to a buffer in which to return a five-character SQLSTATE code (and terminating NULL) for the diagnostic record
	/// RecNumber. The first two characters indicate the class; the next three indicate the subclass. This information is contained in the
	/// SQL_DIAG_SQLSTATE diagnostic field. For more information, see SQLSTATEs.
	/// </param>
	/// <param name="NativeErrorPtr">
	/// [Output] Pointer to a buffer in which to return the native error code, specific to the data source. This information is contained in
	/// the SQL_DIAG_NATIVE diagnostic field.
	/// </param>
	/// <param name="MessageText">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the diagnostic message text string. This information is contained in the
	/// SQL_DIAG_MESSAGE_TEXT diagnostic field. For the format of the string, see Diagnostic Messages.
	/// </para>
	/// <para>
	/// If MessageText is NULL, TextLengthPtr will still return the total number of characters (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by MessageText.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// [Input] Length of the *MessageText buffer in characters. There is no maximum length of the diagnostic message text.
	/// </param>
	/// <param name="TextLengthPtr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding the number of characters required for the
	/// null-termination character) available to return in *MessageText. If the number of characters available to return is greater than
	/// BufferLength, the diagnostic message text in *MessageText is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagrec-function?view=sql-server-ver16 SQLRETURN SQLGetDiagRec(
	// SQL_HANDLE HandleType, IntPtr Handle, short RecNumber, byte * SQLState, int * NativeErrorPtr, byte * MessageText, short BufferLength,
	// short * TextLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetDiagRec(SQL_HANDLE HandleType, IntPtr Handle, short RecNumber,
		[Out] StringBuilder SQLState, out int NativeErrorPtr, [Out] StringBuilder? MessageText, short BufferLength,
		out short TextLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetEnvAttr</c> returns the current setting of an environment attribute.</para>
	/// </summary>
	/// <param name="EnvironmentHandle">[Input] Environment handle.</param>
	/// <param name="Attribute">[Input] Attribute to retrieve.</param>
	/// <param name="ValuePtr">
	/// <para>[Output] Pointer to a buffer in which to return the current value of the attribute specified by Attribute.</para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// [Input] If ValuePtr points to a character string, this argument should be the length of *ValuePtr. If *ValuePtr is an integer,
	/// BufferLength is ignored. If *ValuePtr is a Unicode string (when calling <c>SQLGetEnvAttrW</c>), the BufferLength argument must be an
	/// even number. If the attribute value is not a character string, BufferLength is unused.
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] A pointer to a buffer in which to return the total number of bytes (excluding the null-termination character) available to
	/// return in *ValuePtr. If the attribute value is a character string and the number of bytes available to return is greater than or
	/// equal to BufferLength, the data in *ValuePtr is truncated to BufferLength minus the length of a null-termination character and is
	/// null-terminated by the driver.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetenvattr-function?view=sql-server-ver16 SQLRETURN SQLGetEnvAttr(
	// SQLHENV EnvironmentHandle, int Attribute, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQL_ATTR Attribute, [In, Out, Optional] IntPtr ValuePtr,
		int BufferLength, out int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetFunctions</c> returns information about whether a driver supports a specific ODBC function. This function is
	/// implemented in the Driver Manager; it can also be implemented in drivers. If a driver implements <c>SQLGetFunctions</c>, the Driver
	/// Manager calls the function in the driver. Otherwise, it executes the function itself.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="FunctionId">
	/// <para>
	/// [Input] A <c>#define</c> value that identifies the ODBC function of interest; <c>SQL_API_ODBC3_ALL_FUNCTIONS
	/// orSQL_API_ALL_FUNCTIONS</c>. <c>SQL_API_ODBC3_ALL_FUNCTIONS</c> is used by an ODBC 3*.x* application to determine support of ODBC
	/// 3*.x* and earlier functions. <c>SQL_API_ALL_FUNCTIONS</c> is used by an ODBC 2*.x* application to determine support of ODBC 2*.x* and
	/// earlier functions.
	/// </para>
	/// <para>For a list of <c>#define</c> values that identify ODBC functions, see the tables in "Comments."</para>
	/// </param>
	/// <param name="SupportedPtr">
	/// <para>
	/// [Output] If FunctionId identifies a single ODBC function, SupportedPtr points to a single uint value that is SQL_TRUE if the
	/// specified function is supported by the driver, and SQL_FALSE if it is not supported.
	/// </para>
	/// <para>
	/// If FunctionId is SQL_API_ODBC3_ALL_FUNCTIONS, SupportedPtr points to a short array with a number of elements equal to
	/// SQL_API_ODBC3_ALL_FUNCTIONS_SIZE. This array is treated by the Driver Manager as a 4,000-bit bitmap that can be used to determine
	/// whether an ODBC 3*.x* or earlier function is supported. The SQL_FUNC_EXISTS macro is called to determine function support. (See
	/// "Comments.") An ODBC 3*.x* application can call <c>SQLGetFunctions</c> with SQL_API_ODBC3_ALL_FUNCTIONS against either an ODBC 3*.x*
	/// or ODBC 2*.x* driver.
	/// </para>
	/// <para>
	/// If FunctionId is SQL_API_ALL_FUNCTIONS, SupportedPtr points to an uint array of 100 elements. The array is indexed by <c>#define</c>
	/// values used by FunctionId to identify each ODBC function; some elements of the array are unused and reserved for future use. An
	/// element is SQL_TRUE if it identifies an ODBC 2*.x* or earlier function supported by the driver. It is SQL_FALSE if it identifies an
	/// ODBC function not supported by the driver or does not identify an ODBC function.
	/// </para>
	/// <para>The arrays returned in *SupportedPtr use zero-based indexing.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetfunctions-function?view=sql-server-ver16 SQLRETURN SQLGetFunctions(
	// SQLHDBC ConnectionHandle, uint FunctionId, uint * SupportedPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLGetFunctions(SQLHDBC ConnectionHandle, SQL_API FunctionId,
		out SQL_BOOL SupportedPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetFunctions</c> returns information about whether a driver supports a specific ODBC function. This function is
	/// implemented in the Driver Manager; it can also be implemented in drivers. If a driver implements <c>SQLGetFunctions</c>, the Driver
	/// Manager calls the function in the driver. Otherwise, it executes the function itself.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="FunctionId">
	/// <para>
	/// [Input] A <c>#define</c> value that identifies the ODBC function of interest; <c>SQL_API_ODBC3_ALL_FUNCTIONS
	/// orSQL_API_ALL_FUNCTIONS</c>. <c>SQL_API_ODBC3_ALL_FUNCTIONS</c> is used by an ODBC 3*.x* application to determine support of ODBC
	/// 3*.x* and earlier functions. <c>SQL_API_ALL_FUNCTIONS</c> is used by an ODBC 2*.x* application to determine support of ODBC 2*.x* and
	/// earlier functions.
	/// </para>
	/// <para>For a list of <c>#define</c> values that identify ODBC functions, see the tables in "Comments."</para>
	/// </param>
	/// <param name="SupportedPtr">
	/// <para>
	/// [Output] If FunctionId identifies a single ODBC function, SupportedPtr points to a single uint value that is SQL_TRUE if the
	/// specified function is supported by the driver, and SQL_FALSE if it is not supported.
	/// </para>
	/// <para>
	/// If FunctionId is SQL_API_ODBC3_ALL_FUNCTIONS, SupportedPtr points to a short array with a number of elements equal to
	/// SQL_API_ODBC3_ALL_FUNCTIONS_SIZE. This array is treated by the Driver Manager as a 4,000-bit bitmap that can be used to determine
	/// whether an ODBC 3*.x* or earlier function is supported. The SQL_FUNC_EXISTS macro is called to determine function support. (See
	/// "Comments.") An ODBC 3*.x* application can call <c>SQLGetFunctions</c> with SQL_API_ODBC3_ALL_FUNCTIONS against either an ODBC 3*.x*
	/// or ODBC 2*.x* driver.
	/// </para>
	/// <para>
	/// If FunctionId is SQL_API_ALL_FUNCTIONS, SupportedPtr points to an uint array of 100 elements. The array is indexed by <c>#define</c>
	/// values used by FunctionId to identify each ODBC function; some elements of the array are unused and reserved for future use. An
	/// element is SQL_TRUE if it identifies an ODBC 2*.x* or earlier function supported by the driver. It is SQL_FALSE if it identifies an
	/// ODBC function not supported by the driver or does not identify an ODBC function.
	/// </para>
	/// <para>The arrays returned in *SupportedPtr use zero-based indexing.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetfunctions-function?view=sql-server-ver16 SQLRETURN SQLGetFunctions(
	// SQLHDBC ConnectionHandle, uint FunctionId, uint * SupportedPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLGetFunctions(SQLHDBC ConnectionHandle, SQL_API FunctionId,
		[Out] ushort[] SupportedPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetInfo</c> returns general information about the driver and data source associated with a connection.</para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="InfoType">[Input] Type of information.</param>
	/// <param name="InfoValuePtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the information. Depending on the InfoType requested, the information returned will
	/// be one of the following: a null-terminated character string, an uint value, an uint bitmask, an uint flag, a uint binary value, or a
	/// nuint value.
	/// </para>
	/// <para>
	/// If the InfoType argument is SQL_DRIVER_HDESC or SQL_DRIVER_HSTMT, the InfoValuePtr argument is both input and output. (See the
	/// SQL_DRIVER_HDESC or SQL_DRIVER_HSTMT descriptors later in this function description for more information.)
	/// </para>
	/// <para>
	/// If InfoValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by InfoValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// [Input] Length of the *InfoValuePtr buffer. If the value in *InfoValuePtr is not a character string or if InfoValuePtr is a null
	/// pointer, the BufferLength argument is ignored. The driver assumes that the size of *InfoValuePtr is uint or uint, based on the
	/// InfoType. If *InfoValuePtr is a Unicode string (when calling <c>SQLGetInfoW</c>), the BufferLength argument must be an even number;
	/// if not, SQLSTATE HY090 (Invalid string or buffer length) is returned.
	/// </param>
	/// <param name="StringLengthPtr">
	/// <para>
	/// [Output] Pointer to a buffer in which to return the total number of bytes (excluding the null-termination character for character
	/// data) available to return in *InfoValuePtr.
	/// </para>
	/// <para>
	/// For character data, if the number of bytes available to return is greater than or equal to BufferLength, the information in
	/// *InfoValuePtr is truncated to BufferLength bytes minus the length of a null-termination character and is null-terminated by the driver.
	/// </para>
	/// <para>
	/// For all other types of data, the value of BufferLength is ignored and the driver assumes the size of *InfoValuePtr is uint or uint,
	/// depending on the InfoType.
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function?view=sql-server-ver16 SQLRETURN SQLGetInfo( SQLHDBC
	// ConnectionHandle, uint InfoType, IntPtr InfoValuePtr, short BufferLength, short * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetInfo(SQLHDBC ConnectionHandle, SQL_INFO InfoType, [In, Out, Optional] IntPtr InfoValuePtr,
		short BufferLength, out short StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetInfo</c> returns general information about the driver and data source associated with a connection.</para>
	/// </summary>
	/// <typeparam name="T">The type of the information to return.</typeparam>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="InfoType">[Input] Type of information.</param>
	/// <returns>
	/// The information. Depending on the InfoType requested, the information returned will be one of the following: a null-terminated
	/// character string, an uint value, an uint bitmask, an uint flag, a uint binary value, or a nuint value.
	/// </returns>
	/// <exception cref="System.ArgumentException">Cannot get this type of value from this InfoType.</exception>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function?view=sql-server-ver16 SQLRETURN SQLGetInfo( SQLHDBC
	// ConnectionHandle, uint InfoType, IntPtr InfoValuePtr, short BufferLength, short * StringLengthPtr);
	[PInvokeData("sql.h")]
	public static T? SQLGetInfo<T>(SQLHDBC ConnectionHandle, SQL_INFO InfoType)
	{
		if (!CorrespondingTypeAttribute.CanGet(InfoType, typeof(T)))
			throw new ArgumentException("Cannot get this type of value from this InfoType.");
		short sz;
		if (typeof(T) == typeof(string))
		{
			SQLGetInfo(ConnectionHandle, InfoType, default, 0, out sz).ThrowIfFailed(ConnectionHandle);
			sz += (short)Marshal.SystemDefaultCharSize;
		}
		else
			sz = (short)Marshal.SizeOf(typeof(T));
		using var mem = new SafeHGlobalHandle(sz);
		SQLGetInfo(ConnectionHandle, InfoType, mem, sz, out sz).ThrowIfFailed(ConnectionHandle);
		return mem.ToType<T>();
	}

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLGetStmtAttr</c> returns the current setting of a statement attribute.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="Attribute">[Input] Attribute to retrieve.</param>
	/// <param name="ValuePtr">
	/// <para>[Output] Pointer to a buffer in which to return the value of the attribute specified in Attribute.</para>
	/// <para>
	/// If ValuePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-termination character for
	/// character data) available to return in the buffer pointed to by ValuePtr.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If Attribute is an ODBC-defined attribute and ValuePtr points to a character string or a binary buffer, this argument should
	/// be the length of *ValuePtr. If Attribute is an ODBC-defined attribute and *ValuePtr is an integer, BufferLength is ignored. If the
	/// value returned in *ValuePtr is a Unicode string (when calling <c>SQLGetStmtAttrW</c>), the BufferLength argument must be an even number.
	/// </para>
	/// <para>
	/// If Attribute is a driver-defined attribute, the application indicates the nature of the attribute to the Driver Manager by setting
	/// the BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is a pointer to a character string, then BufferLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If *ValuePtr is a pointer to a value other than a character string or binary string, then BufferLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If *ValuePtr is contains a fixed-length data type, then BufferLength is either SQL_IS_INTEGER or SQL_IS_UINTEGER, as appropriate.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Output] A pointer to a buffer in which to return the total number of bytes (excluding the null-termination character) available to
	/// return in *ValuePtr. If the attribute value is a character string, and the number of bytes available to return is greater than or
	/// equal to BufferLength, the data in *ValuePtr is truncated to BufferLength minus the length of a null-termination character and is
	/// null-terminated by the driver.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetstmtattr-function?view=sql-server-ver16 SQLRETURN SQLGetStmtAttr(
	// SQLHSTMT StatementHandle, int Attribute, IntPtr ValuePtr, int BufferLength, int * StringLengthPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetStmtAttr(SQLHSTMT StatementHandle, SQL_ATTR Attribute, [In, Out, Optional] IntPtr ValuePtr,
		int BufferLength, out int StringLengthPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLGetTypeInfo</c> returns information about data types supported by the data source. The driver returns the
	/// information in the form of an SQL result set. The data types are intended for use in Data Definition Language (DDL) statements.
	/// </para>
	/// <para>
	/// <para>Important</para>
	/// <para>
	/// Applications must use the type names returned in the TYPE_NAME column of the <c>SQLGetTypeInfo</c> result set in <c>ALTER TABLE</c>
	/// and <c>CREATE TABLE</c> statements. <c>SQLGetTypeInfo</c> may return more than one row with the same value in the DATA_TYPE column.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle for the result set.</param>
	/// <param name="DataType">
	/// [Input] The SQL data type. This must be one of the values in the SQL Data Types section of Appendix D: Data Types, or a
	/// driver-specific SQL data type. SQL_ALL_TYPES specifies that information about all data types should be returned.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgettypeinfo-function?view=sql-server-ver16 SQLRETURN SQLGetTypeInfo(
	// SQLHSTMT StatementHandle, short DataType);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLGetTypeInfo(SQLHSTMT StatementHandle, SQL_TYPE DataType);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLMoreResults</c> determines whether more results are available on a statement containing <c>SELECT</c>,
	/// <c>UPDATE</c>, <c>INSERT</c>, or <c>DELETE</c> statements and, if so, initializes processing for those results.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_NO_DATA, SQL_ERROR, SQL_INVALID_HANDLE, OR SQL_PARAM_DATA_AVAILABLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlmoreresults-function?view=sql-server-ver16 SQLRETURN SQLMoreResults(
	// SQLHSTMT StatementHandle);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLMoreResults(SQLHSTMT StatementHandle);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLNativeSql</c> returns the SQL string as modified by the driver. <c>SQLNativeSql</c> does not execute the SQL statement.
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="InStatementText">[Input] SQL text string to be translated.</param>
	/// <param name="TextLength1">[Input] Length in characters of *InStatementText text string.</param>
	/// <param name="OutStatementText">
	/// <para>[Output] Pointer to a buffer in which to return the translated SQL string.</para>
	/// <para>
	/// If OutStatementText is NULL, TextLength2Ptr will still return the total number of characters (excluding the null-termination
	/// character for character data) available to return in the buffer pointed to by OutStatementText.
	/// </para>
	/// </param>
	/// <param name="BufferLength">
	/// [Input] Number of characters in the *OutStatementText buffer. Past versions of this documentation mistakenly implied that this count
	/// of characters must be even if the value returned in *InStatementText is a Unicode string (when calling <c>SQLNativeSqlW</c>). There
	/// is no such a restriction. For optimal interoperability, driver writers should expect any count of characters to be passed to this
	/// function, while application writers are recommended to always use an even count.
	/// </param>
	/// <param name="TextLength2Ptr">
	/// [Output] Pointer to a buffer in which to return the total number of characters (excluding null-termination) available to return in
	/// *OutStatementText. If the number of characters available to return is greater than or equal to BufferLength, the translated SQL
	/// string in *OutStatementText is truncated to BufferLength minus the length of a null-termination character.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnativesql-function?view=sql-server-ver16 SQLRETURN SQLNativeSql(
	// SQLHDBC ConnectionHandle, byte * InStatementText, int TextLength1, byte * OutStatementText, int BufferLength, int * TextLength2Ptr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLNativeSql(SQLHDBC ConnectionHandle, string InStatementText,
		int TextLength1, [Out] StringBuilder? OutStatementText, int BufferLength, out int TextLength2Ptr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLNumParams</c> returns the number of parameters in an SQL statement.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ParameterCountPtr">[Output] Pointer to a buffer in which to return the number of parameters in the statement.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnumparams-function?view=sql-server-ver16 SQLRETURN SQLNumParams(
	// SQLHSTMT StatementHandle, short * ParameterCountPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLNumParams(SQLHSTMT StatementHandle, out short ParameterCountPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLNumResultCols</c> returns the number of columns in a result set.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ColumnCountPtr">
	/// [Output] Pointer to a buffer in which to return the number of columns in the result set. This count does not include a bound bookmark column.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnumresultcols-function?view=sql-server-ver16 SQLRETURN
	// SQLNumResultCols( SQLHSTMT StatementHandle, short * ColumnCountPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLNumResultCols(SQLHSTMT StatementHandle, out short ColumnCountPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLParamData</c> is used together with <c>SQLPutData</c> to supply parameter data at statement execution time, and
	/// with <c>SQLGetData</c> to retrieve streamed output parameter data.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="ValuePtrPtr">
	/// [Output] Pointer to a buffer in which to return the address of the ParameterValuePtr buffer specified in <c>SQLBindParameter</c> (for
	/// parameter data) or the address of the TargetValuePtr buffer specified in <c>SQLBindCol</c> (for column data), as contained in the
	/// SQL_DESC_DATA_PTR descriptor record field.
	/// </param>
	/// <returns>
	/// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
	/// </returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlparamdata-function?view=sql-server-ver16 SQLRETURN SQLParamData(
	// SQLHSTMT StatementHandle, IntPtr * ValuePtrPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLParamData(SQLHSTMT StatementHandle, out IntPtr ValuePtrPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLPrepare</c> prepares an SQL string for execution.</para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="StatementText">[Input] SQL text string.</param>
	/// <param name="TextLength">[Input] Length of *StatementText in characters.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function?view=sql-server-ver16 SQLRETURN SQLPrepare( SQLHSTMT
	// StatementHandle, byte * StatementText, int TextLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, string StatementText, int TextLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLPrimaryKeys</c> returns the column names that make up the primary key for a table. The driver returns the
	/// information as a result set. This function does not support returning primary keys from multiple tables in a single call.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") denotes those tables that do not have catalogs. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] Schema name. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") denotes those tables that do not have schemas. SchemaName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is an ordinary argument; it is treated literally, and its case is not significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] Table name. This argument cannot be a null pointer. TableName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is an ordinary argument; it is treated literally, and its case is not significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprimarykeys-function?view=sql-server-ver16 SQLRETURN SQLPrimaryKeys(
	// SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte * TableName, short NameLength3);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLPrimaryKeys(SQLHSTMT StatementHandle, string CatalogName,
		short NameLength1, string SchemaName, short NameLength2, string TableName,
		short NameLength3);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLProcedureColumns</c> returns the list of input and output parameters, as well as the columns that make up the
	/// result set for the specified procedures. The driver returns the information as a result set on the specified statement.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Procedure catalog name. If a driver supports catalogs for some procedures but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those procedures that do not have catalogs. CatalogName cannot
	/// contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] String search pattern for procedure schema names. If a driver supports schemas for some procedures but not for others, such
	/// as when the driver retrieves data from different DBMSs, an empty string ("") denotes those procedures that do not have schemas.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="ProcName">
	/// <para>[Input] String search pattern for procedure names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ProcName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, ProcName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *ProcName.</param>
	/// <param name="ColumnName">
	/// <para>[Input] String search pattern for column names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ColumnName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, ColumnName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength4">[Input] Length in characters of *ColumnName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedurecolumns-function?view=sql-server-ver16 SQLRETURN
	// SQLProcedureColumns( SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte *
	// ProcName, short NameLength3, byte * ColumnName, short NameLength4);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLProcedureColumns(SQLHSTMT StatementHandle, string CatalogName,
		short NameLength1, string SchemaName, short NameLength2, string ProcName,
		short NameLength3, string ColumnName, short NameLength4);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLProcedures</c> returns the list of procedure names stored in a specific data source. Procedure is a generic term
	/// used to describe an executable object, or a named entity that can be invoked using input and output parameters. For more information
	/// on procedures, see the Procedures.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Procedure catalog. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data
	/// from different DBMSs, an empty string ("") denotes those tables that do not have catalogs. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] String search pattern for procedure schema names. If a driver supports schemas for some procedures but not for others, such
	/// as when the driver retrieves data from different DBMSs, an empty string ("") denotes those procedures that do not have schemas.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="ProcName">
	/// <para>[Input] String search pattern for procedure names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ProcName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, ProcName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *ProcName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedures-function?view=sql-server-ver16 SQLRETURN SQLProcedures(
	// SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte * ProcName, short NameLength3);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLProcedures(SQLHSTMT StatementHandle, string CatalogName, short NameLength1,
		string SchemaName, short NameLength2, string ProcName, short NameLength3);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLPutData</c> allows an application to send data for a parameter or column to the driver at statement execution
	/// time. This function can be used to send character or binary data values in parts to a column with a character, binary, or data
	/// source-specific data type (for example, parameters of the SQL_LONGVARBINARY or SQL_LONGVARCHAR types). <c>SQLPutData</c> supports
	/// binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="DataPtr">
	/// [Input] Pointer to a buffer containing the actual data for the parameter or column. The data must be in the C data type specified in
	/// the ValueType argument of <c>SQLBindParameter</c> (for parameter data) or the TargetType argument of <c>SQLBindCol</c> (for column data).
	/// </param>
	/// <param name="StrLen_or_Ind">
	/// <para>
	/// [Input] Length of *DataPtr. Specifies the amount of data sent in a call to <c>SQLPutData</c>. The amount of data can vary with each
	/// call for a given parameter or column. StrLen_or_Ind is ignored unless it meets one of the following conditions:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>StrLen_or_Ind is SQL_NTS, SQL_NULL_DATA, or SQL_DEFAULT_PARAM.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>The C data type specified in <c>SQLBindParameter</c> or <c>SQLBindCol</c> is SQL_C_CHAR or SQL_C_BINARY.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>The C data type is SQL_C_DEFAULT, and the default C data type for the specified SQL data type is SQL_C_CHAR or SQL_C_BINARY.</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>
	/// For all other types of C data, if StrLen_or_Ind is not SQL_NULL_DATA or SQL_DEFAULT_PARAM, the driver assumes that the size of the
	/// *DataPtr buffer is the size of the C data type specified with ValueType or TargetType and sends the entire data value. For more
	/// information, see Converting Data from C to SQL Data Types in Appendix D: Data Types.
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlputdata-function?view=sql-server-ver16 SQLRETURN SQLPutData( SQLHSTMT
	// StatementHandle, IntPtr DataPtr, nint StrLen_or_Ind);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLPutData(SQLHSTMT StatementHandle, [In] IntPtr DataPtr, nint StrLen_or_Ind);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLRowCount</c> returns the number of rows affected by an <c>UPDATE</c>, <c>INSERT</c>, or <c>DELETE</c> statement;
	/// an SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK operation in <c>SQLBulkOperations</c>; or an SQL_UPDATE or SQL_DELETE
	/// operation in <c>SQLSetPos</c>.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="RowCountPtr">
	/// <para>
	/// [Output] Points to a buffer in which to return a row count. For <c>UPDATE</c>, <c>INSERT</c>, and <c>DELETE</c> statements, for the
	/// SQL_ADD, SQL_UPDATE_BY_BOOKMARK, and SQL_DELETE_BY_BOOKMARK operations in <c>SQLBulkOperations</c>, and for the SQL_UPDATE or
	/// SQL_DELETE operations in <c>SQLSetPos</c>, the value returned in *RowCountPtr is either the number of rows affected by the request or
	/// -1 if the number of affected rows is not available.
	/// </para>
	/// <para>
	/// When <c>SQLExecute</c>, <c>SQLExecDirect</c>, <c>SQLBulkOperations</c>, <c>SQLSetPos, or SQLMoreResults</c> is called, the
	/// SQL_DIAG_ROW_COUNT field of the diagnostic data structure is set to the row count, and the row count is cached in an
	/// implementation-dependent way. <c>SQLRowCount</c> returns the cached row count value. The cached row count value is valid until the
	/// statement handle is set back to the prepared or allocated state, the statement is reexecuted, or <c>SQLCloseCursor</c> is called.
	/// Note that if a function has been called since the SQL_DIAG_ROW_COUNT field was set, the value returned by <c>SQLRowCount</c> might be
	/// different from the value in the SQL_DIAG_ROW_COUNT field because the SQL_DIAG_ROW_COUNT field is reset to 0 by any function call.
	/// </para>
	/// <para>
	/// For other statements and functions, the driver may define the value returned in *RowCountPtr. For example, some data sources may be
	/// able to return the number of rows returned by a <c>SELECT</c> statement or a catalog function before fetching the rows.
	/// </para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// Many data sources cannot return the number of rows in a result set before fetching them; for maximum interoperability, applications
	/// should not rely on this behavior.
	/// </para>
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlrowcount-function?view=sql-server-ver16 SQLRETURN SQLRowCount( SQLHSTMT
	// StatementHandle, nint * RowCountPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLRowCount(SQLHSTMT StatementHandle, out nint RowCountPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLSetConnectAttr</c> sets attributes that govern aspects of connections.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3*.x* application is working with an ODBC 2*.x*
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="ConnectionHandle">[Input] Connection handle.</param>
	/// <param name="Attribute">[Input] Attribute to set, listed in "Comments."</param>
	/// <param name="ValuePtr">
	/// [Input] Pointer to the value to be associated with Attribute. Depending on the value of Attribute, ValuePtr will be an unsigned
	/// integer value or will point to a null-terminated character string. Note that the integral type of the Attribute argument may not be
	/// fixed length, see the Comments section for detail.
	/// </param>
	/// <param name="StringLength">
	/// <para>
	/// [Input] If Attribute is an ODBC-defined attribute and ValuePtr points to a character string or a binary buffer, this argument should
	/// be the length of *ValuePtr. For character string data, this argument should contain the number of bytes in the string.
	/// </para>
	/// <para>If Attribute is an ODBC-defined attribute and ValuePtr is an integer, StringLength is ignored.</para>
	/// <para>
	/// If Attribute is a driver-defined attribute, the application indicates the nature of the attribute to the Driver Manager by setting
	/// the StringLength argument. StringLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If ValuePtr is a pointer to a character string, then StringLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// StringLength. This places a negative value in StringLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a value other than a character string or a binary string, then StringLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If ValuePtr contains a fixed-length value, then StringLength is either SQL_IS_INTEGER or SQL_IS_UINTEGER, as appropriate.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetconnectattr-function?view=sql-server-ver16 SQLRETURN
	// SQLSetConnectAttr( SQLHDBC ConnectionHandle, int Attribute, IntPtr ValuePtr, int StringLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQL_ATTR Attribute, [In] IntPtr ValuePtr,
		int StringLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLSetCursorName</c> associates a cursor name with an active statement. If an application does not call
	/// <c>SQLSetCursorName</c>, the driver generates cursor names as needed for SQL statement processing.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CursorName">
	/// [Input] Cursor name. For efficient processing, the cursor name should not include any leading or trailing spaces in the cursor name,
	/// and if the cursor name includes a delimited identifier, the delimiter should be positioned as the first character in the cursor name.
	/// </param>
	/// <param name="NameLength">[Input] Length in characters of *CursorName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetcursorname-function?view=sql-server-ver16 SQLRETURN
	// SQLSetCursorName( SQLHSTMT StatementHandle, byte * CursorName, short NameLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLSetCursorName(SQLHSTMT StatementHandle, string CursorName,
		short NameLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLSetDescField</c> sets the value of a single field of a descriptor record.</para>
	/// </summary>
	/// <param name="DescriptorHandle">[Input] Descriptor handle.</param>
	/// <param name="RecNumber">
	/// [Input] Indicates the descriptor record containing the field that the application seeks to set. Descriptor records are numbered from
	/// 0, with record number 0 being the bookmark record. The RecNumber argument is ignored for header fields.
	/// </param>
	/// <param name="FieldIdentifier">
	/// [Input] Indicates the field of the descriptor whose value is to be set. For more information, see "FieldIdentifier Argument" in the
	/// "Comments" section.
	/// </param>
	/// <param name="ValuePtr">
	/// [Input] Pointer to a buffer containing the descriptor information, or an integer value. The data type depends on the value of
	/// FieldIdentifier. If ValuePtr is an integer value, it may be considered as 8 bytes (nint), 4 bytes (int) or 2 bytes (short), depending
	/// on the value of the FieldIdentifier argument.
	/// </param>
	/// <param name="BufferLength">
	/// <para>
	/// [Input] If FieldIdentifier is an ODBC-defined field and ValuePtr points to a character string or a binary buffer, this argument
	/// should be the length of *ValuePtr. For character string data, this argument should contain the number of bytes in the string.
	/// </para>
	/// <para>If FieldIdentifier is an ODBC-defined field and ValuePtr is an integer, BufferLength is ignored.</para>
	/// <para>
	/// If FieldIdentifier is a driver-defined field, the application indicates the nature of the field to the Driver Manager by setting the
	/// BufferLength argument. BufferLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If ValuePtr is a pointer to a character string, then BufferLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// BufferLength. This places a negative value in BufferLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a value other than a character string or a binary string, then BufferLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr contains a fixed-length value, then BufferLength is either SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or
	/// SQL_IS_USMALLINT, as appropriate.
	/// </para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetdescfield-function?view=sql-server-ver16 SQLRETURN SQLSetDescField(
	// SQLHDESC DescriptorHandle, short RecNumber, short FieldIdentifier, IntPtr ValuePtr, int BufferLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLSetDescField(SQLHDESC DescriptorHandle, short RecNumber,
		SQL_DESC FieldIdentifier, [In] IntPtr ValuePtr, int BufferLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c> The <c>SQLSetDescRec</c> function sets multiple descriptor fields that affect the data type and buffer bound to a
	/// column or parameter data.
	/// </para>
	/// </summary>
	/// <param name="DescriptorHandle">[Input] Descriptor handle. This must not be an IRD handle.</param>
	/// <param name="RecNumber">
	/// [Input] Indicates the descriptor record that contains the fields to be set. Descriptor records are numbered from 0, with record
	/// number 0 being the bookmark record. This argument must be equal to or greater than 0. If RecNumber is greater than the value of
	/// SQL_DESC_COUNT, SQL_DESC_COUNTis changed to the value of RecNumber.
	/// </param>
	/// <param name="Type">[Input] The value to which to set the SQL_DESC_TYPE field for the descriptor record.</param>
	/// <param name="SubType">
	/// [Input] For records whose type is SQL_DATETIME or SQL_INTERVAL, this is the value to which to set the SQL_DESC_DATETIME_INTERVAL_CODE field.
	/// </param>
	/// <param name="Length">[Input] The value to which to set the SQL_DESC_OCTET_LENGTH field for the descriptor record.</param>
	/// <param name="Precision">[Input] The value to which to set the SQL_DESC_PRECISION field for the descriptor record.</param>
	/// <param name="Scale">[Input] The value to which to set the SQL_DESC_SCALE field for the descriptor record.</param>
	/// <param name="DataPtr">
	/// <para>
	/// [Deferred Input or Output] The value to which to set the SQL_DESC_DATA_PTR field for the descriptor record. DataPtr can be set to a
	/// null pointer.
	/// </para>
	/// <para>
	/// The DataPtr argument can be set to a null pointer to set the SQL_DESC_DATA_PTR field to a null pointer. If the handle in the
	/// DescriptorHandle argument is associated with an ARD, this unbinds the column.
	/// </para>
	/// </param>
	/// <param name="StringLengthPtr">
	/// [Deferred Input or Output] The value to which to set the SQL_DESC_OCTET_LENGTH_PTR field for the descriptor record. StringLengthPtr
	/// can be set to a null pointer to set the SQL_DESC_OCTET_LENGTH_PTR field to a null pointer.
	/// </param>
	/// <param name="IndicatorPtr">
	/// [Deferred Input or Output] The value to which to set the SQL_DESC_INDICATOR_PTR field for the descriptor record. IndicatorPtr can be
	/// set to a null pointer to set the SQL_DESC_INDICATOR_PTR field to a null pointer.
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetdescrec-function?view=sql-server-ver16 SQLRETURN SQLSetDescRec(
	// SQLHDESC DescriptorHandle, short RecNumber, short Type, short SubType, nint Length, short Precision, short Scale, IntPtr DataPtr, nint
	// * StringLengthPtr, nint * IndicatorPtr);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLSetDescRec(SQLHDESC DescriptorHandle, short RecNumber, SQL_TYPE Type,
		short SubType, nint Length, short Precision, short Scale, [In, Out] IntPtr DataPtr,
		ref nint StringLengthPtr, ref nint IndicatorPtr);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLSetEnvAttr</c> sets attributes that govern aspects of environments.</para>
	/// </summary>
	/// <param name="EnvironmentHandle">[Input] Environment handle.</param>
	/// <param name="Attribute">[Input] Attribute to set, listed in "Comments."</param>
	/// <param name="ValuePtr">
	/// [Input] Pointer to the value to be associated with Attribute. Depending on the value of Attribute, ValuePtr will be a 32-bit integer
	/// value or point to a null-terminated character string.
	/// </param>
	/// <param name="StringLength">
	/// <para>
	/// [Input] If ValuePtr points to a character string or a binary buffer, this argument should be the length of *ValuePtr. For character
	/// string data, this argument should contain the number of bytes in the string.
	/// </para>
	/// <para>If ValuePtr is an integer, StringLength is ignored.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetenvattr-function?view=sql-server-ver16 SQLRETURN SQLSetEnvAttr(
	// SQLHENV EnvironmentHandle, int Attribute, IntPtr ValuePtr, int StringLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQL_ATTR Attribute, [In] IntPtr ValuePtr,
		int StringLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLSetPos</c> sets the cursor position in a rowset and allows an application to refresh data in the rowset or to
	/// update or delete data in the result set.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="RowNumber">
	/// <para>
	/// [Input] Position of the row in the rowset on which to perform the operation specified with the Operation argument. If RowNumber is 0,
	/// the operation applies to every row in the rowset.
	/// </para>
	/// <para>For additional information, see "Comments."</para>
	/// </param>
	/// <param name="Operation">
	/// <para>[Input] Operation to perform:</para>
	/// <para>SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// The SQL_ADD value for the Operation argument has been deprecated for ODBC 3.x. ODBC 3.x drivers will need to support SQL_ADD for
	/// backward compatibility. This functionality has been replaced by a call to <c>SQLBulkOperations</c> with an Operation of SQL_ADD. When
	/// an ODBC 3.x application works with an ODBC 2.x driver, the Driver Manager maps a call to <c>SQLBulkOperations</c> with an Operation
	/// of SQL_ADD to <c>SQLSetPos</c> with an Operation of SQL_ADD.
	/// </para>
	/// </para>
	/// <para>For more information, see "Comments."</para>
	/// </param>
	/// <param name="LockType">
	/// <para>[Input] Specifies how to lock the row after performing the operation specified in the Operation argument.</para>
	/// <para>SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK</para>
	/// <para>For more information, see "Comments."</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetpos-function?view=sql-server-ver16 SQLRETURN SQLSetPos( SQLHSTMT
	// StatementHandle, SQLSETPOSIROW RowNumber, uint Operation, uint LockType);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, ExactSpelling = true)]
	public static extern SQLRETURN SQLSetPos(SQLHSTMT StatementHandle, uint RowNumber, SQLBulkOperation Operation,
		SQL_LOCK LockType);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 3.0 Standards Compliance: ISO 92</para>
	/// <para><c>Summary</c><c>SQLSetStmtAttr</c> sets attributes related to a statement.</para>
	/// <para>
	/// <para>Note</para>
	/// <para>
	/// For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x
	/// driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
	/// </para>
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="Attribute">[Input] Option to set, listed in "Comments."</param>
	/// <param name="ValuePtr">
	/// <para>[Input] Value to be associated with Attribute. Depending on the value of Attribute, ValuePtr will be one of the following:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>An ODBC descriptor handle.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>A uint value.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>A nuint value.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>A pointer to one of the following:</para>
	/// </description>
	/// </item>
	/// </list>
	/// <para>If the Attribute argument is a driver-specific value, ValuePtr may be a signed integer.</para>
	/// </param>
	/// <param name="StringLength">
	/// <para>
	/// [Input] If Attribute is an ODBC-defined attribute and ValuePtr points to a character string or a binary buffer, this argument should
	/// be the length of *ValuePtr. If Attribute is an ODBC-defined attribute and ValuePtr is an integer, StringLength is ignored.
	/// </para>
	/// <para>
	/// If Attribute is a driver-defined attribute, the application indicates the nature of the attribute to the Driver Manager by setting
	/// the StringLength argument. StringLength can have the following values:
	/// </para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>If ValuePtr is a pointer to a character string, then StringLength is the length of the string or SQL_NTS.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a binary buffer, then the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in
	/// StringLength. This places a negative value in StringLength.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>
	/// If ValuePtr is a pointer to a value other than a character string or a binary string, then StringLength should have the value SQL_IS_POINTER.
	/// </para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>If ValuePtr contains a fixed-length value, then StringLength is either SQL_IS_INTEGER or SQL_IS_UINTEGER, as appropriate.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetstmtattr-function?view=sql-server-ver16 SQLRETURN SQLSetStmtAttr(
	// SQLHSTMT StatementHandle, int Attribute, IntPtr ValuePtr, int StringLength);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle, SQL_ATTR Attribute, [In] IntPtr ValuePtr,
		int StringLength);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: Open Group</para>
	/// <para><c>Summary</c><c>SQLSpecialColumns</c> retrieves the following information about columns within a specified table:</para>
	/// <list type="bullet">
	/// <item>
	/// <description>
	/// <para>The optimal set of columns that uniquely identifies a row in the table.</para>
	/// </description>
	/// </item>
	/// <item>
	/// <description>
	/// <para>Columns that are automatically updated when any value in the row is updated by a transaction.</para>
	/// </description>
	/// </item>
	/// </list>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="IdentifierType">
	/// <para>[Input] Type of column to return. Must be one of the following values:</para>
	/// <para>
	/// SQL_BEST_ROWID: Returns the optimal column or set of columns that, by retrieving values from the column or columns, allows any row in
	/// the specified table to be uniquely identified. A column can be either a pseudo-column specifically designed for this purpose (as in
	/// Oracle ROWID or Ingres TID) or the column or columns of any unique index for the table.
	/// </para>
	/// <para>
	/// SQL_ROWVER: Returns the column or columns in the specified table, if any, that are automatically updated by the data source when any
	/// value in the row is updated by any transaction (as in SQLBase ROWID or Sybase TIMESTAMP).
	/// </para>
	/// </param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name for the table. If a driver supports catalogs for some tables but not for others, such as when the driver
	/// retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have catalogs. CatalogName cannot contain
	/// a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] Schema name for the table. If a driver supports schemas for some tables but not for others, such as when the driver retrieves
	/// data from different DBMSs, an empty string ("") denotes those tables that do not have schemas. SchemaName cannot contain a string
	/// search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] Table name. This argument cannot be a null pointer. TableName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <param name="Scope">
	/// <para>[Input] Minimum required scope of the rowid. The returned rowid may be of greater scope. Must be one of the following:</para>
	/// <para>
	/// SQL_SCOPE_CURROW: The rowid is guaranteed to be valid only while positioned on that row. A later reselect using rowid may not return
	/// a row if the row was updated or deleted by another transaction.
	/// </para>
	/// <para>SQL_SCOPE_TRANSACTION: The rowid is guaranteed to be valid for the duration of the current transaction.</para>
	/// <para>SQL_SCOPE_SESSION: The rowid is guaranteed to be valid for the duration of the session (across transaction boundaries).</para>
	/// </param>
	/// <param name="Nullable">
	/// <para>[Input] Determines whether to return special columns that can have a NULL value. Must be one of the following:</para>
	/// <para>
	/// SQL_NO_NULLS: Exclude special columns that can have NULL values. Some drivers cannot support SQL_NO_NULLS, and these drivers will
	/// return an empty result set if SQL_NO_NULLS was specified. Applications should be prepared for this case and request SQL_NO_NULLS only
	/// if it is absolutely required.
	/// </para>
	/// <para>SQL_NULLABLE: Return special columns even if they can have NULL values.</para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlspecialcolumns-function?view=sql-server-ver16 SQLRETURN
	// SQLSpecialColumns( SQLHSTMT StatementHandle, short IdentifierType, byte * CatalogName, short NameLength1, byte * SchemaName, short
	// NameLength2, byte * TableName, short NameLength3, short Scope, short Nullable);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLSpecialColumns(SQLHSTMT StatementHandle, SQL_COLID IdentifierType,
		string CatalogName, short NameLength1, string SchemaName, short NameLength2,
		string TableName, short NameLength3, SQL_SCOPE Scope, SQL_NULLABILITY Nullable);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ISO 92</para>
	/// <para>
	/// <c>Summary</c><c>SQLStatistics</c> retrieves a list of statistics about a single table and the indexes associated with the table. The
	/// driver returns the information as a result set.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") indicates those tables that do not have catalogs. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] Schema name. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") indicates those tables that do not have schemas. SchemaName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] Table name. This argument cannot be a null pointer. SchemaName cannot contain a string search pattern.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is an ordinary argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <param name="Unique">[Input] Type of index: SQL_INDEX_UNIQUE or SQL_INDEX_ALL.</param>
	/// <param name="Reserved">
	/// <para>
	/// [Input] Indicates the importance of the CARDINALITY and PAGES columns in the result set. The following options affect the return of
	/// the CARDINALITY and PAGES columns only; index information is returned even if CARDINALITY and PAGES are not returned.
	/// </para>
	/// <para>
	/// SQL_ENSURE requests that the driver unconditionally retrieve the statistics. (Drivers that conform only to the Open Group standard
	/// and do not support ODBC extensions will not be able to support SQL_ENSURE.)
	/// </para>
	/// <para>
	/// SQL_QUICK requests that the driver retrieve the CARDINALITY and PAGES only if they are readily available from the server. In this
	/// case, the driver does not ensure that the values are current. (Applications that are written to the Open Group standard will always
	/// get SQL_QUICK behavior from ODBC 3.x-compliant drivers.)
	/// </para>
	/// </param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlstatistics-function?view=sql-server-ver16 SQLRETURN SQLStatistics(
	// SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte * TableName, short
	// NameLength3, uint Unique, uint Reserved);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLStatistics(SQLHSTMT StatementHandle, string CatalogName, short NameLength1,
		string SchemaName, short NameLength2, string TableName, short NameLength3, SQL_INDEX Unique, SQL_RES Reserved);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: ODBC</para>
	/// <para>
	/// <c>Summary</c><c>SQLTablePrivileges</c> returns a list of tables and the privileges associated with each table. The driver returns
	/// the information as a result set on the specified statement.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Table catalog. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from
	/// different DBMSs, an empty string ("") denotes those tables that do not have catalogs. CatalogName cannot contain a string search pattern.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is significant. For more
	/// information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] String search pattern for schema names. If a driver supports schemas for some tables but not for others, such as when the
	/// driver retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have schemas.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] String search pattern for table names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqltableprivileges-function?view=sql-server-ver16 SQLRETURN
	// SQLTablePrivileges( SQLHSTMT StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte *
	// TableName, short NameLength3);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLTablePrivileges(SQLHSTMT StatementHandle, string CatalogName,
		short NameLength1, string SchemaName, short NameLength2, string TableName, short NameLength3);

	/// <summary>
	/// <para><c>Conformance</c> Version Introduced: ODBC 1.0 Standards Compliance: Open Group</para>
	/// <para>
	/// <c>Summary</c><c>SQLTables</c> returns the list of table, catalog, or schema names, and table types, stored in a specific data
	/// source. The driver returns the information as a result set.
	/// </para>
	/// </summary>
	/// <param name="StatementHandle">[Input] Statement handle for retrieved results.</param>
	/// <param name="CatalogName">
	/// <para>
	/// [Input] Catalog name. The CatalogName argument accepts search patterns if the SQL_ODBC_VERSION environment attribute is SQL_OV_ODBC3;
	/// it does not accept search patterns if SQL_OV_ODBC2 is set. If a driver supports catalogs for some tables but not for others, such as
	/// when a driver retrieves data from different DBMSs, an empty string ("") indicates those tables that do not have catalogs.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, CatalogName is a pattern value argument; it is treated literally, and its case is significant. For
	/// more information, see Arguments in Catalog Functions.
	/// </para>
	/// </param>
	/// <param name="NameLength1">[Input] Length in characters of *CatalogName.</param>
	/// <param name="SchemaName">
	/// <para>
	/// [Input] String search pattern for schema names. If a driver supports schemas for some tables but not for others, such as when the
	/// driver retrieves data from different DBMSs, an empty string ("") indicates those tables that do not have schemas.
	/// </para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength2">[Input] Length in characters of *SchemaName.</param>
	/// <param name="TableName">
	/// <para>[Input] String search pattern for table names.</para>
	/// <para>
	/// If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case is not
	/// significant. If it is SQL_FALSE, TableName is a pattern value argument; it is treated literally, and its case is significant.
	/// </para>
	/// </param>
	/// <param name="NameLength3">[Input] Length in characters of *TableName.</param>
	/// <param name="TableType">
	/// <para>[Input] List of table types to match.</para>
	/// <para>
	/// Notice that the SQL_ATTR_METADATA_ID statement attribute has no effect upon the TableType argument. TableType is a value list
	/// argument, regardless of the setting of SQL_ATTR_METADATA_ID.
	/// </para>
	/// </param>
	/// <param name="NameLength4">[Input] Length in characters of *TableType.</param>
	/// <returns>SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.</returns>
	// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqltables-function?view=sql-server-ver16 SQLRETURN SQLTables( SQLHSTMT
	// StatementHandle, byte * CatalogName, short NameLength1, byte * SchemaName, short NameLength2, byte * TableName, short NameLength3,
	// byte * TableType, short NameLength4);
	[PInvokeData("sql.h")]
	[DllImport(Lib_Odbc32, SetLastError = false, CharSet = CharSet.Auto)]
	public static extern SQLRETURN SQLTables(SQLHSTMT StatementHandle, string CatalogName, short NameLength1,
		string SchemaName, short NameLength2, string TableName, short NameLength3,
		string TableType, short NameLength4);

	internal static SQL_HANDLE GetHandleVal(this ISQLHANDLE h) => h switch
	{
		SQLHDBC _ => SQL_HANDLE.SQL_HANDLE_DBC,
		SafeSQLHDBC _ => SQL_HANDLE.SQL_HANDLE_DBC,
		SQLHDESC _ => SQL_HANDLE.SQL_HANDLE_DESC,
		SafeSQLHDESC _ => SQL_HANDLE.SQL_HANDLE_DESC,
		SQLHENV _ => SQL_HANDLE.SQL_HANDLE_ENV,
		SafeSQLHENV _ => SQL_HANDLE.SQL_HANDLE_ENV,
		SQLHSTMT _ => SQL_HANDLE.SQL_HANDLE_STMT,
		SafeSQLHSTMT _ => SQL_HANDLE.SQL_HANDLE_STMT,
		_ => throw new ArgumentException(null, nameof(h))
	};

	internal static SQL_HANDLE GetHandleVal<T>() => typeof(T) switch
	{
		Type t when t == typeof(SQLHDBC) || t == typeof(SafeSQLHDBC) => SQL_HANDLE.SQL_HANDLE_DBC,
		Type t when t == typeof(SQLHDESC) || t == typeof(SafeSQLHDESC) => SQL_HANDLE.SQL_HANDLE_DESC,
		Type t when t == typeof(SQLHENV) || t == typeof(SafeSQLHENV) => SQL_HANDLE.SQL_HANDLE_ENV,
		Type t when t == typeof(SQLHSTMT) || t == typeof(SafeSQLHSTMT) => SQL_HANDLE.SQL_HANDLE_STMT,
		_ => throw new ArgumentException(null, nameof(T)),
	};

	/// <summary>Provides a handle to a ODBC connection.</summary>
	/// <remarks>Initializes a new instance of the <see cref="SQLHDBC"/> struct.</remarks>
	/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
	[StructLayout(LayoutKind.Sequential)]
	public readonly struct SQLHDBC(IntPtr preexistingHandle) : ISQLHANDLE
	{
		private readonly IntPtr handle = preexistingHandle;

		/// <summary>Returns an invalid handle by instantiating a <see cref="SQLHDBC"/> object with <see cref="IntPtr.Zero"/>.</summary>
		public static SQLHDBC NULL => new(IntPtr.Zero);

		/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
		public readonly bool IsNull => handle == IntPtr.Zero;

		/// <summary>Implements the operator !.</summary>
		/// <param name="h1">The handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !(SQLHDBC h1) => h1.IsNull;

		/// <summary>Performs an explicit conversion from <see cref="SQLHDBC"/> to <see cref="IntPtr"/>.</summary>
		/// <param name="h">The handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static explicit operator IntPtr(SQLHDBC h) => h.handle;

		/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="SQLHDBC"/>.</summary>
		/// <param name="h">The pointer to a handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHDBC(IntPtr h) => new(h);

		/// <summary>Implements the operator !=.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !=(SQLHDBC h1, SQLHDBC h2) => !(h1 == h2);

		/// <summary>Implements the operator ==.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator ==(SQLHDBC h1, SQLHDBC h2) => h1.Equals(h2);

		/// <inheritdoc/>
		public override readonly bool Equals(object? obj) => obj is SQLHDBC h && handle == h.handle;

		/// <inheritdoc/>
		public override readonly int GetHashCode() => handle.GetHashCode();

		/// <inheritdoc/>
		public readonly IntPtr DangerousGetHandle() => handle;
	}

	/// <summary>Provides a handle to an ODBC Description.</summary>
	/// <remarks>Initializes a new instance of the <see cref="SQLHDESC"/> struct.</remarks>
	/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
	[StructLayout(LayoutKind.Sequential)]
	public readonly struct SQLHDESC(IntPtr preexistingHandle) : ISQLHANDLE
	{
		private readonly IntPtr handle = preexistingHandle;

		/// <summary>Returns an invalid handle by instantiating a <see cref="SQLHDESC"/> object with <see cref="IntPtr.Zero"/>.</summary>
		public static SQLHDESC NULL => new(IntPtr.Zero);

		/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
		public readonly bool IsNull => handle == IntPtr.Zero;

		/// <summary>Implements the operator !.</summary>
		/// <param name="h1">The handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !(SQLHDESC h1) => h1.IsNull;

		/// <summary>Performs an explicit conversion from <see cref="SQLHDESC"/> to <see cref="IntPtr"/>.</summary>
		/// <param name="h">The handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static explicit operator IntPtr(SQLHDESC h) => h.handle;

		/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="SQLHDESC"/>.</summary>
		/// <param name="h">The pointer to a handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHDESC(IntPtr h) => new(h);

		/// <summary>Implements the operator !=.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !=(SQLHDESC h1, SQLHDESC h2) => !(h1 == h2);

		/// <summary>Implements the operator ==.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator ==(SQLHDESC h1, SQLHDESC h2) => h1.Equals(h2);

		/// <inheritdoc/>
		public override readonly bool Equals(object? obj) => obj is SQLHDESC h && handle == h.handle;

		/// <inheritdoc/>
		public override readonly int GetHashCode() => handle.GetHashCode();

		/// <inheritdoc/>
		public readonly IntPtr DangerousGetHandle() => handle;
	}

	/// <summary>Provides a handle to an ODBC environment.</summary>
	/// <remarks>Initializes a new instance of the <see cref="SQLHENV"/> struct.</remarks>
	/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
	[StructLayout(LayoutKind.Sequential)]
	public readonly struct SQLHENV(IntPtr preexistingHandle) : ISQLHANDLE
	{
		private readonly IntPtr handle = preexistingHandle;

		/// <summary>Returns an invalid handle by instantiating a <see cref="SQLHENV"/> object with <see cref="IntPtr.Zero"/>.</summary>
		public static SQLHENV NULL => new(IntPtr.Zero);

		/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
		public readonly bool IsNull => handle == IntPtr.Zero;

		/// <summary>Implements the operator !.</summary>
		/// <param name="h1">The handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !(SQLHENV h1) => h1.IsNull;

		/// <summary>Performs an explicit conversion from <see cref="SQLHENV"/> to <see cref="IntPtr"/>.</summary>
		/// <param name="h">The handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static explicit operator IntPtr(SQLHENV h) => h.handle;

		/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="SQLHENV"/>.</summary>
		/// <param name="h">The pointer to a handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHENV(IntPtr h) => new(h);

		/// <summary>Implements the operator !=.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !=(SQLHENV h1, SQLHENV h2) => !(h1 == h2);

		/// <summary>Implements the operator ==.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator ==(SQLHENV h1, SQLHENV h2) => h1.Equals(h2);

		/// <inheritdoc/>
		public override readonly bool Equals(object? obj) => obj is SQLHENV h && handle == h.handle;

		/// <inheritdoc/>
		public override readonly int GetHashCode() => handle.GetHashCode();

		/// <inheritdoc/>
		public readonly IntPtr DangerousGetHandle() => handle;
	}

	/// <summary>Provides a handle to an ODBC statement.</summary>
	/// <remarks>Initializes a new instance of the <see cref="SQLHSTMT"/> struct.</remarks>
	/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
	[StructLayout(LayoutKind.Sequential)]
	public readonly struct SQLHSTMT(IntPtr preexistingHandle) : ISQLHANDLE
	{
		private readonly IntPtr handle = preexistingHandle;

		/// <summary>Returns an invalid handle by instantiating a <see cref="SQLHSTMT"/> object with <see cref="IntPtr.Zero"/>.</summary>
		public static SQLHSTMT NULL => new(IntPtr.Zero);

		/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
		public readonly bool IsNull => handle == IntPtr.Zero;

		/// <summary>Implements the operator !.</summary>
		/// <param name="h1">The handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !(SQLHSTMT h1) => h1.IsNull;

		/// <summary>Performs an explicit conversion from <see cref="SQLHSTMT"/> to <see cref="IntPtr"/>.</summary>
		/// <param name="h">The handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static explicit operator IntPtr(SQLHSTMT h) => h.handle;

		/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="SQLHSTMT"/>.</summary>
		/// <param name="h">The pointer to a handle.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHSTMT(IntPtr h) => new(h);

		/// <summary>Implements the operator !=.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !=(SQLHSTMT h1, SQLHSTMT h2) => !(h1 == h2);

		/// <summary>Implements the operator ==.</summary>
		/// <param name="h1">The first handle.</param>
		/// <param name="h2">The second handle.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator ==(SQLHSTMT h1, SQLHSTMT h2) => h1.Equals(h2);

		/// <inheritdoc/>
		public override readonly bool Equals(object? obj) => obj is SQLHSTMT h && handle == h.handle;

		/// <inheritdoc/>
		public override readonly int GetHashCode() => handle.GetHashCode();

		/// <inheritdoc/>
		public readonly IntPtr DangerousGetHandle() => handle;
	}

	/// <summary>
	/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHDBC"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
	/// </summary>
	public class SafeSQLHDBC : SafeHANDLE, ISQLHANDLE
	{
		/// <summary>Initializes a new instance of the <see cref="SafeSQLHDBC"/> class and assigns an existing handle.</summary>
		/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
		/// <param name="ownsHandle">
		/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
		/// </param>
		public SafeSQLHDBC(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }

		/// <summary>Initializes a new instance of the <see cref="SafeSQLHDBC"/> class.</summary>
		private SafeSQLHDBC() : base() { }

		/// <summary>Performs an implicit conversion from <see cref="SafeSQLHDBC"/> to <see cref="SQLHDBC"/>.</summary>
		/// <param name="h">The safe handle instance.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHDBC(SafeSQLHDBC h) => h.handle;

		/// <inheritdoc/>
		protected override bool InternalReleaseHandle() => SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DBC, handle).SQL_SUCCEEDED();
	}

	/// <summary>
	/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHDESC"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
	/// </summary>
	public class SafeSQLHDESC : SafeHANDLE, ISQLHANDLE
	{
		/// <summary>Initializes a new instance of the <see cref="SafeSQLHDESC"/> class and assigns an existing handle.</summary>
		/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
		/// <param name="ownsHandle">
		/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
		/// </param>
		public SafeSQLHDESC(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }

		/// <summary>Initializes a new instance of the <see cref="SafeSQLHDESC"/> class.</summary>
		private SafeSQLHDESC() : base() { }

		/// <summary>Performs an implicit conversion from <see cref="SafeSQLHDESC"/> to <see cref="SQLHDESC"/>.</summary>
		/// <param name="h">The safe handle instance.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHDESC(SafeSQLHDESC h) => h.handle;

		/// <inheritdoc/>
		protected override bool InternalReleaseHandle() => SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_DESC, handle).SQL_SUCCEEDED();
	}

	/// <summary>
	/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHENV"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
	/// </summary>
	public class SafeSQLHENV : SafeHANDLE, ISQLHANDLE
	{
		/// <summary>Initializes a new instance of the <see cref="SafeSQLHENV"/> class and assigns an existing handle.</summary>
		/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
		/// <param name="ownsHandle">
		/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
		/// </param>
		public SafeSQLHENV(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }

		/// <summary>Initializes a new instance of the <see cref="SafeSQLHENV"/> class.</summary>
		private SafeSQLHENV() : base() { }

		/// <summary>Performs an implicit conversion from <see cref="SafeSQLHENV"/> to <see cref="SQLHENV"/>.</summary>
		/// <param name="h">The safe handle instance.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHENV(SafeSQLHENV h) => h.handle;

		/// <inheritdoc/>
		protected override bool InternalReleaseHandle() => SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_ENV, handle).SQL_SUCCEEDED();
	}

	/// <summary>
	/// Provides a <see cref="SafeHandle"/> for <see cref="SQLHSTMT"/> that is disposed using <see cref="SQLFreeHandle(SQL_HANDLE, IntPtr)"/>.
	/// </summary>
	public class SafeSQLHSTMT : SafeHANDLE, ISQLHANDLE
	{
		/// <summary>Initializes a new instance of the <see cref="SafeSQLHSTMT"/> class and assigns an existing handle.</summary>
		/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
		/// <param name="ownsHandle">
		/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
		/// </param>
		public SafeSQLHSTMT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }

		/// <summary>Initializes a new instance of the <see cref="SafeSQLHSTMT"/> class.</summary>
		private SafeSQLHSTMT() : base() { }

		/// <summary>Performs an implicit conversion from <see cref="SafeSQLHSTMT"/> to <see cref="SQLHSTMT"/>.</summary>
		/// <param name="h">The safe handle instance.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator SQLHSTMT(SafeSQLHSTMT h) => h.handle;

		/// <inheritdoc/>
		protected override bool InternalReleaseHandle() => SQLFreeHandle(SQL_HANDLE.SQL_HANDLE_STMT, handle).SQL_SUCCEEDED();
	}
}