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

结论是通过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();
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 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_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)利用数据库扩展实现,直接访问系统表.


猜你喜欢

转载自blog.csdn.net/wherwh/article/details/49020057