powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / Покритикуйте Оракл 10г
25 сообщений из 600, страница 24 из 24
Покритикуйте Оракл 10г
    #34690576
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drevПостараюсь объяснить понятие "целостность бизнес-логики" в терминах целостности базы данных.
Я не об этом.

drev1. В текущей модели приоритета
Модели приоритета в любом изложении вещь сомнительная.

Вот только пару дней назад натолкнулся на код, автор которого счет уместным переопределить как ему удобнее стандартные типы данных (integer, boolean, string). Вдобавок он додумался сделать это в публичной (interface) секции, соответственно при подключении его модуля - модуль-то работал, а вот с тем, кто его подключал, начинали твориться слегка странные вещи.

drev3. В свете вышеизложенного синтаксическое разделение локальных переменных и объектов метабазы представляется достаточно мудрым.
Если есть проблема, которая может выстрелить в сотне вариантов, глубо изобретать немасштабируемую блокировку единственного варианта, отнюдь не доминирующего. Могу повторить еще раз: решение с крякозябрами проходит только в условиях ограниченности фич; для Oracle это будет попыткой вычерпать море чайной ложкой.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34690608
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev локальная переменная

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

[СТИЛИЗАЦИЯ]
Страшная история.

Итак рассмотрим ситуацию. Существовал пакет, работал, все было хорошо.
Пакет имел такой вид

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE OR REPLACE PACKAGE pkg_test
IS
v_a NUMBER :=  100 ;
PROCEDURE prc_test;
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_test
IS

PROCEDURE prc_test
IS
v_b NUMBER;
BEGIN
v_b := v_a;
dbms_output.put_line(v_b);
END;
END;
/
Вызов

Код: plaintext
1.
2.
3.
4.
begin
pkg_test.prc_test;
END;
/
 100 

Но уволился программист. Пришел другой, И создал он новую локальную переменную
в процедуре prc_test. А в спецификацию он не глянул. А зачем ему спецификация ?
Ведь он там ничего не менял.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE OR REPLACE PACKAGE pkg_test
IS
v_a NUMBER :=  100 ;
PROCEDURE prc_test;
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_test
IS
PROCEDURE prc_test
IS
v_a NUMBER :=  1000 ;
v_b NUMBER;
BEGIN
v_b := v_a;
dbms_output.put_line(v_b);
END;
END;
/
begin
pkg_test.prc_test;
END;
/ 
 1000 

Изменился результат. Влетело программисту. А если вдуматься: а в чем он несчастный
виноват. Ведь его просто подставили... Вы можете возразить "Да что он, слепой ?
Не увидел , что в коде уже есть обращение к переменной с той же именем ?"
А Вы представьте, что процедура на 1000 строк: ну как ему там, грешному, переменную
найти ?

Нет, виноват Oracle, виноват ...
Предложение совершенно естественное. В рамках готовящихся мероприятий
по отделению именования переменных от именований колонок провести дополнительно
разделенеия именования локальных и глобальных переменных: все глобальные переменные
должны начинаться префиком g_ Какой выигрыш даст это простое в реализации
предложение ! Сколько строк программного кода будет спасено !
[/СТИЛИЗАЦИЯ]
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34690963
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek drev локальная переменная

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

[СТИЛИЗАЦИЯ]
Страшная история.


Изменился результат. Влетело программисту. А если вдуматься: а в чем он несчастный
виноват. Ведь его просто подставили... Вы можете возразить "Да что он, слепой ?
Не увидел , что в коде уже есть обращение к переменной с той же именем ?"
А Вы представьте, что процедура на 1000 строк: ну как ему там, грешному, переменную
найти ?

Нет, виноват Oracle, виноват ...
Предложение совершенно естественное. В рамках готовящихся мероприятий
по отделению именования переменных от именований колонок провести дополнительно
разделенеия именования локальных и глобальных переменных: все глобальные переменные
должны начинаться префиком g_ Какой выигрыш даст это простое в реализации
предложение ! Сколько строк программного кода будет спасено !
[/СТИЛИЗАЦИЯ]


1. История значительно менее страшная:) Программист изменил некую процедуру. Поведение её изменилось. Ожидаемый эффект? Да!

