VC++程序如何判定SQL Server的字段是自增长的?

来源:互联网 发布:成都网络教育平台登录 编辑:程序博客网 时间:2024/06/11 07:00
结论是通过ADO/ADOX的对象模式实现不可行.

问题源于一个简单的目标,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();intn1 = 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的值都是1537printf("%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"); ///< 出错位置1m_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 field
http://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_identityFROM     sys.tables t    INNER JOIN sys.columns c        ON t.object_id = c.object_idWHERE c.is_identity = 1

MySQL 
SELECT  column_name FROM    INFORMATION_SCHEMA.COLUMNS WHERE    table_name = "members" AND     extra = "auto_increment";


5.源问题解决方案

有2个选择:
(1)绑定时指定,需要知晓字段的该属性信息,且要适应数据结构的变化.当然,这种变化可能性很低.
(2)利用数据库扩展实现,直接访问系统表.


0 0