Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Переменное число аргументов в пранимой процедуре / 19 сообщений из 19, страница 1 из 1
31.03.2005, 12:23
    #32990655
g613
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
День добрый,

ASE 12.5.1

Не подскажите как передать в хранимую процедуру переменное количество аргументов, и как к ним потом обращаться в самой процедуре ?
...
Рейтинг: 0 / 0
31.03.2005, 12:50
    #32990734
Александр Спелицин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Можно использовать аргументы со значениями по умолчанию
Create procedure Test (@a int, @b int = 50)

Если данной процедуре передается только один парамет (@a), то она считает, что второй равен 50 (@b = 50).
...
Рейтинг: 0 / 0
31.03.2005, 13:07
    #32990797
Crip
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Добавление - вызывать процедуру надо только с именованными параметрами.
Пример:
Create procedure Test (@a int=30, @b int = 50)
Вызов:
exec Test @b = 100
...
Рейтинг: 0 / 0
31.03.2005, 13:36
    #32990886
g613
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Нет, это несколько не то. Грубо говоря это должно выглядеть примерно так:
есть кучка процедур, которые вызываются с определенными параметрами, количество параметров у тех процедур разное. Хочется - в начале/в_конце тех процедур добавить вызов своей, которая принимает все параметры которые передали `родителю` - то есть некое подобие логирования действий.
Можно конечно создать процедуру и прописать ей пару десятков именованых параметров, что то типа:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Create procedure my_log (@parent_name varchar( 50 ),
                                    @Param_1 varchar( 250 ) = null,
                                     ...,
                                    @Param_20 varchar( 250 ) = null )
...
if @Param_1 is not null
  select @LogStr = @LogStr + "  " + @Param_1
...
if @Param_20 is not null
  select @LogStr = @LogStr + "  " + @Param_1
....

но хочется, что то более короткое...
...
Рейтинг: 0 / 0
31.03.2005, 16:56
    #32991654
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Не бывает в ASE процедур с переменным кол-вом параметров. Есть только возможность не указывать значение какого-то параметра, если у него есть значение по умолчанию.

(кстати, если указать лишние параметры по имени или по порядку, то они просто игнорируются без каких-либо последствий).
...
Рейтинг: 0 / 0
31.03.2005, 17:15
    #32991724
g613
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
понятно.

