Как использовать переменную в оракуле script для имени таблицы

У меня есть pl\sql script, где я хочу установить имя таблицы, используемое в script, переменной. Итак, из некоторых примеров, которые я нашел в Интернете, я написал код ниже. Первый раздел работает, поэтому я считаю, что мой общий синтаксис верен, но второй раздел, где я пытаюсь использовать переменную для имени таблицы, это ошибки ( "Ошибка SQL: ORA-00903: недопустимое имя таблицы" ).

Кто-нибудь знает, что я делаю неправильно... Я не делаю много PL\SQL, поэтому, возможно, я просто пропущу что-то очевидное.

--works
variable numOfrecords number;
exec :numOfrecords := 10;
select * from customers2008 where rownum < :numOfrecords;

--does not work
 variable tableNm CHAR;
 exec :tableNm := 'customers2008';
 print tableNm;
 select * from :tableNm;

Ответы

Ответ 1

Если вы используете этот script из sqlplus (это выглядит так), вы хотите использовать команду DEFINE, которая позволяет создавать переменные подстановки sqlplus, которые являются просто прямой заменой строк, например:

define tableNm = 'customers2008'
select * from &tableNm;

См. Использование Sql * Plus для получения дополнительной информации о том, как они используются. Вы можете передать значения в script из командной строки с использованием предопределенных переменных подстановки позиционирования, например:

define tableNm = &1
select * from &tableNm;

... и затем вызовите sqlplus так:

sqlplus user/[email protected] @myscript.sql customers2008

Если вы не передадите значение в командной строке, приглашение script будет запрашиваться для значения.

См. ниже приведенный ниже вариант Дэйва Коста для различий между переменными связи и замены.

Ответ 2

Чтобы добавить какое-то объяснение:

Метод, который вы пытались использовать, называется переменной привязки. Переменная связывания идентифицируется в Oracle SQL двоеточием, за которым следует идентификатор. Цель переменной привязки состоит в том, что ее значение не нужно знать при анализе SQL-запроса; оператор можно разобрать один раз, а затем выполнить несколько раз с разными значениями, привязанными к переменной.

Для анализа синтаксиса SQL необходимо знать имена таблиц и столбцов. Таким образом, имя таблицы не может быть представлено переменной привязки, потому что значение не будет известно во время разбора.

Если вы просто выполняете SQL и встроенный PL/SQl через SQLPlus, то переменные замещения - это простой способ справиться с этой проблемой, как объяснил Стив. Переменная замещения заменяется ее значением, когда клиент SQLPlus считывает команду, прежде чем он даже отправит ее в Oracle для разбора.

Ответ 3

Вам нужно сделать что-то вроде этого:

EXECUTE IMMEDIATE 'select * from' || tableNm;

Это связано с тем, что Oracle не разрешает связывать переменные для таблицы (или любых других имен объектов).

Существуют существенные последствия для безопасности с помощью подхода EXECUTE IMMEDIATE: когда значение tableNm предоставляется пользователю, вы широко открыты для атаки SQL injection.