Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вопрос про :NEW-псевдозапись в BEFORE-триггере / 25 сообщений из 29, страница 1 из 2
04.10.2016, 14:19
    #39320282
konaz_714
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Здравствуйте.

Возник вопрос по поводу работы триггеров уровня строки (row-level
triggers). Как известно, в этих BEFORE-триггерах есть возможность
обращаться к :NEW и :OLD псевдозаписям. В том числе можно изменить
значение поля в :NEW-записи и оно окажется в строке таблицы вместо
того, что было предусмотрено UPDATE или INSERT.

В меру моего понимания, есть PL/SQL-машина (PVM). И есть SQL
движок. Они вместе работают на одном уровне ядра. Уровне выполнения KX.

The execution layer (KX). This layer handles the binding and execution
of SQL statements and PL/SQL program units. It is also responsible for
the execution of recursive calls for trigger execution, and for the
execution of SQL statements within PL/SQL program units.

Выполняются SQL и PL/SQL полностью раздельно. С переключением
контекста SQL-PL/SQL и обратно внутри серверного процесса.

Два вопроса:

1) Как заполняется NEW для BEFORE-триггера? В документации есть фраза.

When a row-level trigger fires, the PL/SQL runtime system creates and
populates the two pseudorecords OLD and NEW.

Но ведь триггер срабатывает ДО изменений (которые дает NEW).
Причем там вся вот эта кухня с мини-откатами и перезапусками.
В статье Сергея Маркеленкова Алгоритм “мини-откатов” в Oracle
или еще раз о Write Consistency такая схема:

- в режиме согласованного чтения находим строку;
- блокируем ее в текущем состоянии;
- на ней срабатывает триггер (OLD-то передается в режиме согласованного
чтения, а NEW-то откуда?, еще изменения-то не было);
- происходит сравнение столбцов из старого (в CR-блоке) и
текущего (в CURRENT-блоке) содержимого строки;
- и только потом выполняется собственно изменение строки.

2) Как сделанные триггером изменения в NEW окажутся в блоках? В меру
моего понимания, это может сделать только SQL. Кто именно его выполнит?

Скорее всего, это делает PL/SQL-машина, которая выполнит UPDATE этой
строки после окончания срабатывания всех триггеров. Не случайно в псевдозаписях есть
столбец с ROWID. А строка заблокирована нами перед срабатыванием
первого триггера. Верная гипотеза? Вроде больше некому.

Спасибо.
...
Рейтинг: 0 / 0
04.10.2016, 14:38
    #39320294
CrazyCat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
и тебе привет!

я знаю кто ты :)
...
Рейтинг: 0 / 0
04.10.2016, 14:39
    #39320296
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
konaz_714обращаться к :NEW и :OLD псевдозаписям.Это конечный перечень bind-переменных.konaz_7142) Как сделанные триггером изменения в NEW окажутся в блоках? В меру
моего понимания, это может сделать только SQL. Кто именно его выполнит?

Скорее всего, это делает PL/SQL-машина, которая выполнит UPDATE этой
строки после окончания срабатывания всех триггеров. Не случайно в псевдозаписях есть
столбец с ROWID. А строка заблокирована нами перед срабатыванием
первого триггера. Верная гипотеза? Вроде больше некому.По-твоему получается, что если триггеров нет, то изменения никогда не попадут в блоки
...
Рейтинг: 0 / 0
04.10.2016, 14:59
    #39320315
konaz_714
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
1) Погодите, какие связываемые переменные в строчном триггере? На каждой строке? Чьи они тогда, для какого предложения SQL? Связываемые переменные, в меру моего понимания, у того SQL, который вызвал срабатывание были, а могли и не быть.

2) Если триггера нет, то и NEW нет и изменения делает просто сам UPDATE.
...
Рейтинг: 0 / 0
04.10.2016, 15:29
    #39320341
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
konaz_714Связываемые переменные, в меру моего понимания, у того SQL, который вызвал срабатывание были, а могли и не быть.Триггер - это рекурсивный SQL.
konaz_7142) Если триггера нет, то и NEW нет и изменения делает просто сам UPDATE.Щаз. Два разных механизма? - Кому это надо сопровождать?

