Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Я запутался совсем, что это такое и с чем это едят. Во всех примерах у Кайта или других авторов просто написано допустим where field=:a, а где это самое а определяется, так и непонятно мне... И еще есть bind variables в динамическом sql, это не совсем же то? Я же могу пользоваться переменными привязки и в статическом sql? Поделитесь, плиз, примерами или ссылочками, а то какая-то каша уже в голове
22 июн 08, 19:04    [5831715]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
C#C++
Member [заблокирован]

Откуда: Суровые северные земли
Сообщений: 2636
А смысл очень простой:
Это применяется при написании программ.
Когда в программе отправляется запрос к серверу, то запрос пишется как ".. where field = :a ...", а сам параметр :а определяется дополнительно к запросу (в библиотеках для работы с СУБД есть такие возможности). Польза: для разных значений запрос считается одним и тем же, и не анализируется перед каждым выполнением, как если значения зашивать прямо в запрос.
22 июн 08, 19:18    [5831728]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Да, про пользу я уже прочитал =) А можно поподробнее про " а сам параметр :а определяется дополнительно к запросу (в библиотеках для работы с СУБД есть такие возможности)" Вот у меня есть хранимка, например, есть входные параметры, я как-то их должен по-другому определять? Или что имеется в виду?
22 июн 08, 19:20    [5831732]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
C#C++
Member [заблокирован]

Откуда: Суровые северные земли
Сообщений: 2636
Краткая иллюстрация в виде примера на C#:
OracleCommand oc = new OracleCommand("select a from tbl where b = :c", conn);
oc.Parameters.Add(":c", OracleType.Number).Value = 55; // "определяю параметр дополнительно к запросу" )
oc.Execute...
22 июн 08, 19:38    [5831757]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
То есть получается, что отличие от обычных переменных ТОЛЬКО В ДВОЕТОЧИИ? *мегашок*

То есть если написать:
OracleCommand oc = new OracleCommand("select a from tbl where b = c", conn);
oc.Parameters.Add("c", OracleType.Number).Value = 55; // "определяю параметр дополнительно к запросу" )
oc.Execute...

то есть без двоеточия, будет происходить разбор, а с ним не будет, и поэтому меняется скорость????
22 июн 08, 19:51    [5831776]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Хм, не получилось так....
procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR);
Попытался вместо llogin написать :llogin,
- ошибка, pls-00049: неверная переменная привязки LLOGIN и еще почему-то PLS-00103
22 июн 08, 20:09    [5831809]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
не получилось
Guest
novichok928
Хм, не получилось так....
procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR);
Попытался вместо llogin написать :llogin,
- ошибка, pls-00049: неверная переменная привязки LLOGIN и еще почему-то PLS-00103


моежт все-таки какую-нибудь книжку почитать для начала
вот например вот эту
Oracle PL/SQL для профессионалов
22 июн 08, 20:14    [5831820]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
C#C++
Member [заблокирован]

Откуда: Суровые северные земли
Сообщений: 2636
novichok928
Хм, не получилось так....
procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR);
Попытался вместо llogin написать :llogin,
- ошибка, pls-00049: неверная переменная привязки LLOGIN и еще почему-то PLS-00103

Когда определяется процедура, пишут без двоеточия, а вот когда вызывается с помощью execute, то можно использовать параметры, т.е. с двоеточием.
Более того, для аргументов типа out использование параметров - единственный способ получить результат.
22 июн 08, 20:18    [5831827]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
А тогда непонятно, в теле процедуры я буду по-прежнему писать условие where field=llogin? Видимо, нет, тогда как? Допустим у меня процедура:

procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR)

IS
BEGIN

OPEN V_CURSOR FOR
;

IO_CURSOR := V_CURSOR;


END Rep1;
end;
22 июн 08, 20:23    [5831839]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Ой, извиняюсь, слуйчано отослал.
Допустим у меня процедура:

procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR)

IS
BEGIN

OPEN V_CURSOR FOR 
select * from Table1 where field=llogin;

IO_CURSOR := V_CURSOR;


END Rep1;
end;

В C# соответственно писал:
orCmd.CommandText = "MyPackage.Rep1";
orCmd.CommandType= CommandType.StoredProcedure;

