我正在尝试在Oracle中编写一个存储过程(我已经讨厌了(除此之外)) 当执行存储过程时,我告诉我已经检索了太多行(例如,多于1行),但是当通过文本查询数据时,它清楚地告诉我只有一行符合此标准。
create or replace PROCEDURE GETADDRESSCOORDS ( HOUSE IN VARCHAR2 , STREET IN VARCHAR2 , X OUT NUMBER , Y OUT NUMBER ) AS BEGIN SELECT X_COORD, Y_COORD INTO X,Y FROM MASTER_ADDRESS WHERE HOUSE=HOUSE AND STR_NAME=STREET AND PRE_DIR IS NULL; END GETADDRESSCOORDS;
运行时,我收到此错误消息:
SQL> execute getaddresscoords('1550', 'BEDFORD', :X, :Y) BEGIN getaddresscoords('1550', 'BEDFORD', :X, :Y); END; * ERROR at line 1: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at "TAXLOTS.GETADDRESSCOORDS", line 9 ORA-06512: at line 1
所以我的行太多了......但是当我执行这个时:
SQL> SELECT MAX(rownum) from MASTER_ADDRESS where HOUSE='1550' AND STR_NAME='BEDFORD' AND PRE_DIR IS NULL; MAX(ROWNUM) ----------- 1
我在这里错过了什么?
答案 0 :(得分:6)
您的问题与变量范围有关。在SELECT
语句中,HOUSE
将始终引用表中的列,而不是同名参数。
通常,在编写PL / SQL时,您使用某种命名约定来区分参数和局部变量与表中的列,以使其更加明显。在你的情况下,你可能想要像
这样的东西create or replace
PROCEDURE GETADDRESSCOORDS
(
P_HOUSE IN VARCHAR2
, P_STREET IN VARCHAR2
, P_X OUT NUMBER
, P_Y OUT NUMBER
) AS
BEGIN
SELECT X_COORD, Y_COORD
INTO P_X,P_Y
FROM MASTER_ADDRESS
WHERE HOUSE=P_HOUSE
AND STR_NAME=P_STREET
AND PRE_DIR IS NULL;
END GETADDRESSCOORDS;
如果要声明局部变量,则类似地使用某种命名约定来区分它们与表中的列(即l_local_variable)。
您可以显式指定与列名匹配的变量的范围分辨率,但这往往会变得更加丑陋(并且您必须非常小心,不要错过列名和变量的任何情况)名称匹配和范围解析未明确指定)。写
是合法的create or replace
PROCEDURE GETADDRESSCOORDS
(
HOUSE IN VARCHAR2
, STREET IN VARCHAR2
, X OUT NUMBER
, Y OUT NUMBER
) AS
BEGIN
SELECT X_COORD, Y_COORD
INTO X,Y
FROM MASTER_ADDRESS ma
WHERE ma.HOUSE=getAddressCoords.HOUSE
AND ma.STR_NAME=getAddressCoords.STREET
AND ma.PRE_DIR IS NULL;
END GETADDRESSCOORDS;
但这不是很传统。