PL / SQL存储过程,根据用户输入值输出值

时间:2015-06-17 22:30:38

标签: oracle stored-procedures plsql

我有一个Oracle表(示例):

+----------------------------+----------------+-----------------------+
|     DEPT                   |   BUILDINGID   |      GEOMETRY         |
+----------------------------+----------------------------------------+
| Emergency Services AMB     |      516       |  [MDSYS.SDO_GEOMETRY] |
| Emergency Services AMB     |      287       |  [MDSYS.SDO_GEOMETRY] |
| Emergency Services FIRE    |      283       |  [MDSYS.SDO_GEOMETRY] |
| Emergency Services FIRE    |      460       |  [MDSYS.SDO_GEOMETRY] |
| Emergency Services POLICE  |      515       |  [MDSYS.SDO_GEOMETRY] |
+----------------------------+----------------------------------------+

我正在制作一个PL / SQL存储过程,要求用户插入他们想要的部门。然后部门名称将链接到其ID(BUILDINGID)和LONGITUDE和LATITUDE。

输出需要如下:

Type of Building:

BUILDINGID      LONGITUDE      LATITUDE
----------      ---------      --------

我已经启动了以下代码,但我仍然试图将BUILDINGID与用户输入的部门相关联。同样,我如何分别显示经度和纬度? (因为它们出现在[MDSYS.SDO_GEOMETRY])?

CREATE OR REPLACE PROCEDURE outputBuilding              --create procedure
  (i_building_type IN VARCHAR2 (20),
   i_BuildingID IN OTTAWABUILDINGS.BUILDINGID%TYPE,
   i_longitude IN OTTAWABUILDINGS.GEOMETRY%Type,
   i_latitude IN OTTAWABUILDINGS.GEOMETRY%Type) IS


CURSOR c_building IS
SELECT DEPT, BUILDINGID
FROM OTTAWABUILDINGS;
r_building c_building%ROWTYPE;

BEGIN
v_type := '&TypeOfBuilding';   --user inserts type of building

DBMS_OUTPUT.PUT_LINE('Type of Building: ' ||v_type);
DBMS_OUTPUT.PUT_LINE ('BUILDINGID   ' || 'LONGITUDE   ' ||'LATITUDE    ' );
DBMS_OUTPUT.PUT_LINE ('----------   ' || '----------   ' ||'----------    ' );

    FOR r_building IN c_building
    LOOP 
        SELECT DEPT INTO v_type FROM OTTAWABUILDINGS WHERE DEPT = v_type;
        IF v_type = 'Emergency Services POLICE' OR
        v_type = 'Emergency Services AMB' OR
        v_type = 'Emergency Services FIRE' THEN
        DBMS_OUTPUT.PUT_LINE (i_BuildingID || '   ' || i_longitude || '   ' || i_latitude);
        END IF;
    END LOOP;
COMMIT;
END outputBuilding;

-----------TESTING STORED PROCEDURE---------------
BEGIN
  outputBuilding (i_BuildingID, i_longitude, i_latitude);
END;

1 个答案:

答案 0 :(得分:3)

设计程序需要一些规划和思考。您需要了解需求并在代码中实现它们。

所以第一个要求是:

  

要求用户插入他们希望的部门

这意味着您的程序应该采用一个参数:

CREATE OR REPLACE PROCEDURE outputBuilding             
  (i_building_type IN VARCHAR2 )
IS

请注意,参数不受长度限制(正如'紧急服务警察'超过20个字符一样)。

下一个要求:

  

部门名称将链接到

这意味着您需要使用该参数来过滤查询。为了清楚起见,我们将坚持使用您的显式光标。

CURSOR c_building IS
    SELECT DEPT, BUILDINGID
    FROM OTTAWABUILDINGS
    where dept = i_building_type;

下一个要求是:

  

部门名称将链接到其ID(BUILDINGID)和LONGITUDE和LATITUDE

嗯,我们最好在查询中包含几何列。

CURSOR c_building IS
    SELECT DEPT, BUILDINGID, geometry
    FROM OTTAWABUILDINGS
    where dept = i_building_type;
r_building c_building%ROWTYPE;

最终,最棘手的要求

  

分别显示经度和纬度

这取决于经度和纬度的存储方式。我们希望它们存储为Points。所以你需要这样的东西:

v_long := r_building.geometry.SDO_POINT.X;
v_lat := r_building.geometry.SDO_POINT.Y;

警告:我现在无法访问具有空间的数据库,因此无法保证这一点。

代码中的冗余:

  • 不要将SQL * Plus语法与PL / SQL混合使用。用户通过参数传递建筑类型,因此请删除:v_type := '&TypeOfBuilding';
  • 同样,您不需要循环中的查询,因为光标会选择您需要的信息。
  • 您只是选择数据,因此不需要commit

所以修改后的存储过程看起来像这样:

CREATE OR REPLACE PROCEDURE outputBuilding             
  (i_building_type IN VARCHAR2) 
IS

    CURSOR c_building IS
        SELECT DEPT, BUILDINGID, geometry
        FROM OTTAWABUILDINGS
        where dept = i_building_type;
    r_building c_building%ROWTYPE;

    v_long varchar2(28);
    v_lat varchar2(28);

BEGIN

    DBMS_OUTPUT.PUT_LINE('Type of Building: ' ||v_type);
    DBMS_OUTPUT.PUT_LINE ('BUILDINGID   ' || 'LONGITUDE    ' ||'LATITUDE    ' );
    DBMS_OUTPUT.PUT_LINE ('----------   ' || '----------   ' ||'----------    ' );

    FOR r_building IN c_building
    LOOP 
        v_long := r_building.geometry.SDO_POINT.X;
        v_lat := r_building.geometry.SDO_POINT.Y;
        DBMS_OUTPUT.PUT_LINE (r_building.BuildingID || '   ' || v_long || '   ' || v_lat);
    END LOOP;
END outputBuilding;

我将重复我关于没有Spatial的声明,所以我无法编译它。因此,它可能包含语法错误,这些错误留给读者练习。

要打电话:

begin
    outputBuilding('Emergency Services POLICE');
end;