Тогда как надо было написать, чтобы использовались переменные привязки?
orCmd.Parameters.Add(new OracleParameter("llogin", OracleType.VarChar)).Direction = ParameterDirection.Input;
orCmd.Parameters["llogin"].Value=username;
orCmd.Parameters.Add(new OracleParameter("IO_CURSOR", OracleType.Cursor)).Direction = ParameterDirection.Output;
orReader=orCmd.ExecuteReader();	
22 июн 08, 20:27    [5831855]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Тогда как надо было написать, чтобы использовались переменные привязки?
22 июн 08, 20:28    [5831857]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10042
OracleCommand oc = new OracleCommand("select a from tbl where b = c", conn);
oc.Parameters.Add("c", OracleType.Number).Value = 55; // "определяю параметр дополнительно к запросу" )

Will fail with parameter ":c" can not be found error. oc.Parameters.Add implies statement oc has parameter called c. Parameter in a statement is designated by semi-colon (:) followed by parameter name - another word by a bind variable. And Parameters.Add performs the "binding" - assigns a value of 55 to :c. Now optimizer chooses an execution plan when you issue

OracleCommand oc = new OracleCommand("select a from tbl where b = :c", conn);

when :c value is not known. And what is also important statement is parsed once but can be executed many times each time with a different bind variable value. This way we save time on such costly operation as parsing at risk of getting sub-optimal plan for some bind variable values. Oracle offers bind variable peeking as a mechanism to address sub-optimal plan issue, where plan is adjusted based on bind variable first value (this is done when statement is executed first time), however if bind variable first value happens to be atypical to the rest of the values bind variable peeking will work against you.

SY.
P.S. The above explanation is in some ways "educational", just to give you basic ideas.
22 июн 08, 20:32    [5831865]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
stax..
Guest
novichok928
Ой, извиняюсь, слуйчано отослал.
Допустим у меня процедура:

procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR)

IS
BEGIN

OPEN V_CURSOR FOR 
select * from Table1 where 
field=llogin;

IO_CURSOR := V_CURSOR;


END Rep1;
end;

PL/SQL движок сам заменит pl/sqlпеременную на бинд
......
stax
23 июн 08, 10:45    [5832933]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Так получилось:
orCmd.CommandText ="delete from Table1 where login=:llogin";		
orCmd.Parameters.Clear();
orCmd.Parameters.Add(":llogin", OracleType.VarChar);
orCmd.Parameters[":llogin"].Value=username;
orCmd.ExecuteNonQuery();	

Но не знаю, как все-таки правильно записать для функций и процедур, где есть входные параметры:
orCmd.CommandText = "MyPackage.MyProc";
orCmd.CommandType= CommandType.StoredProcedure;
orCmd.Parameters.Clear();
orCmd.Parameters.Add(new OracleParameter(":value1", OracleType.VarChar)).Direction = ParameterDirection.Input;
orCmd.Parameters[":value1"].Value=username;
orCmd.Parameters.Add(new OracleParameter("value2", OracleType.Cursor)).Direction = ParameterDirection.Output;

где MyPackage.MyProc (value1 in varchar2, value2 out t_cursor)

Но тут ошибка, ругается на параметры
ORA-06550: Строка 1, столбец 40:
PLS-00103: Встретился символ ":" в то время как ожидалось одно из следующих:

   ( - + case mod new not null <an identifier>
   <a double-quoted delimited-identifier> <a bind variable> avg
   count current exists max min prior sql stddev sum variance
   execute forall merge time timestamp interval date
   <a string literal with character set specification>
   <a number> <a single-quoted SQL string> pipe
Символ "( был вставлен перед ":" для продолжения.
25 июн 08, 19:26    [5848367]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Ну подскажите, плиз
26 июн 08, 22:41    [5855248]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10042
novichok928
Ну подскажите, плиз


Do not confuse procedure/function parameters with bind variables.

SY.

Сообщение было отредактировано: 27 июн 08, 00:11
27 июн 08, 00:11    [5855452]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
G.M.
Member

Откуда:
Сообщений: 342
novichok928
Допустим у меня процедура:
procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR)

IS
BEGIN

OPEN V_CURSOR FOR 
select * from Table1 where field=llogin;

IO_CURSOR := V_CURSOR;


END Rep1;
end;

После ее выполнения в V$SQL появится строка с примерно таким SQL_TEXT:
SELECT * FROM TABLE1 WHERE FIELD=:1
Вот :1 - это и есть переменная привязки
27 июн 08, 15:52    [5858879]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
KhamRad
Member

Откуда: Казань - Москва :)
Сообщений: 108
novichok928
Так получилось:
orCmd.CommandText ="delete from Table1 where login=:llogin";		
orCmd.Parameters.Clear();
orCmd.Parameters.Add(":llogin", OracleType.VarChar);
orCmd.Parameters[":llogin"].Value=username;
orCmd.ExecuteNonQuery();	

