2013-07-26 159 views
2

我正在使用ADO(德爾福& C++ Builder),我想獲得一些TADOTable組件中的主鍵字段(它們的名稱)。怎麼做?ADO - 如何獲得主鍵字段

我發現我需要使用ADOConnection->的OpenSchema,但不知道如何使用這個..

現在,我想這一點:

int bounds[] = {0,2}; 
OleVariant A(bounds,1, varVariant); 
A.PutElement(varEmpty,0); 
A.PutElement(varEmpty,1); 
A.PutElement("MyDBTable",2); 


OleVariant EmptyParam; 
EmptyParam.VType = VT_ERROR; 
EmptyParam.VError = DISP_E_PARAMNOTFOUND; 
TADODataSet *temp = new TADODataSet(NULL); 

AdoConnection1->OpenSchema(siPrimaryKeys, A, EmptyParam, temp); 
temp->Open(); 
temp->First(); 
while (!temp->Eof) 
{ 
    Memo1->Lines->Add(temp->Fields->Fields[0]->AsString); 
    temp->Next(); 
} 
temp->Close(); 
delete temp; 

運行此代碼我得到: 「對象或提供者無法執行請求的操作。」?

回答

4

參考OpenSchema Method (ADO),實例可以發現here

一個例子FPGA實現在Delphi用於Microsoft AC塞斯和MSSQLSERVER看起來是這樣的:

Procedure OpenPrimaryKeyInfo (Connection:TAdoConnection 
          ; DatabaseName , SchemaName , TableName : Variant 
          ; Display:TAdodataset); 
begin 
    Connection.OpenSchema(siPrimaryKeys 
         , VarArrayOf([ DatabaseName , SchemaName , TableName ]) 
         , EmptyParam , Display); 
end; 

調用示例爲Microsoft Access:

OpenPrimaryKeyInfo(AdoConnection2 , UnAssigned , UnAssigned , 'TableX' , Adodataset1); 

調用示例爲MSSQLSERVER:

OpenPrimaryKeyInfo(AdoConnection1 , 'MyDataBase' , 'dbo' , 'TableX' , Adodataset1); 
+0

這看起來不錯。這只是..如何在C++ Builder中編寫VarArrayOf([DatabaseName,SchemaName,TableName])? – Tracer

+0

@Tracer:[documentation](http://docwiki.embarcadero.com/Libraries/XE4/en/System.Variants.VarArrayOf)顯示了C++ Builder的語法(有一個指向C++代碼示例的鏈接該頁面也是如此)。 –

+0

謝謝。我沒有看到它。我現在將嘗試編碼這.. – Tracer

3

建立連接並像往常一樣打開它(使用TADOConnection.ConnectionStringTADOConnection.Open),然後使用OpenSchema詢問模式。您提供的TADODataSet作爲最後一個參數將包含一個RecordSet,您可以像使用任何其他數據集一樣使用它。

下面是我扔在一起的一個快速樣本(感謝@bummi對第三個參數 - UnassignedNull進行了修正,但在測試時沒有真正的工作)。我在新窗體上刪除了一個TADOConnection,TADODataSetTMemo,並將TADOConnection快速配置爲指向一個簡單的SQL Server Express數據庫,用於某些測試 - 包括連接字符串;我對它做出的唯一修改是在Data Source部分提供的計算機名稱中)。

procedure TForm3.FormShow(Sender: TObject); 
var 
    i: Integer; 
    sLine: string; 
begin 
    Memo1.Clear; 
    ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;' + 
            'Integrated Security=SSPI;' + 
            'Persist Security Info=False;' + 
            'Initial Catalog=Contacts;' + 
            'Data Source=MyComputer\SQLEXPRESS'; 
    ADOConnection1.Connected := True; 
    ADOConnection1.OpenSchema(siPrimaryKeys, Unassigned, EmptyParam, ADODataSet1); 
    sLine := ''; 
    for i := 0 to ADODataSet1.FieldCount - 1 do 
    sLine := sLine + ADODataSet1.Fields[i].FieldName + #9; 
    Memo1.Lines.Add(sLine); 
    Memo1.Lines.Add(''); 

    while not ADODataSet1.Eof do 
    begin 
    sLine := ''; 
    for i := 0 to ADODataSet1.FieldCount - 1 do 
     sLine := sLine + ADODataSet1.Fields[i].AsString + #9; 
    Memo1.Lines.Add(sLine); 
    ADODataSet1.Next; 
    end; 
end; 

SchemaInfo值(傳遞給OpenSchema第一個參數)的可能值可以在ADODB單位發現 - 他們記錄在Delphi help file(注意,文件說,不是所有的人都可以經由ADO):

TSchemaInfo = (siAsserts, siCatalogs, siCharacterSets, siCollations, 
    siColumns, siCheckConstraints, siConstraintColumnUsage, 
    siConstraintTableUsage, siKeyColumnUsage, siReferentialConstraints, 
    siTableConstraints, siColumnsDomainUsage, siIndexes, siColumnPrivileges, 
    siTablePrivileges, siUsagePrivileges, siProcedures, siSchemata, 
    siSQLLanguages, siStatistics, siTables, siTranslations, siProviderTypes, 
    siViews, siViewColumnUsage, siViewTableUsage, siProcedureParameters, 
    siForeignKeys, siPrimaryKeys, siProcedureColumns, siDBInfoKeywords, 
    siDBInfoLiterals, siCubes, siDimensions, siHierarchies, siLevels, 
    siMeasures, siProperties, siMembers, siProviderSpecific); 
+0

沒有第二個未分配的需要是EmptyParam這樣,我無法讓它與Unassigned一起工作。 – bummi

+0

@bummi:是的,你絕對正確。它用'Null'和'Unassigned'編譯,但在實際運行代碼時失敗。我已經糾正了它(給予適當的獎勵以便發現它),並且包括實際工作測試代碼。謝謝你的收穫。 (我已經提出了你的答案,順便說一下。):-) –