#sql #database #oracle #plsql
Вопрос:
Я немного переживаю по этому поводу, может быть, кто-то видит что-то, чего не вижу я…
select 'BEGIN dbms_stats.gather_table_stats('''SCHEMA'', ''TABLENAME_'' || to_char(trunc(sysdate, 'MM'), 'YYYY-MM')', cascade => true, no_invalidate => false); END;' from dual;
Таким образом, результат должен быть:
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_2021_07'), cascade => true, no_invalidate => false); END;
Почему-то я не нахожу способа избежать струн, что я делаю не так?
Заранее спасибо
Комментарии:
1. Вместо того, чтобы иметь динамические имена таблиц для каждого месяца, вы можете рассмотреть возможность разделения
2. Должна ли она быть динамичной? Похоже, что вы можете построить имя таблицы как
TABLENAME_2021_07
, а затем просто передать его в dbms_stats.gather_table_stats как обычно.
Ответ №1:
Здесь используется обратный подход, начинающийся с результата и ведущий к выражению результата
- Начните с строки результата
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_2021_07'), cascade => true, no_invalidate => false); END;
- Разделите его на статическую и динамическую части
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_ 2021_07 <--- dynamic '), cascade => true, no_invalidate => false); END;
- заключите статические части в q-кавычки (чтобы вам не нужно было убегать!), замените динамическую часть выражением и совместите все части с
||
Добавьте в запрос select:
select
q'[BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_]' ||
to_char(trunc(sysdate, 'MM'), 'YYYY-MM') ||
q'['), cascade => true, no_invalidate => false); END;]'
from dual;
Ответ №2:
Если я правильно понимаю:
select 'BEGIN dbms_stats.gather_table_stats(''SCHEMA'', ''TABLENAME_' ||
to_char(trunc(sysdate, 'MM'), 'YYYY-MM') ||
''', cascade => true, no_invalidate => false); END;'
from dual;
Комментарии:
1. Привет, спасибо за ваш ответ, единственная проблема здесь-это «после ИМЕНИ ТАБЛИЦЫ» с этим запросом, который я получаю: «ИМЯ ТАБЛИЦЫ». Есть идеи?
2. @MladenNikolic . . . Я передвинул заключительную цитату.
Ответ №3:
Используйте механизм q-кавычек, это упрощает задачу (вам не нужно избегать одинарных кавычек).:
SELECT q'[BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_' || to_char(trunc(sysdate, 'MM'), 'YYYY_MM'), cascade => true, no_invalidate => false); END;]' result
FROM DUAL;
что приводит к
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_' || to_char(trunc(sysdate, 'MM'), 'YYYY_MM'), cascade => true, no_invalidate => false); END;
Ваше заявление длинное, поэтому его трудно увидеть, поэтому — вот упрощенный пример, который показывает, как это сделать:
SQL> select 'stats(''schema'')' old_result,
2 q'[stats('schema')]' new_result
3 from dual;
OLD_RESULT NEW_RESULT
--------------- ---------------
stats('schema') stats('schema')
SQL>
q
- далее следует одна цитата
- за ним следует скобка (используйте ту, которая не является частью строки!)
- теперь напишите свое заявление так, как вы бы сделали, если бы оно не было заключено в одинарные кавычки
- завершите его закрывающей скобой …
- … и завершающая одинарная цитата
Комментарии:
1. Привет, спасибо за ваш ответ, могу ли я использовать несколько механизмов цитирования вопросов в одном операторе select? поскольку функции trunc() необходимо вычислить фактическую дату в строке, она этого не делает, поэтому я полагаю, что мне нужно разделить ее от строки, верно?
2. В коде, который вы опубликовали (и который я использовал повторно), есть 2 опечатки:
'YYYY-MM')'
: в имени таблицы не может быть тире (вероятно, следует подчеркнуть), и последняя одинарная кавычка должна быть удалена. Что касается вашего вопроса: вам не нужно использовать механизм несколько раз (но вы можете). Хотя, если вы исправите то, что я только что написал (и исправили в ответе), это может сработать нормально.3. Задача здесь состоит в том, чтобы не «избежать»
||
конкатенаций в q-строке. Что, конечно, работает, но дает другой результат. Я знаю это по собственному тяжелому опыту;)
Ответ №4:
Ты хочешь:
select 'BEGIN dbms_stats.gather_table_stats(''SCHEMA'', ''TABLENAME_'
|| to_char(sysdate, 'YYYY_MM')
|| ''', cascade => true, no_invalidate => false); END;'
from dual;
Я нахожу, что это помогает отформатировать его так, чтобы статические и динамические части находились в разных строках, тогда вы можете записать статические строки, а затем удвоить все кавычки, чтобы избежать их, и поместить начальную и конечную кавычки для начала и конца строкового литерала.
или, если вам нужен строковый литерал в кавычках q:
select q'[BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_]'
|| to_char(sysdate, 'YYYY_MM')
|| q'[', cascade => true, no_invalidate => false); END;]'
from dual;
Просто напишите свою статическую строку и добавьте q'[
в начало и ]'
в конец.