Ты вообще уверен, что понимаешь основы, чтобы лезть в дебри? Да и зачем туда лезть?
...
Рейтинг: 0 / 0
04.10.2016, 16:22
    #39320401
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
konaz_714Погодите, какие связываемые переменные в строчном триггере?Триггер - рекурсивный вызов PL/SQL и NEW/OLD выступает в роли интерфейса передачи параметров туда.

Элементарный пример как триггеры работают при рестарте смотри тут .

Про уровни и вызовы - полная каша.
Если интересна последователось вызовов - воспользуйся инструментарием из ссылок wurdu в твоем предыдудем топике.
Кроме того, куча профайлеров на сайте Подера.
Из встроенных средст - PL/SQL tracing & dbms_hprof, но не дает такой детализации.

В чем вообще цель изысканий? Конкурента Ораклу пишешь?
...
Рейтинг: 0 / 0
05.10.2016, 09:23
    #39320713
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
ElicТриггер - это рекурсивный SQL.
dbms_photoshop Триггер - рекурсивный вызов PL/SQL

Вы что ребят сговорились? Рекурсия это описание себя в себе.
Что-то типа:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t(id) as (
 select 1 id from dual
  union all
 select id+1 from t where id<3
)
select * from t;

create or replace function f(n number) return number is
 begin
  if n<10 then 
   return f(n+1);
  end if; 
  return n;
 end;
/



А запуск чего-то по событию, называется триггер, а не рекурсия.
...
Рейтинг: 0 / 0
05.10.2016, 09:39
    #39320730
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
...
Рейтинг: 0 / 0
05.10.2016, 09:46
    #39320735
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Вячеслав Любомудров,

Рекурсивные вызовы . Но не рекурсивный SQL.

P.S. Назвать :NEW и :OLD обращением к вызывающему оператору. Ладно пусть будет.
...
Рейтинг: 0 / 0
05.10.2016, 09:57
    #39320744
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей Арсеньева не рекурсия.RTFM ORA-00604
...
Рейтинг: 0 / 0
05.10.2016, 10:08
    #39320755
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей Арсеньева не рекурсия.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SQL> create table plch_tmp(n int);

Table created.

SQL> create trigger plch_tmp$trg after insert on plch_tmp
  2  begin
  3    insert into plch_tmp select max(n) + 1 from plch_tmp;
  4  end;
  5  /

Trigger created.

SQL> insert into plch_tmp values (1);
insert into plch_tmp values (1)
            *
ERROR at line 1:
ORA-00036: maximum number of recursive SQL levels (50) exceeded

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2
ORA-04088: error during execution of trigger 'ELIC.PLCH_TMP$TRG'
ORA-06512: at "ELIC.PLCH_TMP$TRG", line 2


SQL> drop table plch_tmp;

Table dropped.

...
Рейтинг: 0 / 0
05.10.2016, 10:18
    #39320766
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Elic,

Заметь. Ты вызвал SQL машину из SQL машины (через триггер). Это рекурсия.
тут Оракул считает именно их
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
drop table t;

create table t as select 1 id,0 value from dual;

CREATE OR REPLACE TRIGGER T 
AFTER UPDATE ON T
declare
 n number;
BEGIN
  select value into n from t where id=1;
  if n<=51 then
   update t set value=value+1 where id=1;
  end if;  
END;
/

update t set value=1 where id=1;

CREATE OR REPLACE TRIGGER T 
AFTER UPDATE ON T
declare
 n number;
BEGIN
  select value into n from t where id=1;
  if n<=50 then
   update t set value=value+1 where id=1;
  end if;  
END;
/

update t set value=1 where id=1;

select * from t where id=1;


Вызов PL/SQL машины из SQL (собственно триггер). За рекурсию не считается.
...
Рейтинг: 0 / 0
05.10.2016, 10:38
    #39320786
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
konaz_714Но ведь триггер срабатывает ДО изменений (которые дает NEW).
Собственно, проблема в попытках привнести человечески язык в программирование. В конце концов это приводит к непониманию того, что реально происходит.

На данную проблему надо смотреть проще. Оба вида триггеров срабатывают после наступления события (изменения) просто те которые before срабатывают гарантированно раньше тех, которые after (в пределах одного и того же типа порядок не гарантирован).

А то, что по английски эта фраза значит совсем другое - так забей на английский, ты не с англичанином общаешся, а с компьютером. :)
...
Рейтинг: 0 / 0
05.10.2016, 10:52
    #39320804
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей АрсеньевОба вида триггеров срабатывают после наступления события (изменения) просто те которые before срабатывают гарантированно раньше тех, которые after
Серьезно?!
...
Рейтинг: 0 / 0
05.10.2016, 11:19
    #39320836
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
andrey_anonymous,

