#oracle #dynamic #plsql
#Oracle #динамический #plsql
Вопрос:
Ниже приведена функция, которую мне нужно выполнить.
create or replace function GET_FROM_ANY_STD2(TheValue in varchar2, TheTableName in varchar2, TheContext in varchar2)
return varchar2
is GET_FROM_ANY_STD2 varchar2(10000);
begin
select listagg(value0, '@') within group (order by rn) into GET_FROM_ANY_STD2
from (
execute immediate
'select levels.column_value rn,
trim (regexp_substr(TheValue, '[^@] ', 1, levels.column_value)) as did
from dual t, table(cast(multiset(select level
from dual connect by level <= length(regexp_replace(**TheValue**, '[^@] ')) 1)
as sys.odcinumberlist)) levels) t
left join **TheTableName** d on d.code0 = t.did and d.context =**TheContext**;
return(GET_FROM_ANY_STD2);'
end;
но когда я пытаюсь выполнить это, я получаю несколько ошибок.
все значения между двойными звездочками должны быть параметром.
Я пробовал несколько вещей, но ни одна из них не увенчалась успехом: (
Я приветствую любую помощь.
С наилучшими пожеланиями,
Мурат
Комментарии:
1. Нет
return
инструкции. Что он должен делать?
Ответ №1:
Я не уверен, что должен делать этот фрагмент кода, поскольку возвращает то, на что вы никогда не ссылались в своем коде: listagg(value0 ...)
— что такое value0
?
В любом случае, просто чтобы показать, как это должно быть сделано, держи.
Примерная таблица:
SQL> CREATE TABLE thetablename
2 AS
3 SELECT '0' code0, 'context' AS context FROM DUAL;
Table created.
Функция: при использовании динамического SQL вам необходимо объединить параметры с остальной частью кода. Это некрасиво, сложно для отладки, сложно для чтения, сложно для записи (проблемы с одинарными кавычками), вы должны знать о возможной SQL-инъекции (читайте о dbms_assert
).
Я попытался сделать это как можно более простым, составив инструкцию SQL в отдельной переменной ( l_str
), а затем просто выполнить ее результат в retval
.
SQL> CREATE OR REPLACE FUNCTION get_from_any_std2 (TheValue IN VARCHAR2,
2 TheTableName IN VARCHAR2,
3 TheContext IN VARCHAR2)
4 RETURN VARCHAR2
5 IS
6 l_str VARCHAR2 (10000);
7 retval VARCHAR2 (10000);
8 BEGIN
9 l_str :=
10 'WITH
11 trows
12 AS
13 (SELECT t.COLUMN_VALUE rn,
14 TRIM (REGEXP_SUBSTR ( '
15 || CHR (39)
16 || TheValue
17 || CHR (39)
18 || ',
19 ''[^@] '',
20 1,
21 t.COLUMN_VALUE)) AS did
22 FROM DUAL t
23 CROSS JOIN
24 TABLE (
25 CAST (
26 MULTISET (
27 SELECT LEVEL
28 FROM DUAL
29 CONNECT BY LEVEL <=
30 LENGTH (
31 REGEXP_REPLACE ( '
32 || CHR (39)
33 || thevalue
34 || CHR (39)
35 || ',
36 ''[^@] ''))
37 1)
38 AS SYS.odcinumberlist)) t)
39 SELECT LISTAGG (t.did, ''@'') WITHIN GROUP (ORDER BY t.rn)
40 FROM trows t
41 LEFT JOIN '
42 || TheTableName
43 || ' d
44 ON d.code0 = t.did
45 AND d.context = '
46 || CHR (39)
47 || TheContext
48 || CHR (39);
49
50 EXECUTE IMMEDIATE l_str
51 INTO retval;
52
53 RETURN retval;
54 END;
55 /
Function created.
Тестирование:
SQL> SET VERIFY OFF
SQL>
SQL> SELECT get_from_any_std2 ( 'amp;thevalue', 'amp;thetablename', 'amp;thecontext') result
2 FROM DUAL;
Enter value for thevalue: 0@abc@def
Enter value for thetablename: thetablename
Enter value for thecontext: context
RESULT
--------------------------------------------------------------------------------
0@abc@def
SQL>
Итак, да — он что-то делает и что-то возвращает. Я понятия не имею, действительно ли это то, чего вы хотели, но — теперь, когда вы знаете, как это сделать, сделайте это.
Комментарии:
1. К сожалению, это не правильно. У меня есть таблица с именем std и некоторые другие таблицы поиска с такой же структурой.
2. Структура следующая: создайте таблицу STD (контекст VARCHAR2(30), code0 VARCHAR2(3), value0 VARCHAR2(254), value1 VARCHAR2(254), value2 VARCHAR2(254), value3 VARCHAR2(254), value4 VARCHAR2(254), флаги INTEGER, upid VARCHAR2(21), НОМЕР upd_cnt(3) по умолчанию 0 не равен нулю, идентификационный НОМЕР (10) не равен нулю, last_modified ДАТА, last_modified_user VARCHAR2(30), create_date ДАТА, create_user VARCHAR2(30) )
3. допустим, данные для таблицы STD следующие: context, code0, value0 «a», «x», «x1» «a», «y», «y1» «b», «z», «z2» «a», «z», «z1»
4. основная цель — получить строку «x1 @z1», когда входные данные являются; Значение = ‘a @z’, имя_таблицы = ‘STD’, текст = ‘a’.
5. Основной sqp достигает цели без параметризованного имени таблицы. Это то, что мне нужно выполнить…