Программирование >>  Oracle 

1 ... 167 168 169 [ 170 ] 171 172 173 ... 469


Стратегии и средства настройки

Еше один побочный эффект установки параметра CURSOR SHARING -возможные неожиданные изменения размера столбцов, возвращаемых запросом. Рассмотрим следующий пример, в котором выдается размер возвращаемых столбцов до и после установки CURSOR SHARING. В этом примере для динамического разбора и описания запроса используется пакет DBMS SQL. Он выдает размеры столбцов, которые сообщает приложению сервер Oracle:

tkyte@TKYTE816> declare

2 3 4

6 7 8

10 11 12 13 14 15 16 17 18 19 20 21 22 23

25 26 27 28 29 30 31 32 33

l theCursor

l descTbl l colCnt

integer default dbms sql.open cursor;

dbms sql.desc tab;

number;

begin

execute immediate alter session set cursor sharing=exact; dbms output.put line(Without Cursor Sharing:); f or i in 1.. 2 loop

dbms sql.parse(

l theCursor,

select substr(object name, 55 c2 , Hello c3 from all objects tjji, dbms sql.native);

1, 5) cl.

dbms sql.describe columns(l theCursor,

l colCnt,

l descTbl);

i in 1 . . l colCnt loop dbms output.put line(Column jj

l descTbl(i).col name jj has a length of jj l descTbl(i).col max len);

end loop;

execute immediate alter session set cursor sharing=force;

dbms output.put line(With Cursor Sharing:);

loop;

dbms sql.close cursor(l theCursor); execute immediate alter session set

cursor sharing=exact;

end;

Without Cursor Sharing: Column Cl has a length Column C2 has a length Column C3 has a length With Cursor Sharing: Column Cl has a length Column C2 has a length Column C3 has a length

of of of

of of of

5 2 5

30 22 32

PL/SQL procedure successfully completed.



Глава 10

Размер первого столбца с 5 байт вырос до 30, потому что функция SUBSTR(OBJECT NAME, 1, 5) б1ла переписана как SUBSTR(OBJECT NAME, :SYS B 0, :SYS B l) Сервер не знает , что функция может вернуть максимум 5 байт, поэтому теперь возвращается значение 30 (длина поля OBJECTNAME). Длина второго столбца выросла с 2 до 22 байт, потому что сервер больше не знает , что будет возвращено значение 55 - известно только, что будет возвращаться число, а длина числа может составлять до 22 байт. Для последнего столбца выдано стандартное значение - если бы строка HELLO была больше, то и стандартное значение оказалось бы больше (например, если бы использовалась 35-байтовая строка, стандартное значение составляло бы 128 байт).

Можно возразить: Ну, длина возвращаемых данных не изменится, изменится только значение длины, выдаваемое сервером по запросу описания результирующего множества... . Проблемы возникнут во всех сценариях SQL*Plus, во всех отчетах, создаваемых с помощью различных инструментальных средств, и вообще во всех приложениях, запрашивающих у сервера характеристики результирующего множества для соответствующего форматирования столбцов. Результаты, выдаваемые этими приложениями, при установке параметра CURSOR SHARING изменятся; форматирование тщательно подготовленных отчетов во многих случаях окажется неадекватным. Только подумайте, как это может повлиять на множество уже существующих приложений! Этот побочный эффект очень легко продемонстрировать:

tkyte@TKYTE816> select substr(object name,1,2)

2 from all objects tl

3 where rownum = 1

tkyte@TKYTE816> alter session set cursor sharing = force; Session altered.

tkyte@TKYTE816> select substr(object name,1,2)

2 from all objects t2

3 where rownum = 1

SUBSTR(OBJECT NAME,1,2) /1

Утилита SQL*Plus перешла от столбца из 2 символов к столбцу из 30. Это, несомненно, повлияет на ранее успешно работавшие отчеты.

Используются ли связываемые переменные?

Когда я спрашиваю: Используете ли вы связываемые переменные? , в ответ получаю вопрос: А как узнать, используются ли связываемые переменные? . К счастью, выяснить это весьма просто; вся необходимая информация находится в разделяемом пуле.



Стратегии и средства настройки 543

Я создал сценарий, который часто использую (и распространяю), для выявления операторов, которые совпадали бы при использовании связываемых переменных. Чтобы показать, как работает этот сценарий, я искусственно заполнил разделяемый пул операторами SQL, не использующими связываемых переменных:

tkyte@TKYTE816> create table t (x int) ; Table created.

tkyte@TKYTE816> begin

2 for i in 1 .. 100

3 loop

4 execute immediate insert into t values ( jj i jj );

5 end loop;

6 end;

PL/SQL procedure successfully completed.

Теперь можно демонстрировать сценарий. Он начинается с создания функции, удаляющей константы из строк. Она будет преобразовывать SQL-операторы вида:

insert into t values (hello, 55); insert into t values (world, 66);

в такой вид:

insert into t values (#, @) ;

Все операторы, которые могли бы совпасть при использовании связываемых переменных, теперь легко вхявить: оба представленных выше уникальных оператора INSERT после подстановки станут одинаковыми. Такое преобразование позволяет выполнить следующая функция:

tkyte@TKYTE816> create or replace

2 function remove constants(p query in varchar2)

3 return varchar2

4 as

5 l query long;

6 l char varchar2 (1) ;

7 l in quotes boolean default FALSE;

8 begin

9 for i in 1 .. length(p query)

10 loop

11 l char := substr(p query,i,l);

12 if (l char = and l in quotes)

13 then

14 l in quotes := FALSE;

15 elsif (l char = and NOT l in quotes)

16 then

17 l in quotes := TRUE;

18 l query := l query jj #;

19 end if;

20 if ( NOT l in quotes ) then

21 l query := l query jj l char;



1 ... 167 168 169 [ 170 ] 171 172 173 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика