结论是通过ADO/ADOX的对象模式实现不可行.
问题源于一个简单的目标,vc++程序能够判定一个数据库表的某个字段是否是自增长的,这样可以在基于与类绑定的编程中,在处理insert,update时避开这类字段.
其中objectid是identity列,eid则不是。但运行结果n1,n2都是1.
ADOX代码(利用列的AutoIncrement属性)
使用不同的驱动分别测试:
Microsoft OLE DB Provider for SQL Server(SQLOLEDB.1)
SQL SErver Native Client 10.0(SQLNCLI10.1)
在出错位置2产生错误:对象或提供程序不能执行所需的操作.
Microsoft OLE DB Provider for ODBC Driver(MSDASQL.1)
在出错位置1,产生错误:在对应所需名称或序数的集合中,未找到项目
MSDN的ADOX示例中,
OLE DB Properties
https://msdn.microsoft.com/en-us/library/ms713689(v=vs.85).aspx
列举了所有属性包括了AutoIncrement.
Provider Support for ADOX (ADO)
https://msdn.microsoft.com/en-us/library/ms676495(v=vs.85).aspx
该文列出了各种OLE DB Provider的限制.
这些限制并没有包含对Column属性的访问.
ADOX FAQ
http://www.oblique.ch/ms/ADOX_Faq.html
也提到了对SQL Server的限制,不能创建Database.
ADOX in Detail
http://www.verycomputer.com/165_719757bbc3ef2a9d_1.htm
以下是其中的关键信息
提问者;
回答者:Steven Bras, MCSD
此贴是2001年.
Q288444 BUG: Problems Reading/Writing Dynamic Properties of ADOX Column
http://www.helpdoc-online.com/Microsoft_Knowledge_Base_October_2001_ActiveX_en/BUG_Problems_Reading_Writing_Dynamic_Properties_ADOX_Column.php
问题适用于ADO 2.5,2.6.
类似的帖子还有,也由Steven Bras做答,时间是2002年.
http://www.verycomputer.com/165_581334e03f9ab336_1.htm
目前仍没有变化吗?
并不是Microsoft OLE DB Provider for SQL Server声明的限制范围,也不应该是ADOX本身的问题,作何解释?
MySQL
(1)绑定时指定,需要知晓字段的该属性信息,且要适应数据结构的变化.当然,这种变化可能性很低.
(2)利用数据库扩展实现,直接访问系统表.
问题源于一个简单的目标,vc++程序能够判定一个数据库表的某个字段是否是自增长的,这样可以在基于与类绑定的编程中,在处理insert,update时避开这类字段.
但自增字段可能被查询,所以存在于类的绑定关系中.
1.测试代码与结果
ADO代码(利用列的ISAUTOINCREMENT属性)
_RecordsetPtr pRstEmployee = NULL; _ConnectionPtr pConnection = NULL; FieldsPtr fldLoop = NULL; TESTHR(pRstEmployee.CreateInstance(__uuidof(Recordset))); pRstEmployee->Open("t_ven_order", _variant_t((IDispatch *)pConnection,true), adOpenForwardOnly,adLockReadOnly, adCmdTable); fldLoop = pRstEmployee->GetFields(); int n1 = fldLoop->GetItem("eid")->GetProperties()->GetItem("ISAUTOINCREMENT")->Value; int n2 = fldLoop->GetItem("objectid")->GetProperties()->GetItem("ISAUTOINCREMENT")->Value;
其中objectid是identity列,eid则不是。但运行结果n1,n2都是1.
ADOX代码(利用列的AutoIncrement属性)
m_pCnn->Open(strcnn,"","",NULL); m_pCatalog->PutActiveConnection(_variant_t((IDispatch *) m_pCnn)); m_pTable= m_pCatalog->Tables->GetItem("t_ven_order"); int column_num = m_pTable->Columns->Count; _variant_t Index; Index.vt = VT_I2; for (int i=0;i<column_num;i++) { Index.iVal = i; m_pColumn = m_pTable->Columns->GetItem(Index); for (int j=0;j<m_pColumn->Properties->Count;j++) { Index.iVal = j; ///< 所有Attributes的值都是1537 printf("%s=%d\n",(LPSTR)_bstr_t(m_pColumn->Properties->GetItem(Index)->GetName()),m_pColumn->Properties->GetItem(Index)->Attributes); } m_pProperty = m_pColumn->Properties->GetItem("AutoIncrement"); ///< 出错位置1 m_pProperty->GetValue(); ///< 出错位置2 }
使用不同的驱动分别测试:
Microsoft OLE DB Provider for SQL Server(SQLOLEDB.1)
SQL SErver Native Client 10.0(SQLNCLI10.1)
在出错位置2产生错误:对象或提供程序不能执行所需的操作.
Microsoft OLE DB Provider for ODBC Driver(MSDASQL.1)
在出错位置1,产生错误:在对应所需名称或序数的集合中,未找到项目
MSDN的ADOX示例中,
m_pCatalog->Tables->GetItem("t_ven_order")->Columns->Append(m_pColumn->Name, adVarWChar, 24);在SQL Server上执行也产生异常(捕获的异常信息内容为null).
2.查阅资料
OLE DB Properties
https://msdn.microsoft.com/en-us/library/ms713689(v=vs.85).aspx
列举了所有属性包括了AutoIncrement.
Provider Support for ADOX (ADO)
https://msdn.microsoft.com/en-us/library/ms676495(v=vs.85).aspx
该文列出了各种OLE DB Provider的限制.
这些限制并没有包含对Column属性的访问.
ADOX FAQ
http://www.oblique.ch/ms/ADOX_Faq.html
也提到了对SQL Server的限制,不能创建Database.
ADOX in Detail
http://www.codeguru.com/cpp/data/mfc_database/ado/article.php/c4343/ADOX-in-Detail.htm
ADOX编程的简明的说明,本文的测试代码也没有看出问题.
相似的问题
Thread: ADOX and SQL Server
http://www.webdeveloper.com/forum/showthread.php?88240-ADOX-and-SQL-Server
多数涉及使用ADOX的文章都是针对MS Access的, Microsoft Jet 4.0 OLE DB Provider是全特性支持。
(因Office 2010的MS Access的accdb文件不能被识别,这步验证就没有继续.可能需要Microsoft Access 2010 数据库引擎可再发行程序包)
3.结论(目前)
ADOX, SQL Server and Autoincrement fieldhttp://www.verycomputer.com/165_719757bbc3ef2a9d_1.htm
以下是其中的关键信息
提问者;
How (with ADOX) read the autoincrement property (alt method)? With access provider it works fine, what's the problem
回答者:Steven Bras, MCSD
Unfortunately, the only "universal" library for accessing database schemas (from Microsoft at least) is ADOX; it does, admittedly, have its limitations. The only other solution I can think of is to query system tables in your particular database to obtain schema information.
// ******* The following GetValue call throws _com_error exception for error // ******* 800A0CB3 -- Object or provider is not capable of performing requested与本文测试的现象一致.
此贴是2001年.
Q288444 BUG: Problems Reading/Writing Dynamic Properties of ADOX Column
http://www.helpdoc-online.com/Microsoft_Knowledge_Base_October_2001_ActiveX_en/BUG_Problems_Reading_Writing_Dynamic_Properties_ADOX_Column.php
问题适用于ADO 2.5,2.6.
类似的帖子还有,也由Steven Bras做答,时间是2002年.
http://www.verycomputer.com/165_581334e03f9ab336_1.htm
目前仍没有变化吗?
并不是Microsoft OLE DB Provider for SQL Server声明的限制范围,也不应该是ADOX本身的问题,作何解释?
4.检查自增字段的SQL
SQL Server
SELECT t.name AS [TableName], c.Name AS [ColumnName], c.is_identity FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id WHERE c.is_identity = 1
MySQL
SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = "members" AND extra = "auto_increment";
5.源问题解决方案
有2个选择:(1)绑定时指定,需要知晓字段的该属性信息,且要适应数据结构的变化.当然,这种变化可能性很低.
(2)利用数据库扩展实现,直接访问系统表.