2. Однако поведение её изменилось не так, как хотел программист. Задаём один из главных наших вопросов: Кто виноват?

Ответы:

а) Программист, поскольку он не сделал unit test.
б) Отдел тестирования
в) Разработчик IDE, который не включил в её функциональность импакт-анализ. Как Вы понимаете, в этом случае выдать программисту моментальное предупреждение о смене смысла идентификатора очень легко, правда? Все в пределах одного текста, даже в метабазу ходить не надо.
г) Оракл, который дал лишнюю, ИМХО, свободу? Может быть, но лишь в последнюю очередь.

3. В моей страшной, а по сравнению с Вашей, просто лавкрафтовской истории, всё значительно страшнее. Текст процедуры не менялся. В таблицу была добавлена колонка, неиспользуемая в процедуре. А её поведение - изменилось! Импакт анализ, как Вы отметили, очень сложен в реализации, а в ряде случаев (пример - dynamic SQL) - невозможен.

Мистика какая-то.

Лирическое отступление:

Код: plaintext
1.
2.
3.
4.
А, Б, В встретились в Москве.
В - сказало, Б - упало и осталося без Г.
Кто в ответе, А иль В?

Вот такая мистическая история. Буду очень обрадован, если кто знает на неё ответ.


Кстати, softwarer, на мой взгляд, частичным решением Ваших предпочтений о разделение логики и SQL, является использование binding variables. Вы согласны?

Так вот, при использовании внутри DML statements все локальные переменные в Transact-SQL - binding variables.

И префикс "@" является прямым аналогом префикса ":".
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691364
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev dmidek drev локальная переменная

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

[СТИЛИЗАЦИЯ]
Страшная история.


Изменился результат. Влетело программисту. А если вдуматься: а в чем он несчастный
виноват. Ведь его просто подставили... Вы можете возразить "Да что он, слепой ?
Не увидел , что в коде уже есть обращение к переменной с той же именем ?"
А Вы представьте, что процедура на 1000 строк: ну как ему там, грешному, переменную
найти ?

Нет, виноват Oracle, виноват ...
Предложение совершенно естественное. В рамках готовящихся мероприятий
по отделению именования переменных от именований колонок провести дополнительно
разделенеия именования локальных и глобальных переменных: все глобальные переменные
должны начинаться префиком g_ Какой выигрыш даст это простое в реализации
предложение ! Сколько строк программного кода будет спасено !
[/СТИЛИЗАЦИЯ]


1. История значительно менее страшная:) Программист изменил некую процедуру. Поведение её изменилось. Ожидаемый эффект? Да!

2. Однако поведение её изменилось не так, как хотел программист. Задаём один из главных наших вопросов: Кто виноват?

Ответы:

а) Программист, поскольку он не сделал unit test.
б) Отдел тестирования
в) Разработчик IDE, который не включил в её функциональность импакт-анализ. Как Вы понимаете, в этом случае выдать программисту моментальное предупреждение о смене смысла идентификатора очень легко, правда? Все в пределах одного текста, даже в метабазу ходить не надо.
г) Оракл, который дал лишнюю, ИМХО, свободу? Может быть, но лишь в последнюю очередь.

3. В моей страшной, а по сравнению с Вашей, просто лавкрафтовской истории, всё значительно страшнее. Текст процедуры не менялся. В таблицу была добавлена колонка, неиспользуемая в процедуре. А её поведение - изменилось! Импакт анализ, как Вы отметили, очень сложен в реализации, а в ряде случаев (пример - dynamic SQL) - невозможен.

Мистика какая-то.


ОК. Это хорошо, что этот пример Вас не напугал. Тогда может быть и с другими
Вашими опасениями справимся :-)

Итак насколько я понял, это Вас не пугает

drev1. История значительно менее страшная:) Программист изменил некую процедуру. Поведение её изменилось. Ожидаемый эффект? Да!

2. Однако поведение её изменилось не так, как хотел программист. Задаём один из главных наших вопросов: Кто виноват?

ОК. Тогда рассмотрим пример . Автор пишет новую процедуру.