Я в общем то остановился на том, что отписал несколько выше ( то есть с определением числа параметров равное максимально возможному и кучей ИФ'оф ), только громоздко оно несколько смотрится...
...
Рейтинг: 0 / 0
31.03.2005, 17:46
    #32991810
g613
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Такой вопрос еще возник, как передать в качестве аргумента в процедуру значение какой либо функции, тоесть хочется примерно следующего:
Код: plaintext
1.
exec my_log 'UserDel', convert(varchar,@unknown_type_par_1), convert(varchar, @unknown_type_par_2)

так ругается:
Incorrect syntax near the keyword 'convert'.
...
Рейтинг: 0 / 0
31.03.2005, 22:14
    #32992185
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
В вызове процедуры по синтаксису в качестве значения параметра может быть только либо константа, либо локальная переменная.
Надо предварительно вычислить значение функции и сохранить ее в переменной, а затем переменную передать в параметр процедуры.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
23.02.2011, 15:42
    #37132285
jab
jab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Дабы не плодить похожие темы, решил задать аналогичный вопрос в этой теме. У меня тоже ASE 12.5.4 и тоже подошел момент к тому, что надобы както реорганизовывать подход доступа к данным с стороны программистов. Хотелось бы какимто макаром реализовать следующее. Допустим у меня есть набор некоторых связанных таблиц с данными. Мне нужно из них выбирать, добавлять, изменять, удалять данные. Раньше программеры у нас работали так. Для выборки есть ряд хранимок, которые параметризированны и возвращают некий результирующий набор данных. В крайнем случае делался прямой SQL запрос к таблицам. С этим какбы все понятно. Но вот для сохранения, изменения и удаления данных приходится программерам (у нас) писать тексты непосредственно в программах. Ну допустим удаление, по цепочке в связанных таблицах, ещё реализовывается в хранимке или на триггерах, а вот уйти от прямого доступа к таблицам при инсерте или упдейте не получилось пока. Так вот. Хотелось бы как-то избавить программистов от надобности знать все структуры при добавлении данных в кучу связанных таблиц. Предложить им подход на уровне документа. Типа они знают, что есть документ такойто и в нем есть такието реквизиты и чтоб добавить этот документ с реквизитами, нужно вызвать процедуру с параметрами. При этом процедура сама разбросает данные по нужным таблицам и при этом возможно в рамках одной транзакции. (бывают у нас моменты, когда номера документов пропадают, а документа нет т.к. номер генерится отдельно, а потом по какойто причине не отрабатывает сохранение основного документа с сгенерированным номером). Точно такимже макаром должно и упдэйт проходить. Только вот возникает вопрос с поддержкой совместимости. А именно, в процессе эксплуатации будет меняться технология и часть переменнох может оказаться не нужной, часть добавится и вообще очередность их может изменится. Т.е. должна быть процедурка с переменным количеством параметров и не зависимым от очередности. Что посоветуете?
Заранее в процедуре получать все возможные параметры, а в случае их отсутствия либо заменять дефолтными либо генерировать ошибку? Или может есть ещё какие решения? Чтоб не изобретать велосипеды. У меня была ещё мысль сделать для этого типа временную табличку (табличек таких может быть много под разные наборы данных) и в неё инсертом передавать. Типа снандартной командой SQL с перечислением заполняемых реквизитов и с их значением, а уже потом триггером на инсерте разбирать полученные данные и распихивать по нужным табличкам и потом удалять запись. Но опять таки.. там есть ограничения на триггерах... чот может не заработать как хотелось бы.
...
Рейтинг: 0 / 0
23.02.2011, 17:56
    #37132468
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
jabЧтоб не изобретать велосипеды. Чтобы не изобретать велосипеды, читай про трех-звенную архитектуру: http://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture
Вопрос относится к топику Проектирования БД а не Sybase.
...
Рейтинг: 0 / 0
23.02.2011, 19:00
    #37132536
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
jabНо вот для сохранения, изменения и удаления данных приходится программерам (у нас) писать тексты непосредственно в программах. Ну допустим удаление, по цепочке в связанных таблицах, ещё реализовывается в хранимке или на триггерах, а вот уйти от прямого доступа к таблицам при инсерте или упдейте не получилось пока.


Что мешает ? для каждой таблицы - 3 процедуры CUD + 1 на чтение = 4. Пишутся легко, генерируются тоже легко.

jabТак вот. Хотелось бы как-то избавить программистов от надобности знать все структуры при добавлении данных в кучу связанных таблиц. Т.е. должна быть процедурка с переменным количеством параметров и не зависимым от очередности.


От очерёдности параметры и так не зависят, если их передавать по имени. А переменное число параметров не понятно зачем вам нужно. Таблиц с переменным числом полей не бывает.

jabЧто посоветуете?


Писать процедуры. А ещё лучше -- генерировать автоматом.
Проблем ваших в упор не понимаю.
...
Рейтинг: 0 / 0
24.02.2011, 12:16
    #37133413
jab
jab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
авторЧто мешает ? для каждой таблицы - 3 процедуры CUD + 1 на чтение = 4. Пишутся легко, генерируются тоже легко.
А можно простой пример из двух таблиц из трех полей?

авторА переменное число параметров не понятно зачем вам нужно. Таблиц с переменным числом полей не бывает.
Например сегодня у меня 2 таблицы всего. В одной 2 поля (id1 + name), во второй 4 поля (id2 + id1 + caption + vid). Написана процедура в которую надо передать 3 параметра (name + caption + vid), которая раскидает записи в эти две таблицы (это примитив, на самом деле может и id1 надо передавать, если я хочу добавить много записей caption + vid). Так вот. Завтра я решил удалить поле vid из таблицы за ненадобностью и переписать процедуру убрав из её параметров vid. Интерфейс не придется переделывать? Можно конечно параметр оставить в процедуре, но больше не использовать его... В общем да, варианты есть и по идее ошибку не должен давать, если передаю именованый параметр которого нет... не попробовал ещё.

авторПисать процедуры. А ещё лучше -- генерировать автоматом.
По поводу генерации автоматом эт как?
...
Рейтинг: 0 / 0
24.02.2011, 12:26
    #37133446
Alexandr Nikolaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
CREATE GLOBAL TEMPORARY TABLE "DBA"."PROC_PARAM_VALUE" (
  "PROC_NAME" long varchar NOT NULL DEFAULT '',
  "PARAM_NAME" long varchar NOT NULL DEFAULT '',
  "PARAM_VALUE" long varchar NOT NULL DEFAULT '',
  "PARAM_TYPE" integer NOT NULL DEFAULT  0 ,
  CONSTRAINT "PROC_PARAM_VALUE_PK" PRIMARY KEY ( "PROC_NAME", "PARAM_NAME" )
) NOT TRANSACTIONAL;
Код: 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.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
CREATE PROCEDURE "DBA"."PROC_PARAM_VALUE_SET"
(
  in @PROC_NAME long varchar DEFAULT '',
  in @PARAM_NAME long varchar DEFAULT '',
  in @PARAM_VALUE long varchar DEFAULT '',
  in @PARAM_TYPE integer DEFAULT  10 
)
RESULT(MSG long varchar)
BEGIN
/*
description
*/
  -- comment
  declare @msg long varchar;
  declare @param_exists integer;
  declare @string_delimiter char;
  -- comment
  set @msg = '';
  set @param_exists =  0 ;
  set @string_delimiter = ',';
  -- comment
  set @PROC_NAME = ISNULL(@PROC_NAME, '');
  set @PARAM_NAME = ISNULL(@PARAM_NAME, '');
  set @PARAM_VALUE = ISNULL(@PARAM_VALUE, '');
  set @PARAM_TYPE = ISNULL(@PARAM_TYPE,  10 );
  if (@msg = '') and (@PROC_NAME = '') then
    set @msg = STRING('Procedure name is empty.');
  end if;
  -- comment
  if (@msg = '') and (@PROC_NAME = '') then
    set @msg = STRING('Parameter name is empty.');
  end if;
  -- comment
  if (@msg = '') then
    -- comment
    if exists(select  1  from DBA.PROC_PARAM_VALUE where PROC_NAME = @PROC_NAME and PARAM_NAME = @PARAM_NAME) then
      set @param_exists =  1 ;
    end if;
    -- comment
    case @PARAM_TYPE
      -- string
      when  10  then
        -- check @PARAM_VALUE

       -- strings
      when  11  then
        -- check @PARAM_VALUE
        if (@param_exists =  1 ) then
          select STRING(PARAM_VALUE, @string_delimiter, @PARAM_VALUE) into @PARAM_VALUE from DBA.PROC_PARAM_VALUE where PROC_NAME = @PROC_NAME and PARAM_NAME = @PARAM_NAME;
          set @PARAM_VALUE = ISNULL(@PARAM_VALUE, '');
        end if;

      -- integer
      when  20  then
        -- check @PARAM_VALUE

      -- decimal
      when  30  then
        -- check @PARAM_VALUE
      else
        set @msg = STRING('Invalid parameter type.');
    end case;
  end if;
  -- comment
  if (@msg = '') then
    if (@param_exists =  0 ) then
      insert into DBA.PROC_PARAM_VALUE ("PROC_NAME", "PARAM_NAME", "PARAM_VALUE", "PARAM_TYPE") values(@PROC_NAME, @PARAM_NAME, @PARAM_VALUE, @PARAM_TYPE);
    else
      update DBA.PROC_PARAM_VALUE set PARAM_VALUE = @PARAM_VALUE where PROC_NAME = @PROC_NAME and PARAM_NAME = @PARAM_NAME;
    end if;
  end if;
  -- comment
  select @msg as MSG;
END;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE PROCEDURE "DBA"."PROC_PARAM_VALUE_DEL"
(
  in @PROC_NAME long varchar DEFAULT '',
  in @PARAM_NAME long varchar DEFAULT ''
)
BEGIN
  set @PROC_NAME = ISNULL(@PROC_NAME, '');
  set @PARAM_NAME = ISNULL(@PARAM_NAME, '');
  if (@PROC_NAME <> '') then
    if (@PARAM_NAME <> '') then
      delete from DBA.PROC_PARAM_VALUE where PROC_NAME = @PROC_NAME and PARAM_NAME = @PARAM_NAME;
    else
      delete from DBA.PROC_PARAM_VALUE where PROC_NAME = @PROC_NAME;
    end if;
  else
    delete from DBA.PROC_PARAM_VALUE;
  end if;
END;
Код: 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.
CREATE PROCEDURE "DBA"."PROC_PARAM"
(
)
BEGIN
  --
  declare @string_value long varchar;
  declare @strings_value long varchar;
  declare @integer_value integer;
  declare @decimal_value decimal( 127 ,  67 );
  --
  select PARAM_VALUE into @string_value from DBA.PROC_PARAM_VALUE where PROC_NAME = 'PROC_PARAM' and PARAM_NAME = 'STRING';
  select PARAM_VALUE into @strings_value from DBA.PROC_PARAM_VALUE where PROC_NAME = 'PROC_PARAM' and PARAM_NAME = 'STRINGS';
  select PARAM_VALUE into @integer_value from DBA.PROC_PARAM_VALUE where PROC_NAME = 'PROC_PARAM' and PARAM_NAME = 'INTEGER';
  select PARAM_VALUE into @decimal_value from DBA.PROC_PARAM_VALUE where PROC_NAME = 'PROC_PARAM' and PARAM_NAME = 'DECIMAL';
  --
  set @string_value = ISNULL(@string_value, '');
  set @strings_value = ISNULL(@strings_value, '');
  set @integer_value = ISNULL(@integer_value,  0 );
  set @decimal_value = ISNULL(@decimal_value,  0 . 0 );
  --
  select
    @string_value as STRING_VALUE,
    @strings_value as STRINGS_VALUE,
    @integer_value as INTEGER_VALUE,
    @decimal_value as DECIMAL_VALUE;
END;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
BEGIN
COMMIT;
  --
  call PROC_PARAM_VALUE_DEL();
  --
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'STRING', 'DEF');
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'STRINGS', 'A',  11 );
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'STRINGS', 'AB',  11 );
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'STRINGS', 'ABC',  11 );
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'INTEGER', '12345',  20 );
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'DECIMAL', '12345.54321',  30 );
  call PROC_PARAM_VALUE_SET('PROC_PARAM', 'STRING', 'ABC');
  --
  call PROC_PARAM();
  --
