Oracle PL/SQL中用于在表中插入新记录的存储过程
我需要创建一个PL/SQL存储过程来向tblCity2表中添加一条记录。tblCity2样品:Oracle PL/SQL中用于在表中插入新记录的存储过程,oracle,plsql,Oracle,Plsql,我需要创建一个PL/SQL存储过程来向tblCity2表中添加一条记录。tblCity2样品: +-------------+--------+-------------+------------+ | NAME | CAPITAL| POPULATION | STATE_CODE | +-------------+--------+-------------+------------+ | Monterrey | Y | 2015000 | MX
+-------------+--------+-------------+------------+
| 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;
您可以使用
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行,它将失败,找不到数据或行太多
通过将查询嵌入从双查询中选择,可以捕获未找到数据错误:
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中使用,也可以(在本例中)在过程中使用。该过程可以安全地修改数据,因为它无论如何都不能用于select查询。OP需要一个函数来检索查找
状态\u code
,而不是在insert语句中使用标量游标。正如您所知,使用函数更改系统状态被认为是不好的做法(没有双关语)。使用过程的原始实现更好。@APC我同意您关于函数更改状态的看法,我想我只是误解了这个问题。我删除了所有以前的内容并编写了一个新的内容,其中一个函数返回状态名,然后该函数将在过程中使用,而不是在subselect中使用。