-
Здравствуйте. Есть запрос:
SELECT * FROM BazaDannih.DB ORDER BY Pole
Как мне вставить вместо Pole переменную?
Чтоб как нибудь так получилось...
var
Perem : string;
begin
Perem :='Name' ;
SELECT * FROM BazaDannih.DB ORDER BY Perem
-
'SELECT * FROM BazaDannih.DB ORDER BY ' + Perem
-
в общем случае см. 1
в ADO есть Parameters
в DOA есть Variables
в чем то еще что-то еще
-
В TQuery пишешь свой запрос 'SELECT * FROM BazaDannih.DB ORDER BY :Pole'
Потом гоняй как хочешь через присваивание нужного значения параметру :Pole
-
> [3] Труп Васи Доброго © (22.09.08 11:37)
Сам то пробовал так?
-
> Труп Васи Доброго © (22.09.08 11:37) [3]
Не болтайте ерундой (с)
-
> в общем случае см. 1
> в ADO есть Parameters
> в DOA есть Variables
> в чем то еще что-то еще
параметры и переменные в данном случае никаким боком не прокатывают. Разве что макросы, которые мало кто есть (DOA, ODAC).
Так что выход - только динамически формировать текст запроса. Впрочем, использование макросов фактически дает такой же эффект - изменяется текст запроса.
-
JEDI/RxLib использует макросы для такой ситуации
-
> Сам то пробовал так?
Бейте меня ногами - не врубился в вопрос! (пьяный что-ли был)
А по теме: В RXLib есть компонент запроса, вот там в параметрах можно и таблицу другую подставить и поле любое.
-
> [8] Труп Васи Доброго © (23.09.08 09:43)
> вот там в параметрах
Там, если мне память не изменяет, это называется макросами. Они существуют паралельно с нормальными параметрами и являются по сути оберткой к переписыванию текста запроса.
-
> Там, если мне память не изменяет, это называется макросами.
>
Ну да, я про них и имел в виду.
Тогда в TRxQuery запрос будет такой: 'SELECT * FROM BazaDannih.DB ORDER BY %Pole'
-
и тем не менее, почему a всегда меньше b
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
a,b:longint;
step:integer;
begin
step:=30;
a:=GetTickCount;
for I := 0 to step do
begin
OracleDataSet1.Active:=false;
OracleDataSet1.SetVariable('OWNER','SYS');
OracleDataSet1.Active:=true;
OracleDataSet1.Active:=false;
OracleDataSet1.SetVariable('OWNER','SYSTEM');
OracleDataSet1.Active:=true;
OracleDataSet1.Active:=false;
OracleDataSet1.SetVariable('OWNER','SDD');
OracleDataSet1.Active:=true;
OracleDataSet1.Active:=false;
OracleDataSet1.SetVariable('OWNER','WH1');
OracleDataSet1.Active:=true;
end;
a:=GetTickCount-a;
b:=GetTickCount;
for I := 0 to step do
begin
OracleDataSet2.Active:=false;
OracleDataSet2.SQL.Text:='Select * from all_all_tables where OWNER ='+ quotedstr('SYS');
OracleDataSet2.Active:=true;
OracleDataSet2.Active:=false;
OracleDataSet2.SQL.Text:='Select * from all_all_tables where OWNER = '+ quotedstr('SYSTEM');
OracleDataSet2.Active:=true;
OracleDataSet2.Active:=false;
OracleDataSet2.SQL.Text:='Select * from all_all_tables where OWNER = '+ quotedstr('SDD');
OracleDataSet2.Active:=true;
OracleDataSet2.Active:=false;
OracleDataSet2.SQL.Text:='Select * from all_all_tables where OWNER = '+ quotedstr('WH1');
OracleDataSet2.Active:=true;
end;
b:=GetTickCount-b;
ShowMessageFmt('%d %d',[a,b]);
end;
-
> Vlad Oshin © (23.09.08 10:26) [11]
Хех. Как раз у тебя пример параметризации литералов. Для чего она, собственно и задумана. И ты действительно экономишь (правда, не так уж и много, т.е. заметно если таки запросы выполняются довольно часто) на времени разбора запроса.
Ты имя таблицы попробуй подставить.
Ну и плюс - учти, что оракл - штука хитрая и любит все кэшировать. Так что произвести сравнительный тест на скорость в равных условиях не так уж и просто.
-
> и тем не менее, почему a всегда меньше b
Да, кстати, а тут будет не всегда меньше б. Запусти еще раз - и они будут одинаковые, т.к. непараметризованные запросы тоже легли в процедурный кэш.
-
Кстати, в тексте SQLзапроса SELECT можно не только имя поля указывать в ORDER BY, но и номер вместо этого (ORDER BY 3 - упорядочить по третьей колонке возвращаемого набора).
Иногда это удобно.
А в качестве параметра в общем случае в ORDER BY нельзя ничего пихать, так как запрос подготавливается (сервер выбирает план, какие индексы юзать) в зависимости от того, что в ORDER BY указано.
То есть параметризованный запрос сначала 1 раз подготавливается на сервере методом PREPARE, а уже затем может много раз вызваться метод EXECUTE с теми или иными параметрами.
А так как подготовка (оптимизация) очень сильно зависит от ORDER BY, поэтому параметры в этом месте передать нельзя. Разве что какой-нибудь навороченный компонент xxQuery как-нибудь сэмулирует якобы "параметр", реально просто заменив текст запроса. На сервер это в качестве законного параметра попасть не может в принципе. Если такой сервер и существует, то я о нем не знаю.
-
ему как раз для препара нужен валидный текст запроса.
а '...ордер бай ?' для него непонятно.
-
> Поросенок Винни-Пух (24.09.2008 9:25:15) [15]
Проще - метаданные с параметрами не живут.
-
> kaif © (24.09.08 01:33) [14]
Абсолютно прав с выводами и совершенно не прав в рассуждении о причинах :)