COMMIT;
END
...
Рейтинг: 0 / 0
24.02.2011, 12:39
    #37133483
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
jabНапример сегодня у меня 2 таблицы всего.

В одной 2 поля (id1 + name), во второй 4 поля (id2 + id1 + caption + vid).

Написана процедура в которую надо передать 3 параметра (name + caption + vid), которая раскидает записи в эти две таблицы (это примитив, на самом деле может и id1 надо передавать, если я хочу добавить много записей caption + vid).


Надо писать ДВЕ ПРОЦЕДУРЫ. По процедуре на каждую таблицу.

1-ая процедура

create procedure create_t1 @id1 u_ID output, @name u_NAME as ...

2-ая процедура

create procedure create_t2 @id1 u_ID, @id2 u_ID output, @caption u_CAPTION, @vid u_VID as ...



jabТак вот. Завтра я решил удалить поле vid из таблицы за ненадобностью и переписать процедуру убрав из её параметров vid. Интерфейс не придется переделывать?


Не думайте об этом. Проектируйте свою БД грамотно с точки зрения предметной области, и всё будет хорошо.
А если что-то будет меняться, вам придётся менять не только это, а и много чего другого.

Но простые модификации типа убрать поле тем не менее вполне можно делать легко.

jab Можно конечно параметр оставить в процедуре, но больше не использовать его... В общем да, варианты есть и по идее ошибку не должен давать, если передаю именованый параметр которого нет... не попробовал ещё.

