PL / SQL: переписать оператор SELECT с использованием параметра IN в хранимой процедуре - PullRequest
2 голосов
/ 01 апреля 2012

Предположим, у меня есть база данных Oracle 11.2, содержащая следующую таблицу:

TABLE: SURVEY

PARAMETER    MALE   FEMALE 
--------------------------
SAMPLE_SIZE  102       95
AVG_WEIGHT   170      120
AVG_HEIGHT   5.9      5.4

Вот пример минимальной хранимой процедуры PL / SQL, которая выбирает средний вес мужчин и помещает его (например, 170) в переменную v_stat.

PROCEDURE get_stat (gender IN VARCHAR2) 
AS
    v_stat number;
BEGIN
    SELECT male INTO v_stat FROM survey WHERE parameter = 'avg_weight';
END get_stat;

Обратите внимание, что параметр IN gender здесь ничего не делает.Я хочу передать переменную gender, которая может равняться либо «мужчине», либо «женщине», и каким-то образом использовать gender в операторе SELECT (вместо «мужского»).Цель состоит в том, чтобы передать gender в качестве переменной, которая может использоваться, например, для получения среднего веса, как мужского, так и женского пола, как определено gender.

Я знаю, что, вероятно, могу использовать оператор IF / THEN / ELSE с двумя отдельными инструкциями SELECT, но мне было интересно, существует ли элегантный способ использовать только один оператор SELECT, изменив «мужской» в приведенном выше операторе SELECTк чему-то еще?

Обратите внимание, что это повторение моего предыдущего вопроса здесь

Как программно установить имя таблицы в PL / SQL?

это было (справедливо) подвергнуто критике за то, что оно не было реалистичным вопросом.

Ответы [ 3 ]

5 голосов
/ 01 апреля 2012

Вам нужно будет использовать тот же подход динамического SQL, который был предложен в вашем другом вопросе

PROCEDURE get_stat (gender IN VARCHAR2) 
AS
    v_sql   varchar2(1000);
    v_param varchar2(100) := 'AVG_WEIGHT';
    v_stat  number;
BEGIN
    v_sql := 'SELECT ' || gender || ' FROM survey WHERE parameter = :1';
    EXECUTE IMMEDIATE v_sql
                 INTO v_stat
                USING v_param;
END get_stat;

Но у вас будут те же общие возражения, которые были высказаны в вашем предыдущем вопросе - модель данных в корне ошибочна. Вам было бы намного лучше иметь отдельную строку для результатов опросов MALE и FEMALE, а не отдельные столбцы для результатов male и female.

1 голос
/ 01 апреля 2012

Мне нужно посмотреть, как преобразовать ваш пример, но я знаю, что в SQL Server вы можете выполнять динамический SQL.И, кажется, что вы можете сделать это и в Oracle .

Это будет примерно так (я приведу только примеров здесь , поскольку Oracle не мой обычный язык)

avg_weight_str := avg_weight;
stmt_str := 'SELECT :gender INTO v_stat FROM survey WHERE parameter = :avg_weight_str';
EXECUTE IMMEDIATE stmt_str;

Проблема с динамическим SQL заключается в том, чтоэто не так эффективно.Хотя это и не элегантно, но если у вас есть только два пути if, то я бы остановился на блоке if, чтобы код мог быть более производительным.

1 голос
/ 01 апреля 2012

Вам нужно составить инструкцию SELECT в виде строки, а затем использовать EXECUTE IMMEDIATELY .

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