Код: plaintext
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.
create or replace procedure prc_emp
is
comm NUMBER :=  100000 ;
v_count NUMBER;
begin
SELECT count(*) INTO v_count
FROM emp WHERE sal > comm;
dbms_output.put_line(v_count);
END;
/
SELECT sal, comm from emp
/
SAL COMM 
 23   1  
 800   2  
 1600   2  
 1250   2  
 2975   2  
 1250   2  
 2850   2  
 2450   2  
 3000   2  
 5000   2  
 1500   2  
 1100   2  
 950   2  
 3000   2  
 1300   2  

begin
prc_emp;
end;
/
 15 
Упс. Программист ожидал, что ничего не найдется :-)
Но ничего, будем логичны, нам не страшно, так как у нас есть

drevОтветы:

а) Программист, поскольку он не сделал unit test.
б) Отдел тестирования

Они отбивают эту угрозу. Итак запомним, что нас пугают не все случаи
проявления неприятного эффекта, а лишь некоторые, когда инициатором
ошибки выступает изменение в DDL, путем добавления колонки таблицы.

Хорошо. Прежде, чем пойдем дальше, мои статистические наблюдения.
Я довольно часто бываю в форуме Oracle и периодически сталкиваюсь
у начинающих с этой ошибкой. Так вот, ее описание всегда звучало так
"Я написал(a) функцию и она возвращает неверные результаты",
но никогда я не встречал эту ошибку с описанием "Функция работала и вдруг
перестала". Отметим это .

Теперь идем дальше.
Рассмотрим еще 2 примера

Заранее прошу прощения за их примитивность, исключительно в иллюстративных
целях

Пример 1 : Нас пугает триггер

Код: plaintext
1.
2.
3.
4.
5.
update emp
set sal =  900  where empno =  7369 
/
select sal from emp where empno =  7369 
/
 900 

Так вроде все нормально.
Теперь некто пишет триггер

Код: plaintext
1.
2.
3.
4.
5.
create or replace trigger trg_test
before update on emp
for each row
BEGIN
:new.sal :=  1200 ;
end;

А мы ничего не меняя в наших процедурах пытаемся снова

Код: plaintext
1.
2.
3.
4.
5.
update emp
set sal =  800  where empno =  7369 
/
select sal from emp where empno =  7369 
/
 1200 

В таком аксепте :-)

2. Нас пугает представление с функцией

Пишем функцию и представление

Код: plaintext
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.
create or replace function fnc_emp
return number
is
v_sal number;
begin
select max(sal) into v_sal from emp;
return v_sal;
end;
/
create or replace view viw_test (empno, max_sal)
as select empno, fnc_emp from emp
/
select * from viw_test
/
EMPNO MAX_SAL 
 7369   5000  
 7499   5000  
 7521   5000  
 7566   5000  
 7654   5000  
 7698   5000  
 7782   5000  
 7788   5000  
 7839   5000  
 7844   5000  
 7876   5000  
 7900   5000  
 7902   5000  
 7934   5000  
 8888   5000  
Ну и работаем спокойно с этим представлением везде.
И вдруг меняем - нет, даже не представление - просто фукнцию

Код: plaintext
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.
create or replace function fnc_emp
return number
is
v_sal number;
begin
select min(sal) into v_sal from emp;
return v_sal;
end;
/

select * from viw_test
/
EMPNO MAX_SAL 
 7369   23  
 7499   23  
 7521   23  
 7566   23  
 7654   23  
 7698   23  
 7782   23  
 7788   23  
 7839   23  
 7844   23  
 7876   23  
 7900   23  
 7902   23  
 7934   23  
 8888   23  

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

Так. Теперь вопрос. Пугают ли Вас эти примеры 1 и 2 ?

Если пугают - это вполне понятно, но тогда Ваши первичные страхи имели совершенно
ложную природу.

Ну а если не пугают, то я даже не знаю.
Тогда объяснение одно - пугает именно комбинация фактов.
Кот не пугает и шкаф не пугает, а вот кот на шкафу охватывает душу ужасом.

