如何在oracle存储过程中将包含纬度/经度的数组保存到sdo_geometry对象

问题描述

我在包内创建了存储过程。我想在 sdo_geometry 对象中存储一个由 lat/lng 组成的点数组。

首先在包内声明类型

TYPE p_int_type 是数字表;

然后定义过程定义。

  PROCEDURE PRC_polyGON_ADD_TESTING(
  pPointArray IN p_int_type,pCODE OUT VARCHAR2,pDesc OUT VARCHAR2,pMSG OUT VARCHAR2 );

这是我的程序主体

 PROCEDURE PRC_polyGON_ADD_TESTING
    (
      pPointArray IN p_int_type,pMSG OUT VARCHAR2
    )
  AS
  BEGIN
      INSERT
    INTO CIRCLE_LOCATION
      (
        polygon
      )
      VALUES
      (
        sdo_geometry ( 2003      -- 2D polygon,4326                   -- wgs84,the typical GPS coordinate system,NULL                   -- sdo_point_type,should be NULL if sdo_ordinate_array specified,sdo_elem_info_array( 1 -- First ordinate position within ordinate array,1003                   -- Exterior polygon,1                      -- All polygon points are specified in the ordinate array
        ),sdo_ordinate_array(pPointArray))
      );
  END PRC_polyGON_ADD_TESTING;

但是我收到错误消息,这里不允许本地集合类型。 请指导我如何保存由 sdo_geometry 对象中的点经纬度组成的完整数组。点是动态的,这就是我想使用数组的原因。

解决方法

HWND myDialogGlobalHandle; int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); INITCOMMONCONTROLSEX InitCtrlEx; InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); InitCtrlEx.dwICC = ICC_PROGRESS_CLASS; InitCommonControlsEx(&InitCtrlEx); if (!CreateMyDialog(hInstance)) { //return FALSE; } else { MSG message = { 0 }; while (GetMessage(&message,nullptr,0)) { if (!IsDialogMessage(myDialogGlobalHandle,&message)) { DispatchMessage(&message); } } } HACCEL hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_PROJECT)); MSG msg; // Main message loop: while (GetMessage(&msg,0)) { if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } SDO_ORDINATE_ARRAY 不是相同的数据类型,您需要将值从一种类型转换为另一种类型。

创建包:

P_INT_TYPE

然后是正文,您需要将 CREATE PACKAGE package_name IS TYPE p_int_type IS TABLE OF number; PROCEDURE PRC_POLYGON_ADD_TESTING( pPointArray IN p_int_type,pCODE OUT VARCHAR2,pDesc OUT VARCHAR2,pMSG OUT VARCHAR2 ); END; / 转换为 p_int_type

SDO_ORDINATE_ARRAY

然后就可以调用包插入值了:

CREATE PACKAGE BODY package_name IS
  PROCEDURE PRC_POLYGON_ADD_TESTING(
    pPointArray IN p_int_type,pMSG OUT VARCHAR2
  )
  AS
    coords SDO_ORDINATE_ARRAY := SDO_ORDINATE_ARRAY();
  BEGIN
    coords.EXTEND( pPointArray.COUNT );
    FOR i IN 1 .. pPointArray.COUNT LOOP
      coords(i) := pPointArray(i);
    END LOOP;

    INSERT INTO CIRCLE_LOCATION
    (
      polygon
    ) VALUES (
      sdo_geometry(
          2003                   -- 2D Polygon,4326                   -- WGS84,the typical GPS coordinate system,NULL                   -- sdo_point_type,should be NULL if sdo_ordinate_array specified,sdo_elem_info_array(
            1                    -- First ordinate position within ordinate array,1003                 -- Exterior polygon,1                    -- All polygon points are specified in the ordinate array
        ),coords
      )
    );
  END PRC_POLYGON_ADD_TESTING;
END;
/

dbfiddle here


但是,您最好将过程声明为采用 DECLARE pCODE VARCHAR2(20); pDesc VARCHAR2(20); pMsg VARCHAR2(20); BEGIN PACKAGE_NAME.PRC_POLYGON_ADD_TESTING( PACKAGE_NAME.P_INT_TYPE( 0,10,0 ),pCode,pDesc,pMsg ); END; / ,而不是声明您自己的集合数据类型,然后您就不需要在类型之间进行转换。