我需要创建一个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;
答案 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中使用,或者(在这种情况下)在过程中使用。该过程可以安全地修改数据,因为它无论如何都不能用于选择查询。