Тогда это действительно иррациональный страх, да , пожалуй лавкрафтовский :-)
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691368
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek Ну и вот собственно, мы ничего не меняли, спокойно работаем с тем же кодом,
а результат прямо противоположный.

Так. Теперь вопрос. Пугают ли Вас эти примеры 1 и 2 ?

Если пугают - это вполне понятно, но тогда Ваши первичные страхи имели совершенно
ложную природу.

Ну а если не пугают, то я даже не знаю.
Тогда объяснение одно - пугает именно комбинация фактов.
Кот не пугает и шкаф не пугает, а вот кот на шкафу охватывает душу ужасом.

Тогда это действительно иррациональный страх, да , пожалуй лавкрафтовский :-)



Да нет, не пугают примеры 1 и 2. )

Намерения:

1. Как бы не менялось значение sal , установить его в 1200 - осознанное действие приводит к ожидаемому результату

2. Изменить формулу расчёта - осознанное действие приводит к ожидаемому результату


В моём примере:

3. Добавить колонку в таблицу для хранения дополнительных данных.

Намерения "Изменить поведение всех DML statements, в которых используются локальные переменные с именем, совпадающем с именем новой колонки, в контексте, где имя этой колонки допустимо" не было.

Налицо типичный "side-effect".

И тем более страшный, что меняется топология DML statements.


Я объяснил разницу?


Кстати, просто интересно, моё лирическое отступление понятно? :) Про А, Б, В?
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691388
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drevНамерения "Изменить поведение всех DML statements, в которых используются локальные переменные с именем, совпадающем с именем новой колонки, в контексте, где имя этой колонки допустимо" не было.

Налицо типичный "side-effect".

И тем более страшный, что меняется топология DML statements.


Я объяснил разницу?


В общем объяснили. Давайте остановимся тогда на этой формулировке,
а не на "изменении результатов кода без внесения в него изменений".
Этот side-effect достаточно ясно и недвусмысленно документирован

Oracle® Database PL/SQL User's Guide and Reference
10g Release 2 (10.2)
Part Number B14261-01
Name Resolution

In potentially ambiguous SQL statements, the names of database columns take precedence over the names of local variables and formal parameters. For example, if a variable and a column with the same name are both used in a WHERE clause, SQL considers that both cases refer to the column.

To avoid ambiguity, add a prefix to the names of local variables and formal parameters, or use a block label to qualify references as shown in Example 2-14.

Example 2-14 Using a Block Label for Name Resolution

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE employees2 AS SELECT last_name FROM employees;
<<main>>
DECLARE
   last_name VARCHAR2( 10 ) := 'King';
   v_last_name VARCHAR2( 10 ) := 'King';
BEGIN
-- deletes everyone, because both LAST_NAMEs refer to the column
   DELETE FROM employees2 WHERE last_name = last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
-- OK, column and variable have different names
   DELETE FROM employees2 WHERE last_name = v_last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
-- OK, block name specifies that 2nd last_name is a variable
   DELETE FROM employees2 WHERE last_name = main.last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
END;
/

Example 2-15 shows that you can use a subprogram name to qualify references to local variables and formal parameters.

Example 2-15 Using a Subprogram Name for Name Resolution

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
DECLARE
   FUNCTION dept_name (department_id IN NUMBER)
      RETURN departments.department_name%TYPE
   IS
      department_name departments.department_name%TYPE;
   BEGIN
-- DEPT_NAME.department_name specifies the local variable
-- instead of the table column
      SELECT department_name INTO dept_name.department_name
         FROM departments
         WHERE department_id = dept_name.department_id;
      RETURN department_name;
   END;
BEGIN
   FOR item IN (SELECT department_id FROM departments)
   LOOP
      DBMS_OUTPUT.PUT_LINE('Department: ' || dept_name(item.department_id));
   END LOOP;
END;
/


Я в затруднении, можно ли ясно документированное поведение считать
side-effect-ом ...

drevКстати, просто интересно, моё лирическое отступление понятно? :) Про А, Б, В?

