CREATE OR REPLACE FUNCTION getFlightSeats (v_seatRange IN VARCHAR2)
RETURN VARCHAR2
IS
seat_number_template seat_num_collection;
seat_numbers seat_num_collection;
result_query VARCHAR2(200);
condition VARCHAR2(200);
--create or replace type seat_num_collection AS table of VARCHAR2(60);
BEGIN
IF v_seatRange LIKE '%-%' THEN
SELECT comma_split
BULK COLLECT INTO seat_number_template
FROM (
SELECT regexp_substr(v_seatRange, '[^,]+', 1, level) as comma_split
FROM dual
connect by regexp_substr(v_seatRange, '[^,]+', 1, level) is not null
);
FOR i IN 1..seat_number_template.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('seat_number_template inside loop::::: ' || seat_number_template(i));
SELECT hiphen_split
BULK COLLECT INTO seat_numbers
FROM (
SELECT regexp_substr(seat_number_template(i), '[^-]+', 1, level) as hiphen_split
FROM dual
CONNECT BY regexp_substr(seat_number_template(i), '[^-]+', 1, level) is not null
);
IF (i = 1) THEN
condition := condition || '(seat_number BETWEEN ' || '''' || seat_numbers(1)|| '''' || ' AND ' || '''' || seat_numbers(2)|| '''' || ')';
DBMS_OUTPUT.PUT_LINE('Condition::::: ' || condition);
--FOR j IN 1..seat_numbers.COUNT LOOP
--DBMS_OUTPUT.PUT_LINE('seat_numbers inside loop::::: '||seat_numbers(j));
--END LOOP;
ELSE
condition := condition || ' OR (seat_number BETWEEN ' || '''' || seat_numbers(1)|| '''' || ' AND ' || '''' || seat_numbers(2)|| '''' || ')';
DBMS_OUTPUT.PUT_LINE('Condition::::: ' || condition);
END IF;
END LOOP;
condition := '(' || condition || ')';
END IF;
--condition to check only comma and without hiphen
IF REGEXP_LIKE(v_seatRange, '[[:alnum:]]') AND v_seatRange NOT LIKE '%-%' THEN
condition := replace('''' || v_seatRange, ',', ''',''') || '''';
DBMS_OUTPUT.PUT_LINE('Condition::::: ' || condition);
condition := 'seat_number IN ' || '(' || condition || ')';
END IF;
result_query := condition;
DBMS_OUTPUT.PUT_LINE('final result_query::::: ' || result_query);
return result_query;
END;
字符串
如果用户调用函数为
select getFlightSeats('3A,5A,7C')` from dual;
型
函数结果:seat_number IN('3A','5A ','7C')
如果用户调用函数为
select getFlightSeats('3A-5B,6A-9B') from dual;
型
函数结果:((seat_number BETWEEN '3A' AND '5B')OR(seat_number BETWEEN '6A' AND '9B'))
我面临的问题是如何在 where 子句中调用这个函数,如下所示:
SELECT seat_number
FROM SEAT_TABLE
WHERE getFlightSeats('3A,5B,6B')
型
它不工作,因为它的预期条件。我如何在选择查询中实现这一点?
我得到了解决方案(来自this answer):
您更愿意选择返回一个集合并将其与表函数一起使用,无论是作为连接还是在子查询中。
但是在这里我无法将字符串追加到集合中。
2条答案
按热度按时间3gtaxfhh1#
为了好玩,在SQL中尝试:
字符串
iyr7buue2#
不要尝试生成动态SQL。使用
PIPELINED
函数并生成范围之间的行(假设您知道每行中有多少个座位,您可能完全可以在PL/SQL中完成,因此可以避免任何上下文切换):字符串
然后,对于样本数据:
型
可以使用以下命令调用该函数:
型
其输出:
| 座位号|
| --|
| 3A|
| 5B|
| 6B|
| 6C|
| 6D|
| 9C|
| 9D|
| 10A|
| 10B|
| 10C|
| 10D|
| 11A|
| 11B|
fiddle