PL / SQL中的存储过程在表中插入新记录

时间:2015-05-30 00:03:09

标签: oracle plsql

我需要创建一个PL / SQL存储过程来将记录添加到tblCity2表中。 tblCity2的样本:

+-------------+--------+-------------+------------+
|     NAME    | CAPITAL|  POPULATION | STATE_CODE |
+-------------+--------+-------------+------------+
| Monterrey   |   Y    |   2015000   |      MX19  |
| Mazatlan    |   N    |    199830   |      MX25  |
| Guadalajara |   Y    |   2325000   |      MX14  |
+-------------+--------+-------------+------------+

该程序接收4个参数:城市名称,城市是否为大都市,城市人口和州名称。状态名称取自表tblState2:

+------+-----------------------+---------+-----------+
| CODE |         NAME          | POP1990 | AREA_SQMI |
+------+-----------------------+---------+-----------+
| MX02 | Baja California Norte | 1660855 | 28002.325 |
| MX03 | Baja California Sur   |  317764 | 27898.191 |
| MX18 | Nayarit               |  824643 | 10547.762 |
+------+-----------------------+---------+-----------+

该过程调用存储函数向其传递状态名称,函数返回状态代码,然后与其他参数一起使用以在tblCity2中插入新记录。

我已经启动了一些代码,但我不确定下一步:

PROCEDURE question2
(i_StateName IN TBLSTATE2.NAME%TYPE,
i_CityName IN TBLCITY2.NAME%TYPE,
i_CityCapital IN TBLCITY2.CAPITAL%TYPE,
i_CityPopulation IN TBLCITY2.POPULATION%TYPE);

FUNCTION create_city
(i_StateName IN TBLSTATE2.NAME%TYPE)
RETURN [something??]
INSERT INTO TBLCITY2 VALUES;
END question2;

我还需要插入一个匿名程序块来调用该过程。它是否正确?我可以使用与上面相同的代码运行此代码,还是必须单独运行?

BEGIN
question2(i_StateName, i_CityName, i_CityCapital, i_CityPopulation);
END;

1 个答案:

答案 0 :(得分:2)

您可以使用SELECT .. INTO语句编写一个函数,以根据州名称获取州代码。 INTO子句允许您指定存储select语句的返回值的变量。

FUNCTION getStateCode
  (i_StateName IN TBLSTATE2.NAME%TYPE) 
RETURN tblState2.CODE%TYPE IS
  V_CODE tblState2.CODE%TYPE;
BEGIN
    SELECT CODE
    INTO   V_CODE
    FROM   tblState2
    WHERE  NAME = i_StateName;

    RETURN V_CODE;
END;

请注意,查询必须只返回一行。如果它返回0或超过1行,它将失败,找不到数据或行太多。

可以通过在SELECT FROM DUAL查询中嵌入查询来捕获No Data Found错误:

FUNCTION getStateCode
  (i_StateName IN TBLSTATE2.NAME%TYPE) 
RETURN tblState2.CODE%TYPE IS
  V_CODE tblState2.CODE%TYPE;
BEGIN
    SELECT (SELECT CODE
            FROM   tblState2
            WHERE  NAME = i_StateName)
    INTO   V_CODE
    FROM   DUAL

    RETURN V_CODE;
END;

该函数返回代码,然后可以在过程中的insert语句中使用该代码:

PROCEDURE insertCity
  (i_StateName      IN TBLSTATE2.NAME%TYPE,
   i_CityName       IN TBLCITY2.NAME%TYPE,
   i_CityCapital    IN TBLCITY2.CAPITAL%TYPE,
   i_CityPopulation IN TBLCITY2.POPULATION%TYPE) IS

BEGIN

    INSERT INTO TBLCITY2 (NAME, CAPITAL, POPULATION, STATE_CODE)
    VALUES(
      i_CityName,
      i_CityCapital,
      i_CityPopulation,
      getStateCode(i_StateName)
    );

END;

然后,您可以像以下一样调用该过程:

BEGIN
  insertCity(i_StateName, i_CityName, i_CityCapital, i_CityPopulation);
END;

就像@APC在评论中提到的那样,修改函数内部的数据是不好的做法。原因是,函数也可以从查询中调用,这意味着当您只想查询数据时可能会意外地修改数据。

因此,在上面的设置中,有一个只查询数据的函数。该函数可以在SQL中使用,或者(在这种情况下)在过程中使用。该过程可以安全地修改数据,因为它无论如何都不能用于选择查询。