2013-07-26 4 views
2

Я использую ADO (Delphi & 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

в качестве примера РЕАЛИЗАЦИЯ в 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

Это выглядит великолепно. Это просто .. как написать VarArrayOf ([DatabaseName, SchemaName, TableName]) в C++ Builder? – Tracer

+0

@Tracer: [документация] (http://docwiki.embarcadero.com/Libraries/XE4/en/System.Variants.VarArrayOf) показывает синтаксис C++ Builder (есть ссылка на пример кода C++ внизу эта страница также). –

+0

Спасибо. Я этого не видел. Теперь я попытаюсь закодировать это. – Tracer

3

Вы устанавливаете соединение и открываете его как обычно (используя TADOConnection.ConnectionString и TADOConnection.Open), а затем запросите схему, используя OpenSchema. TADODataSet, который вы укажете в качестве последнего параметра, будет содержать RecordSet, который вы можете использовать так же, как и любой другой набор данных.

Вот быстрый образец, который я сбрасывал вместе (спасибо @bummi за поправку к третьему параметру - Unassigned и Null оба скомпилированы, но на самом деле не работали при тестировании). Я сбросил TADOConnection, TADODataSet и TMemo в новой форме и быстро установил 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», но сбой при фактическом запуске кода. Я исправил его (с соответствующим кредитом, предоставленным вам для определения его), и включил фактический рабочий тестовый код. Спасибо за уловку. (Я уже поддержал ваш ответ, BTW.) :-) –

Смежные вопросы