Не не серьезно. Только вот иначе непонятно, что такое :new.value если его еще нет и откуда RDMS его берет если событие еще не наступило? Да и триггер должен сработать на событие, а его еще нет. Так логический ряд выглядит так событие->вычисление того, что должно поменяться и на что должно поменяться->before триггера->финализация записи->after триггера. Поэтому в after и стоит запрет на изменения, потому что это те триггера в которых известно чему будет равно значение после операции (или изменения строки), а before триггера видят только промежуточный итог.
...
Рейтинг: 0 / 0
05.10.2016, 11:26
    #39320841
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей Арсеньевandrey_anonymous,

Не не серьезно. Только вот иначе непонятно, что такое :new.value если его еще нет и откуда RDMS его берет если событие еще не наступило?
Если бы мсье задался вопросом про :old в before-триггере - я бы еще как-то понял сомнения, но :new - это уже перебор.

:new - это переданные в insert/update данные, предназначенные для ЗАНЕСЕНИЯ в таблицу.
Они пришли извне и могут быть скорректированы триггером.
К примеру, для delete вы в этом :new ничего не найдете.
:old - это то, содержалось в (уже обнаруженной к моменту срабатывания строчного триггера) строке до выполнения изменений.
В случае insert никакого :old, понятно, не будет.

Перед физическим изменением строки :new и :old уже известны однозначно и определенно.
...
Рейтинг: 0 / 0
05.10.2016, 12:03
    #39320896
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
andrey_anonymous:new - это переданные в insert/update данные, предназначенные для ЗАНЕСЕНИЯ в таблицу.

Скорее текущее состояние. Ибо триггеров может быть чуть больше чем один.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
drop table t;

create table t as select 1 id,0 value from dual;

CREATE OR REPLACE TRIGGER T1
before UPDATE ON T for each row
BEGIN
  SYS.DBMS_OUTPUT.PUT_LINE('T1:'||:new.value);
   :new.value:=:new.value*1.02;
END;
/

CREATE OR REPLACE TRIGGER T2
before UPDATE ON T for each row
BEGIN
  SYS.DBMS_OUTPUT.PUT_LINE('T2:'||:new.value);
   :new.value:=:new.value+0.5;
END;
/

set SERVEROUTPUT ON;

update t set value=1 where id=1;

select * from t where id=1;



Считать ли что update начался когда определились с тем что и на что менять или, когда изменили значение в блоке - уже вопрос физической реализации (собственно если бы не было изменений, то и не замечал бы oracle, что таблица мутировала).
...
Рейтинг: 0 / 0
05.10.2016, 13:24
    #39320996
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей АрсеньевСкорее текущее состояние. Ибо триггеров может быть чуть больше чем один
Нет. Именно то, что пришло на вход триггеру.
Рассматривайте before-триггер как фильтр.
Несколько триггеров - цепочка фильтров.
И все станет просто.

Сергей АрсеньевСчитать ли что update начался когда определились с тем что и на что менять или, когда изменили значение в блоке - уже вопрос физической реализации (собственно если бы не было изменений, то и не замечал бы oracle, что таблица мутировала).
Нет. Это в первую голову вопрос логической организации процесса.
Рассмотрите, к примеру, вариант с наличием ограничений уникальности или check-constraint на обновляемых полях.
А до кучи - процесс обновления/удаления первичного/уникального ключа при наличии дочерних записей при различных вариантах декларации связи (ON DELETE CASCADE/SET NULL).

Вопрос о "мутации таблицы" тоже не столько вопрос физической реализации, сколько логический вопрос о том, с какими записями и в каком виде будет работать строчный триггер, вызванный посреди процесса модификации неизвестного триггеру количества строк в неопределенном порядке .
Весь exception - чтобы не порушить принцип атомарности, а не ограничение реализации.
...
Рейтинг: 0 / 0
05.10.2016, 17:30
    #39321254
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
andrey_anonymousВопрос о "мутации таблицы" тоже не столько вопрос физической реализации, сколько логический вопрос о том, с какими записями и в каком виде будет работать строчный триггер, вызванный посреди процесса модификации неизвестного триггеру количества строк в неопределенном порядке .
Весь exception - чтобы не порушить принцип атомарности, а не ограничение реализации.
Вот в том и дело, что процесс начат и не закончен. Даже если мы имеем дело всего с одной строкой.

