Мой код ниже не является отличным способом решения этой проблемы. Прежде чем использовать этот код, продолжайте искать более официальное решение.
Похоже, что у OCI есть функция для динамического извлечения имен связывания через функцию OCIStmtGetBindInfo . Однако, похоже, что эта функция недоступна в default PHP functions . Возможно, есть другие, более продвинутые способы подключения PHP к Oracle, которые обеспечивают необходимую функцию, но я не знаю достаточно об OCI или PHP, чтобы найти их.
Если вы готовы к не очень хорошему решению, вы можете использовать мою программу с открытым исходным кодом plsql_lexer , чтобы найти имена переменных связывания. Лексер разбивает операторы SQL на маленькие токены и обрабатывает сложные синтаксические проблемы, такие как комментарии и строки. Результаты должны быть намного более точными, чем использование нескольких регулярных выражений.
Недостатком является то, что программа не является полным анализатором, и вам приходится иметь дело с примитивными токенами. В этом случае относительно легко найти 99,9999% переменных связывания с помощью одного оператора SQL. После установки программы поместите ваш SQL в середину следующего оператора SELECT:
--Find bind variables.
--(Words or numerics that were immediately preceded (excluding whitespace) by a colon.)
select to_char(value) bind_variable_name
from
(
--Get previous token.
select type, value, first_char_position,
lag(to_char(type)) over (order by first_char_position) previous_type
from
(
--Convert to tokens, ignore whitespace.
select type, value, first_char_position
from table(plsql_lexer.lex(
q'[
--Here's the actual SQL statement you care about.
--/*:fake_bind1*/
select 1 a
from dual
where 1 = : real_bind_1 and :real_bind_2 = ':fake_bind_2'
]'))
where type not in ('whitespace')
order by first_char_position
)
)
where type in ('numeric', 'word')
and previous_type = ':'
order by first_char_position;
BIND_VARIABLE_NAME
------------------
real_bind_1
real_bind_2
Могут быть некоторые странные случаи, которые этот код не обрабатывает. Например, переменная связывания может быть идентификатором в кавычках, вам может потребоваться обработать двойные кавычки. И приведенный выше код не обрабатывает показатели . С другой стороны, я буквально никогда не видел ни одной из этих функций, так что это может не иметь значения для вас. Тщательно проверьте.