SQL-запрос к БД через ArcObjects?

0 голосов
спросил 29 Июнь, 05 от Rage (240 баллов) в категории Программные продукты Esri

Програмирую на Delphi. Столкнулся с рядом проблем при попытке выполнить произвольный! SQL-запрос к БД Oracle через ArcObjects (объект QueryDef). Проблемы связаны с использованием вычислений и групповых функций в этом SQL-запросе и органиченностью возможностей объекта QueryDef в этом отношении.

Попробовал заменить сложный SQL-запрос на вьюшку в БД и обращение к ней, но и тут возникли глюки: если поле вычисляемое, то не правильно определяется тип данных поля! Дробные значения округляются до целого!

Кто нибудь сталкивался с подобными проблемами? Можно ли получать данные из БД Oracle не через QueryDef, но при этом получать родной для ArcObjects интерфейс ITable к этим данным? Пожалуйста поделитесь вашими решениями, буду очень признателен : )

3 Ответы

0 голосов
ответил 17 Окт, 05 от filippov70 (5,320 баллов)

Здравствуйте Rage
ITable к ораклевой вьюшке (ссылка на воркспэйс берется через IFeatureLayer
 потому, как все в одной базе лежит)

правда это VB ....

Public Function PreSetORA(sTableName As String) As ITable

On Error GoTo err

  Dim pMxDoc As IMxDocument
  Set pMxDoc = ThisDocument
    Dim pFeatureCur As IFeatureCursor
    Dim pFeatureLayer As IFeatureLayer
    Dim pObject As IFeature
    Set pFeatureLayer = GetLayerByName(ZU)
    Set pFeatureCur = pFeatureLayer.Search(Nothing, False)
    Set pObject = pFeatureCur.NextFeature
   
  Dim pObjectClass As IObjectClass
  Dim pDataset As IDataset
  Dim pWorkspace As IFeatureWorkspace
  Set pObjectClass = pObject.Class
  Set pDataset = pObjectClass
  Set pWorkspace = pDataset.Workspace

  Set PreSetORA = pWorkspace.OpenTable(sTableName)
 
Exit Function

err:

MsgBox err.Description

End Function


0 голосов
ответил 20 Окт, 05 от Rage (240 баллов)

Спасибо за ответ nukevlad!

Но в моем случае не все лежит в одной базе, географически слои лежат на локальной машине в Базе геоданных *.mdb, а атрибутивные данные на удаленном сервере под СУБД Oracle. Вот оттуда я их и дергаю програмно и присоединяю к атрибутивной таблице слоя по общему ключевому полю путем создания MemoryRelationshipClass`a. Тут возникают проблемы, о которых я писал выше.

Ссылку на воркспейс я получаю через OleDBWorkspaceFactory.

На данном этапе реализовал ( на Delphi) свои потребности нижеследующими функциями, но проблема с самопроизвольным! округлением дробных значений вычисляемых полей присоединяемых вьюшек осталась (число 0,0115 например получается делением одного поля на другое, при выкачивании вьюшки в ArcMap оно округляется до 0 и никакие манипуляции с полями IField не помогли). Возможно это проблемы реализации СОМ-объектов ArcObjects, надеюсь в 9 версии ArcGIS они это исправят.

0 голосов
ответил 20 Окт, 05 от Rage (240 баллов)

Привожу свои исходники решения этой проблемы, может кому интересно

//делаем запрос в удаленную БД

function OraQuery(const sTableNames, sSubFields, sWhereClause: String): IName;
var
  cursor: HICON;
  pWorkspace: IWorkspace;
  pQueryDef: IQueryDef;
  pTableQueryName: IQueryName2;
  pWorkspaceName: IName;
  bCopyLocally: WordBool;
begin
  cursor:=SetCursor(LoadCursor(HInstance, 'SQLGlass'));
  try
    //Создаем  Workspace
    pWorkspace:=GetOracleWorkspace; //- см. ниже
    (pWorkspace as IFeatureWorkspace).CreateQueryDef(pQueryDef);
    pQueryDef.Set_Tables(sTableNames);
    pQueryDef.Set_SubFields(sSubFields);
    pQueryDef.Set_WhereClause(sWhereClause);
    pTableQueryName:=(CoTableQueryName.Create as IQueryName2);
    pTableQueryName.Set_QueryDef(pQueryDef);
    bCopyLocally := boolReadIni('CommonOptions', 'CopyLocaly');
    pTableQueryName.Set_CopyLocally(bCopyLocally);
    //pTableQueryName.Set_PrimaryKey(sTableKeyFieldName);не устанавливать иначе тормозит!!!
    (pWorkspace as IDataset).Get_FullName(pWorkspaceName);
    with (pTableQueryName as IDatasetName) do
    begin
      _Set_WorkspaceName(pWorkspaceName as IWorkspaceName);//строка обязательна!
      Set_Name('TmpQuery'+IntToStr(Random(9999)))//эта тоже
    end;
    Result:=(pTableQueryName as IName);

    {Result.Open(pT); - получаем искомую ссылку на закешированный на диске результат SQL запроса
    pStandaloneTable:=(CoStandaloneTable.Create as IStandaloneTable);
    pStandaloneTable._Set_Table(pT as ITable);
    (pApp.Document as IMxDocument).Get_FocusMap(pMap);
    (pMap as IStandaloneTableCollection).AddStandaloneTable(pStandaloneTa ble);
    (pApp.Document as IMxDocument).UpdateContents;}
  except
    on E: EAbort do Abort;
    on E: Exception do
    begin
      raise EGisException.CreateError(E, 'Ошибка при создании запроса в Оракл!'+#13#10+E.Message, 0, 'un_GisPipeline_DBFunc', 'OraQuery');
    end
  end;
  pWorkspace := nil;
  SetCursor(Cursor);
end;

//устанавливаем соединение с оракловой БД

function GetOracleWorkspace: IWorkspace;
var
  pOLEDBWorkspaceFactory: IWorkspaceFactory;

  pOraConProp: IPropertySet;

begin
    pOraConProp := MadeOracleConnectionProp; //- смысл - выдает диалог, запрашивающий имя и пароль и записывает их в специальную структуру IPropertySet
    try
      pOLEDBWorkspaceFactory:=(CoOLEDBWorkspaceFactory.Create as IWorkspaceFactory);
      pOLEDBWorkspaceFactory.Open(pOraConProp, 0, Result);
      pOLEDBWorkspaceFactory:=nil;
    except
      on E: Exception do
      begin
        ErrorHandler(E, E.Message, 0, 'un_GISPipeline_DBFunc', 'GetOracleWorkspace');
        pOraConProp:=nil;
      end
    end;
    if Result = nil then
    begin
      pOraConProp:=nil;
      MessageBox(Application.Handle, PAnsiChar('Не удалось установить соединение с Ораклом!'+#13#10+'Возможно введены неправильные имя пользователя и пароль или сервер временно не доступен!'), 'Внимание!', MB_OK+MB_ICONWARNING);
      raise EExitException.Create('');
    end;
end;

Добро пожаловать на сайт Вопросов и Ответов, где вы можете задавать вопросы по GIS тематике и получать ответы от других членов сообщества.
...