Ммм :-) У меня есть более или менее правдоподобная версия, хотя там не все точно
сходится. В общем, я промолчу , чтобы "не остаться без Г"
Наводяший вопрос - это политический памфлет ? :-)
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691397
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek drevНамерения "Изменить поведение всех DML statements, в которых используются локальные переменные с именем, совпадающем с именем новой колонки, в контексте, где имя этой колонки допустимо" не было.

Налицо типичный "side-effect".

И тем более страшный, что меняется топология DML statements.


Я объяснил разницу?


В общем объяснили. Давайте остановимся тогда на этой формулировке,
а не на "изменении результатов кода без внесения в него изменений".
Этот side-effect достаточно ясно и недвусмысленно документирован

Oracle® Database PL/SQL User's Guide and Reference
10g Release 2 (10.2)
Part Number B14261-01
Name Resolution

In potentially ambiguous SQL statements, the names of database columns take precedence over the names of local variables and formal parameters. For example, if a variable and a column with the same name are both used in a WHERE clause, SQL considers that both cases refer to the column.

To avoid ambiguity, add a prefix to the names of local variables and formal parameters, or use a block label to qualify references as shown in Example 2-14.

Example 2-14 Using a Block Label for Name Resolution

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE employees2 AS SELECT last_name FROM employees;
<<main>>
DECLARE
   last_name VARCHAR2( 10 ) := 'King';
   v_last_name VARCHAR2( 10 ) := 'King';
BEGIN
-- deletes everyone, because both LAST_NAMEs refer to the column
   DELETE FROM employees2 WHERE last_name = last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
-- OK, column and variable have different names
   DELETE FROM employees2 WHERE last_name = v_last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
-- OK, block name specifies that 2nd last_name is a variable
   DELETE FROM employees2 WHERE last_name = main.last_name;
   DBMS_OUTPUT.PUT_LINE('Deleted ' || SQL%ROWCOUNT || ' rows.');
   ROLLBACK;
END;
/

Example 2-15 shows that you can use a subprogram name to qualify references to local variables and formal parameters.

Example 2-15 Using a Subprogram Name for Name Resolution

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
DECLARE
   FUNCTION dept_name (department_id IN NUMBER)
      RETURN departments.department_name%TYPE
   IS
      department_name departments.department_name%TYPE;
   BEGIN
-- DEPT_NAME.department_name specifies the local variable
-- instead of the table column
      SELECT department_name INTO dept_name.department_name
         FROM departments
         WHERE department_id = dept_name.department_id;
      RETURN department_name;
   END;
BEGIN
   FOR item IN (SELECT department_id FROM departments)
   LOOP
      DBMS_OUTPUT.PUT_LINE('Department: ' || dept_name(item.department_id));
   END LOOP;
END;
/


Я в затруднении, можно ли ясно документированное поведение считать
side-effect-ом ...

drevКстати, просто интересно, моё лирическое отступление понятно? :) Про А, Б, В?

Ммм :-) У меня есть более или менее правдоподобная версия, хотя там не все точно
сходится. В общем, я промолчу , чтобы "не остаться без Г"
Наводяший вопрос - это политический памфлет ? :-)

1. Если бы его ещё не документировали:) Но:) Так как приведённые примеры предполагают наличие совпадающих имён на момент написания процедуры, это не спасает в случае добавления НОВОЙ колонки. Это попытка штопать дыры. В общем случае, следует рекомендовать ВСЕГДА использовать префиксы или квалификтаторы.

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

2. А = Аннушка:)
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691400
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev
2. А = Аннушка:)

Черт возьми !
А ведь можно было, можно было догадаться :-)

Об остальном уже завтра, сорри.
До свидания
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691401
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek drev
2. А = Аннушка:)

Черт возьми !
А ведь можно было, можно было догадаться :-)

Об остальном уже завтра, сорри.
До свидания

Good night:)
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34691636
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OffTop:

softwarerРасскажу другую сказку, в которой буквально на днях принял участие, не страшную, правда, характеризующуюся другим словом. Есть у борланда такая дурная по большому счету технология, weak packaging.

заинтреговал (как старого делфятника), а что хотел сделать если не секрет ?
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34692382
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev
1. Если бы его ещё не документировали:) Но:) Так как приведённые примеры предполагают наличие совпадающих имён на момент написания процедуры, это не спасает в случае добавления НОВОЙ колонки. Это попытка штопать дыры. В общем случае, следует рекомендовать ВСЕГДА использовать префиксы или квалификтаторы.

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



