Хранимая процедура ORACLE, возвращающая слишком много строк - PullRequest
2 голосов
/ 15 ноября 2011

Я пытаюсь написать хранимую процедуру в 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

что мне здесь не хватает?

1 Ответ

6 голосов
/ 15 ноября 2011

Ваша проблема связана с переменной областью видимости. В вашем выражении 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;

но это было бы не очень условно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...