Если рассматривать before триггер именно, как, сработавший до начала операции, то никакой мутации бы быть не должно - ибо до изменений то нет. Но он срабатывает именно в процессе, когда результат неизвестен. И чтобы выходцы из TSQL (и прочие) не наваяли несуразного и присутствует exception.
...
Рейтинг: 0 / 0
05.10.2016, 17:44
    #39321264
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей АрсеньевЕсли рассматривать before триггер именно, как, сработавший до начала операции, то никакой мутации бы быть не должно - ибо до изменений то нет. Но он срабатывает именно в процессе, когда результат неизвестен. И чтобы выходцы из TSQL (и прочие) не наваяли несуразного и присутствует exception.
Вы точно хорошо помните как и при каких условиях срабатывает "мутация"? :)
...
Рейтинг: 0 / 0
05.10.2016, 18:44
    #39321316
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
andrey_anonymous,

При попытке из row level триггера узнать содержимое изменяемых строк.
В силу того, что триггер написан на PL читать содержимое блока он не может, он запускает новый sql. который срабатывает на другой scn. А значение на этот scn в рамках этой же транзакции СУБД определить не может. Ибо действия в пределах одной операции Оракул помечать разными моментами времени не хочет - накладно.
...
Рейтинг: 0 / 0
05.10.2016, 18:57
    #39321327
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей АрсеньевВ силу того, что триггер написан на PL читать содержимое блока он не может, он запускает новый sql. который срабатывает на другой scn. А значение на этот scn в рамках этой же транзакции СУБД определить не может. Ибо действия в пределах одной операции Оракул помечать разными моментами времени не хочет - накладно.Пошёл откровенный бред...
...
Рейтинг: 0 / 0
05.10.2016, 19:31
    #39321347
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
Сергей Арсеньевandrey_anonymous:new - это переданные в insert/update данные, предназначенные для ЗАНЕСЕНИЯ в таблицу.

Скорее текущее состояние. Ибо триггеров может быть чуть больше чем один.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
drop table t;

create table t as select 1 id,0 value from dual;

CREATE OR REPLACE TRIGGER T1
before UPDATE ON T for each row
BEGIN
  SYS.DBMS_OUTPUT.PUT_LINE('T1:'||:new.value);
   :new.value:=:new.value*1.02;
END;
/

CREATE OR REPLACE TRIGGER T2
before UPDATE ON T for each row
BEGIN
  SYS.DBMS_OUTPUT.PUT_LINE('T2:'||:new.value);
   :new.value:=:new.value+0.5;
END;
/

set SERVEROUTPUT ON;

update t set value=1 where id=1;

select * from t where id=1;



Считать ли что update начался когда определились с тем что и на что менять или, когда изменили значение в блоке - уже вопрос физической реализации (собственно если бы не было изменений, то и не замечал бы oracle, что таблица мутировала).До 11 порядок срабатывания триггеров был неопределен. Потом появилось FOLLOWS .

При чем здесь мутация?

Сергей АрсеньевВ силу того, что триггер написан на PL читать содержимое блока он не может, он запускает новый sqlТриггеру вообще не надо читать блоки! В него передается то, что необходимо.
А вообще неожиданно читать такие фантазии после того как был упомянут необходимый инструментарий.

Все вызовы SQL можно отловить трассой 10046, но это ж надо было такое придумать!
...
Рейтинг: 0 / 0
05.10.2016, 19:42
    #39321364
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
dbms_photoshopТриггеру вообще не надо читать блоки! В него передается то, что необходимо.

Ну чтобы отловить мутацию - таки надо читать блоки :)
Другой вопрос, что уважаемый визави нафантазировал тут с три короба - но то такое...
...
Рейтинг: 0 / 0
05.10.2016, 20:39
    #39321401
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про :NEW-псевдозапись в BEFORE-триггере
andrey_anonymous,

Чтобы возникла мутация рекурсивный SQL должен читать меняемую таблицу.
Триггер ничего не читает сам по себе. Его вообще может не быть для возникновения мутации.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вопрос про :NEW-псевдозапись в BEFORE-триггере / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]