авторПисать процедуры. А ещё лучше -- генерировать автоматом.
По поводу генерации автоматом эт как?


По метаданным БД или системы, их всё равно описывать надо или они уже есть.
Берёшь метаданные БД или системы, назначение процедуры, (C|R|U|D) и генерируете.
...
Рейтинг: 0 / 0
24.02.2011, 12:40
    #37133485
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
[quot Alexandr Nikolaev]
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
CREATE GLOBAL TEMPORARY TABLE "DBA"."PROC_PARAM_VALUE" (
  "PROC_NAME" long varchar NOT NULL DEFAULT '',
  "PARAM_NAME" long varchar NOT NULL DEFAULT '',
  "PARAM_VALUE" long varchar NOT NULL DEFAULT '',
  "PARAM_TYPE" integer NOT NULL DEFAULT  0 ,
  CONSTRAINT "PROC_PARAM_VALUE_PK" PRIMARY KEY ( "PROC_NAME", "PARAM_NAME" )
) NOT TRANSACTIONAL;

Самое идиотское решение. Глупее ничего быть не может.
...
Рейтинг: 0 / 0
24.02.2011, 12:44
    #37133492
Alexandr Nikolaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
MasterZivСамое идиотское решение. Глупее ничего быть не может.
А обосновать забыли?
...
Рейтинг: 0 / 0
24.02.2011, 13:32
    #37133611
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
On 24.02.2011 12:44, Alexandr Nikolaev wrote:

