динамическая передача имени таблицы и столбца с использованием переменных связывания

Есть ли способ динамически передавать имена столбцов и таблиц в запрос с использованием переменных связывания? Это можно сделать с помощью простого оператора конкатенации ||, но я бы хотел другой подход, с помощью которого это можно было бы достичь.

ИЗМЕНИТЬ

OPEN abc_cur FOR 'Select :column_name
                  from :table_name' 
                USING column_name,table_name;

В этом примере я передаю column_name как empno,ename и table_name как emp

Но у меня такой подход не работает. Возможно ли использовать другой подход, отличный от традиционного подхода конкатенации?


person Gaurav Soni    schedule 15.03.2012    source источник
comment
@ Адриан: Вы понимаете, что я имел в виду, задавая вопрос?   -  person Gaurav Soni    schedule 15.03.2012
comment
Честно говоря, нет. Я думаю, вам следует уточнить.   -  person Adriano Carneiro    schedule 15.03.2012


Ответы (3)


Имена таблиц и столбцов не могут быть переданы как переменные связывания, нет. Весь смысл переменных связывания в том, что Oracle может один раз сгенерировать план запроса для оператора, а затем выполнить его много раз с разными значениями переменных связывания. Если оптимизатор не знает, к какой таблице осуществляется доступ или какие столбцы выбираются и фильтруются, он не может создать план запроса.

Если ваша проблема связана с атаками с использованием SQL-инъекций и если предположить, что динамический SQL действительно необходим (в большинстве случаев необходимость прибегать к динамическому SQL подразумевает проблемы с моделью данных), вы можете использовать _ 1_ package, чтобы убедиться, что имена таблиц и столбцов не содержат встроенный SQL.

person Justin Cave    schedule 15.03.2012
comment
Меня беспокоит динамическое создание sql-запроса, а затем его выполнение. Есть ли для этого альтернатива? - person Gaurav Soni; 15.03.2012
comment
@ Gaurav Soni- Что вас беспокоит? - person Justin Cave; 15.03.2012
comment
Я могу создать свой динамический sql с конкатенацией строки, такой как v_sql:=select '||column_name||' from dual where 1=1, а затем еще одну строку, подобную этой, как мы можем создать это более эффективно, я имею в виду, что другой подход, кроме этого - person Gaurav Soni; 15.03.2012
comment
: Есть ли какой-нибудь более оптимизированный и эффективный подход, кроме этого? - person Gaurav Soni; 15.03.2012
comment
@Gaurav Soni- Вас беспокоит, что конкатенация строк идет медленно? Что вы делаете излишний жесткий синтаксический анализ? Что вы открываете дыры в безопасности для атак с использованием SQL-инъекций? Или что-то другое? В большинстве хорошо спроектированных систем нет необходимости прибегать к динамическому SQL, поэтому я всегда подозреваю, что динамический SQL используется для прикрытия плохого дизайна. Однако, если вам действительно нужно, чтобы запросы были динамическими, вам необходимо динамически собрать строку. - person Justin Cave; 15.03.2012
comment
Спасибо за ответ, я думаю, что вы лучший объяснитель и наставник в этой области. - person Gaurav Soni; 15.03.2012

Нет, ты не можешь. Изменение имени таблицы или столбца в запросе изменяет семантику этого запроса, т. Е. Становится другим запросом.

Все переменные привязки предназначены для передачи разных значений в один и тот же запрос. Оптимизатор может повторно использовать запрос с другими значениями без его повторного анализа и оптимизации.

person Tony Andrews    schedule 15.03.2012

У меня была аналогичная проблема, когда мне пришлось изменить таблицу в моем запросе в зависимости от значения элемента <select>. В большинстве ответов здесь говорилось, что имена таблиц не могут быть переданы в качестве переменных связывания, но когда я создал переменную, содержащую имя таблицы и переданную в мой запрос sql, она действительно сработала:

<?php

$conn = mysqli_connect("<host>", "<username>", "<password>", "<database>");

$variable = "table_name";
$sql = $conn->("SELECT <column_name> FROM $variable ....);

?>

Итак, что я сделал, так это то, что я создал функцию и написал все свои sql-запросы внутри моей функции. А в качестве параметра функции я передал переменную с именем $ table:

function getResult($table){
    
$conn = mysqli_connect("<host>", "<username>", "<password>", "<database>");
    $minDate = $conn->real_escape_string($_POST['minDate']);
    $maxDate = $conn->real_escape_string($_POST['maxDate']);
    $jobName = $conn->real_escape_string($_POST['jobName']);



$sql = $conn->query("SELECT COUNT(countX) as boxCount FROM $table WHERE job_name='$jobName' AND dateX BETWEEN '$minDate' AND '$maxDate'");


/* ... I removed the other operations from the code to make it compact */

А затем я написал условие, которое меняет целевую таблицу в зависимости от значения имени задания:

if ($_POST['jobName'] === "job1"){
    getResult("table_name");
}
else if($_POST['jobName'] === "job2") {
    getResult("table_name");
}
person burkhoniddin    schedule 15.05.2021