Теперь по сабжу. В документации есть еще слово "potentially".
А в целом... Я право затрудняюсь. Я уже довольно много написал по
этому поводу. Если Вы считаете данное решение неверным, что же,
для Вас наверное это так и есть.

Скажу за себя и искренне. Впервые с сабжем (в его с Вашей точки зрения
безобидной модификации) я столкнулся на нашем сайте в программах
новичков, уже имея к тому времени довольно большой опыт работы с Oracle.
Почему ? Из- за использования корпоративных стандартов написания
кода. Конечно, математическая вероятность возникновения такого эффекта
остается всегда, но в моей реальной программистской жизни она слишком
незначительна и неважна, чтобы на ее основе делать столь неутешительные
выводы. Это естественно полностью мое субъективное мнение.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34694363
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gluk (Kazan)заинтреговал (как старого делфятника), а что хотел сделать если не секрет ?
Да все просто на самом деле. Сделал я маленькую такую подпрограмму, FreeOnExit (AObject), предназначение надеюсь понятно. Вопрос в том, как бы половчее отловить собственно OnExit в случае пакетов-dll-ек. И вот как раз weakpackage-овский finally для этого ну невозможно подходит. Но к сожалению - в 11-й версии работает, а например в 6-й нет. В семерке - не проверял.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34694367
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drevКстати, softwarer, на мой взгляд, частичным решением Ваших предпочтений о разделение логики и SQL, является использование binding variables. Вы согласны?
Нет, пожалуй. Я бы сказал, bind variables - это "физика", проглядывающая сквозь прореху логической модели "sql прямо в программном коде". Какое отношение это имеет к "разделению" - не могу вообразить.

drevТак вот, при использовании внутри DML statements все локальные переменные в Transact-SQL - binding variables.
Знаю.

drevИ префикс "@" является прямым аналогом префикса ":".
Не годится. Это было бы так, если бы вне DML переменные использовались бы без префикса "@". А так это - ровно те самые бейсиковские S$; просто некоторое поддерживаемое компилятором соглашение.

Впрочем, если хотите, попробуйте как доказательство похожести повторить следующий пример (вот уж, кстати, что относится к реальным недостаткам Oracle, так это именно он)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SQL> set serveroutput on ;
SQL> 
SQL> declare
   2     a integer :=  1  ;
   3     b integer :=  2  ;
   4     c integer ;
   5   begin
   6     execute immediate 'select count(*) into :c from dual where :a = :a' into c using a, b ;
   7     dbms_output.put_line ( 'count = ' || c ) ;
   8   end ;
   9   /

count =  0 

PL/SQL procedure successfully completed
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34694489
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer Gluk (Kazan)заинтреговал (как старого делфятника), а что хотел сделать если не секрет ?
Да все просто на самом деле. Сделал я маленькую такую подпрограмму, FreeOnExit (AObject), предназначение надеюсь понятно. Вопрос в том, как бы половчее отловить собственно OnExit в случае пакетов-dll-ек. И вот как раз weakpackage-овский finally для этого ну невозможно подходит. Но к сожалению - в 11-й версии работает, а например в 6-й нет. В семерке - не проверял.

понятно
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34695198
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerВпрочем, если хотите, попробуйте как доказательство похожести повторить следующий пример (вот уж, кстати, что относится к реальным недостаткам Oracle, так это именно он)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SQL> set serveroutput on ;
SQL> 
SQL> declare
   2     a integer :=  1  ;
   3     b integer :=  2  ;
   4     c integer ;
   5   begin
   6     execute immediate 'select count(*) into :c from dual where :a = :a' into c using a, b ;
   7     dbms_output.put_line ( 'count = ' || c ) ;
   8   end ;
   9   /

count =  0 

PL/SQL procedure successfully completed


Да уж :-)
В документации этот момент представлен достаточно забавно - впечатление,
что рассказывают так быстро, чтобы никто спросить не успел

Using Duplicate Placeholders

авторSo, if the same placeholder appears two or more times in the SQL statement, each appearance must correspond to a bind argument in the USING clause. For example, given the dynamic string

sql_stmt := 'INSERT INTO payroll VALUES (:x, :x, :y, :x)';


you might code the corresponding USING clause as follows:

EXECUTE IMMEDIATE sql_stmt USING a, a, b, a;

И быстрей бежать, пока никто не спросил

"А если написать ?"

Код: plaintext
EXECUTE IMMEDIATE sql_stmt USING a, b, b, a;


Да и ниже описанная разница в поведении между SQL и PL/SQL -
да уж: две разные бригады
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696852
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. В исходном примере Александра у меня сразу мелькнула мысль поменять двойку на единицу:) Чтоб получить в результате 1:)

2. Документация Оракл, особенно используемые примеры, это тема отдельная, богатая:) Впрочем, это касается не только Оракл.

3. Мне, лично, показалась бы более естественной и удобной такая структура:

Код: plaintext
1.
2.
3.
4.
sql_stmt := 'INSERT INTO payroll VALUES (:x, :x, :y, :x)';

you might code the corresponding USING clause as follows:

EXECUTE IMMEDIATE sql_stmt USING :х = a, :у = b;
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696902
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev
3. Мне, лично, показалась бы более естественной и удобной такая структура:

Код: plaintext
1.
2.
3.
4.
sql_stmt := 'INSERT INTO payroll VALUES (:x, :x, :y, :x)';

you might code the corresponding USING clause as follows:

EXECUTE IMMEDIATE sql_stmt USING :х = a, :у = b;


drev, а Вы прочитали по ссылке , как разрешается эта коллизия в PL/SQL ?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
DECLARE
   a NUMBER :=  4 ;
   b NUMBER :=  7 ;
BEGIN
   plsql_block := 'BEGIN calc_stats(:x, :x, :y, :x); END;'
   EXECUTE IMMEDIATE plsql_block USING a, b;
   ...
END;

Или , взяв пример Александра

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :a;
                   b integer := :a;
           begin 
           select count(*) into :c from dual where a = b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;
/
ORA- 01006 : bind variable does not exist 

А вот так все в порядке

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :a;
                   b integer := :b;
           begin 
           select count(*) into :c from dual where a = b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;
/
count =  0 

И наконец

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :a;
                   b integer := :a;
           begin 
           select count(*) into :c from dual where a = b;
           end; ' USING IN a, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;
/
count =  1 

Вторая бригада "PL/SQL" продвинулась гораздо дальше
Практически Ваш вариант ...
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696952
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek
Вторая бригада "PL/SQL" продвинулась гораздо дальше
Практически Ваш вариант ...

1. Весело:)

2. Насколько я понимаю, всё-таки несовсем "мой вариант".

Как я понимаю, в PL/SQL происходит позиционная привязка по первому упоминанию binding variable?

Т.е.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :a;
                   b integer := :b;
           begin 
           select count(*) into :c from dual where a > b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;
эквивалентно

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :b;
                   b integer := :a;
           begin 
           select count(*) into :c from dual where a > b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;

В предложенном мной варианте результат будет разный.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696957
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev dmidek
Вторая бригада "PL/SQL" продвинулась гораздо дальше
Практически Ваш вариант ...

1. Весело:)

2. Насколько я понимаю, всё-таки несовсем "мой вариант".

Как я понимаю, в PL/SQL происходит позиционная привязка по первому упоминанию binding variable?

Т.е.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :a;
                   b integer := :b;
           begin 
           select count(*) into :c from dual where a > b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;
эквивалентно

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
    begin
      execute immediate '
           declare a integer := :b;
                   b integer := :a;
           begin 
           select count(*) into :c from dual where a > b;
           end; ' USING IN a, IN b, OUT c;
      dbms_output.put_line ( 'count = ' || c ) ;
    end ;

В предложенном мной варианте результат будет разный.

Да, Вы правы. Но идеологически ИМХО они довольно таки похоже и представляют
прогресс по сравнению с SQL-вским.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696985
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek
Да, Вы правы. Но идеологически ИМХО они довольно таки похоже и представляют
прогресс по сравнению с SQL-вским.


ИМХО, это прогресс уровня:

- 2х2 = 17

- Нет! 2х2 = 5!

Но Вы правы, прогресс на лицо.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696989
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev dmidek
Да, Вы правы. Но идеологически ИМХО они довольно таки похоже и представляют
прогресс по сравнению с SQL-вским.


ИМХО, это прогресс уровня:

- 2х2 = 17

- Нет! 2х2 = 5!

Но Вы правы, прогресс на лицо.

Не вижу этой параллели :-)
Но это субъективно.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34696994
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dmidek drev dmidek
Да, Вы правы. Но идеологически ИМХО они довольно таки похоже и представляют
прогресс по сравнению с SQL-вским.


ИМХО, это прогресс уровня:

- 2х2 = 17

- Нет! 2х2 = 5!

Но Вы правы, прогресс на лицо.

Не вижу этой параллели :-)
Но это субъективно.

Вроде бы решается банальная задача параметризации. ИМХО, лучше формальных параметров, с именами и типами, не придумали:)

Кстати, предложенный мной вариант я бы оценил как 2х2 = 4.5 :)

Типы и дефолты отсутствуют.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34697000
Фотография dmidek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drev dmidek drev dmidek
Да, Вы правы. Но идеологически ИМХО они довольно таки похоже и представляют
прогресс по сравнению с SQL-вским.


ИМХО, это прогресс уровня:

- 2х2 = 17

- Нет! 2х2 = 5!

Но Вы правы, прогресс на лицо.

Не вижу этой параллели :-)
Но это субъективно.

Вроде бы решается банальная задача параметризации. ИМХО, лучше формальных параметров, с именами и типами, не придумали:)

Кстати, предложенный мной вариант я бы оценил как 2х2 = 4.5 :)

Типы и дефолты отсутствуют.

Снова ИМХО
Все- таки считаю, что приведение в качестве аналогии таблицы умножения с неверным
результатом простейшей операции явлется сильной и совершенно неоправданной
натяжкой и может вызвать у постороннего читателя превратную картину.
И первое и второе использование bind-variables с динамическим SQL вошло со всеми своими особенностями в повседневную практику , не вызывает сложностей и не чревато ошибками.
Здесь опять же на мой взгляд можно говорить об узких местах достаточно
неуклюжего инструментария, тем не менее редко проявляющихся на практике .
Не более того.
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34697336
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может Вы и правы, и я утрирую.

Мне просто кажется, что

Код: plaintext
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.
declare
      a integer :=  1  ;
      b integer :=  2  ;
      c integer ;
      
      new_plsql_str varchar2( 500 );

    begin
           new_plsql_str  :=
           'define  :a integer IN;
                   :b integer DEFAULT 5 IN;    
                   :c integer OUT;    
           declare a integer := :b;
                   b integer := :a;
           begin 

           select count(*) into :c from dual where a > b;
           end; ' ;
  
           execute immediate new_plsql_str USING a,b,c;

           dbms_output.put_line ( 'count = ' || c ) ;

           execute immediate new_plsql_str USING :a = b, :c = c;

           dbms_output.put_line ( 'count = ' || c ) ;

    end ;


было бы правильнее
...
Рейтинг: 0 / 0
Покритикуйте Оракл 10г
    #34697579
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drevбыло бы правильнее
В формате с define внутри строки правильнее бы это не было, имхо, по нескольким причинам. Во-первых, ключевая и совершенно статическая вещь тащится в динамическую компиляцию. Во-вторых, Вы предлагаете построить механизм, практически альтернативный уже существующему (параметры функций). Ну и наконец, дополнительные загрузы с shared pool-ом. Дефолтовые значения в данном случае не нужны по той причине, что строка - не объект и переиспользуется весьма и весьма редко.

Если сосредоточиться на предложении добавить именной биндинг к позиционному - думаю, это было бы хорошо. Насчет более глобальных модификаций - спорно.
...
Рейтинг: 0 / 0
25 сообщений из 600, страница 24 из 24
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / Покритикуйте Оракл 10г
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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