> А обосновать забыли?

А надо что ли ? По-моему всё очевидно.

Одно

"PARAM_VALUE" long varchar NOT NULL DEFAULT '',


select PARAM_VALUE into @string_value from DBA.PROC_PARAM_VALUE where PROC_NAME
= 'PROC_PARAM' and PARAM_NAME = 'STRING';


чего стоит. Нарушение доменной целостности данных с далеко идущими последствиями.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
24.02.2011, 14:26
    #37133738
Alexandr Nikolaev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
MasterZivчего стоит. Нарушение доменной целостности данных с далеко идущими последствиями.
Если значение параметра для процедуры с клиента на сервер передаётся посредством процедуры ("PROC_PARAM_VALUE_SET")
которая проверяет значение на допустимость("-- check @PARAM_VALUE") и если что не так то возвращает сообщение об ошибке или кидает исключение.
Если значение параметра допустимо, то записывает в таблицу ("PROC_PARAM_VALUE").
Далее вызывается процедура ("PROC_PARAM"), читает значения необходимых ей параметров и делает что нужно, вот тут уже и будет "доменная целостность", всё что выше бизнес(пользовательская) целостность.
Где нарушение доменной целостности?
...
Рейтинг: 0 / 0
24.02.2011, 14:53
    #37133794
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов в пранимой процедуре
On 24.02.2011 14:26, Alexandr Nikolaev wrote:

> Где нарушение доменной целостности?

Одно преобразование в строку -- уже нарушение доменной целостности.
Правда, не на всех типах это будет приводить к катастрофическим последствиям.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Переменное число аргументов в пранимой процедуре / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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