Но не знаю, как все-таки правильно записать для функций и процедур, где есть входные параметры:
orCmd.CommandText = "MyPackage.MyProc";
orCmd.CommandType= CommandType.StoredProcedure;
orCmd.Parameters.Clear();
orCmd.Parameters.Add(new OracleParameter(":value1", OracleType.VarChar)).Direction = ParameterDirection.Input;
orCmd.Parameters[":value1"].Value=username;
orCmd.Parameters.Add(new OracleParameter("value2", OracleType.Cursor)).Direction = ParameterDirection.Output;

где MyPackage.MyProc (value1 in varchar2, value2 out t_cursor)

Но тут ошибка, ругается на параметры
ORA-06550: Строка 1, столбец 40:
PLS-00103: Встретился символ ":" в то время как ожидалось одно из следующих:

   ( - + case mod new not null <an identifier>
   <a double-quoted delimited-identifier> <a bind variable> avg
   count current exists max min prior sql stddev sum variance
   execute forall merge time timestamp interval date
   <a string literal with character set specification>
   <a number> <a single-quoted SQL string> pipe
Символ "( был вставлен перед ":" для продолжения.


Попробуй без ":"

orCmd.Parameters.Add(new OracleParameter("value1", OracleType.VarChar)).Direction = ParameterDirection.Input;
orCmd.Parameters["value1"].Value=username;
27 июн 08, 16:14    [5859022]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
G.M.
novichok928
Допустим у меня процедура:
procedure Rep1(llogin in varchar2, IO_CURSOR OUT T_CURSOR)

IS
BEGIN

OPEN V_CURSOR FOR 
select * from Table1 where field=llogin;

IO_CURSOR := V_CURSOR;


END Rep1;
end;

После ее выполнения в V$SQL появится строка с примерно таким SQL_TEXT:
SELECT * FROM TABLE1 WHERE FIELD=:1
Вот :1 - это и есть переменная привязки


Что такое V$Sql? А если я хочу явно использовать переменные привязки, а не чтобы за меня это среда делала? Ведь я так понимаю это было бы эффективнее? Я вот нашел вариант
Open my_cursor for
'Select field1
from Table1
where field2=:x'
using x;
Вот тогда явно описал переменную привязки, но если делать то же самое без кавычек, то ругается, что невверная переменная привязки
28 июн 08, 15:02    [5860913]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
Elic
Member

Откуда:
Сообщений: 29977
novichok928
А если я хочу явно использовать переменные привязки, а не чтобы за меня это среда делала? Ведь я так понимаю это было бы эффективнее?
Если "среда" - это PL/SQL, то нет.
28 июн 08, 15:07    [5860920]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
Ну как так! Я всюду читал, что используйте переменные привязки, используйте переменные привязки, а сейчас, когда я это хочу попробовать сделать, получается, что мне ничего и не надо делать? За меня все будет сделано? Их использовать нужно только при динамическом sql?
28 июн 08, 15:32    [5860946]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
Elic
Member

Откуда:
Сообщений: 29977
novichok928
Их использовать нужно только при динамическом sql?
Не только. Главное их место - в клиентском SQL-е, который приложение передаёт на сервер.
28 июн 08, 16:01    [5860962]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
novichok928
Member

Откуда:
Сообщений: 14
О, то есть для процедур не нужно их использование? Я пользуюсь обычными параметрами? И в этом случае не происходит тех самых жестких разборов(, от которых позволяют избавиться переменные привязки)? А происходит оно только если я прям из кода пытаюсь выполнить запрос с переменными(, то есть не хранимкю процедуру, ни фкц, сохраненные и проверенные в базе)
28 июн 08, 18:27    [5861145]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
Elic
Member

Откуда:
Сообщений: 29977
novichok928
О, то есть для процедур не нужно их использование?
В статическом коде это просто невозможно :)
STFF и снова связанные переменные...
28 июн 08, 19:00    [5861192]     Ответить | Цитировать Сообщить модератору
 Re: Переменные привязки  [new]
G.M.
Member

Откуда:
Сообщений: 342
novichok928
Ну как так! Я всюду читал, что используйте переменные привязки, используйте переменные привязки, а сейчас, когда я это хочу попробовать сделать, получается, что мне ничего и не надо делать? За меня все будет сделано?

А Вас не устраивают стандартные легкие пути, хочется испытать радость трудных дорог?
30 июн 08, 11:21    [5863754]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить