powered by simpleCommunicator - 2.0.57     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Переменное число аргументов в пранимой процедуре
19 сообщений из 19, страница 1 из 1
Переменное число аргументов в пранимой процедуре
    #32990655
g613
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
День добрый,

ASE 12.5.1

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

Если данной процедуре передается только один парамет (@a), то она считает, что второй равен 50 (@b = 50).
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #32990797
Crip
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавление - вызывать процедуру надо только с именованными параметрами.
Пример:
Create procedure Test (@a int=30, @b int = 50)
Вызов:
exec Test @b = 100
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #32991654
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не бывает в ASE процедур с переменным кол-вом параметров. Есть только возможность не указывать значение какого-то параметра, если у него есть значение по умолчанию.

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

Я в общем то остановился на том, что отписал несколько выше ( то есть с определением числа параметров равное максимально возможному и кучей ИФ'оф ), только громоздко оно несколько смотрится...
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #32992185
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В вызове процедуры по синтаксису в качестве значения параметра может быть только либо константа, либо локальная переменная.
Надо предварительно вычислить значение функции и сохранить ее в переменной, а затем переменную передать в параметр процедуры.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Переменное число аргументов в пранимой процедуре
    #37132285
jab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дабы не плодить похожие темы, решил задать аналогичный вопрос в этой теме. У меня тоже ASE 12.5.4 и тоже подошел момент к тому, что надобы както реорганизовывать подход доступа к данным с стороны программистов. Хотелось бы какимто макаром реализовать следующее. Допустим у меня есть набор некоторых связанных таблиц с данными. Мне нужно из них выбирать, добавлять, изменять, удалять данные. Раньше программеры у нас работали так. Для выборки есть ряд хранимок, которые параметризированны и возвращают некий результирующий набор данных. В крайнем случае делался прямой SQL запрос к таблицам. С этим какбы все понятно. Но вот для сохранения, изменения и удаления данных приходится программерам (у нас) писать тексты непосредственно в программах. Ну допустим удаление, по цепочке в связанных таблицах, ещё реализовывается в хранимке или на триггерах, а вот уйти от прямого доступа к таблицам при инсерте или упдейте не получилось пока. Так вот. Хотелось бы как-то избавить программистов от надобности знать все структуры при добавлении данных в кучу связанных таблиц. Предложить им подход на уровне документа. Типа они знают, что есть документ такойто и в нем есть такието реквизиты и чтоб добавить этот документ с реквизитами, нужно вызвать процедуру с параметрами. При этом процедура сама разбросает данные по нужным таблицам и при этом возможно в рамках одной транзакции. (бывают у нас моменты, когда номера документов пропадают, а документа нет т.к. номер генерится отдельно, а потом по какойто причине не отрабатывает сохранение основного документа с сгенерированным номером). Точно такимже макаром должно и упдэйт проходить. Только вот возникает вопрос с поддержкой совместимости. А именно, в процессе эксплуатации будет меняться технология и часть переменнох может оказаться не нужной, часть добавится и вообще очередность их может изменится. Т.е. должна быть процедурка с переменным количеством параметров и не зависимым от очередности. Что посоветуете?
Заранее в процедуре получать все возможные параметры, а в случае их отсутствия либо заменять дефолтными либо генерировать ошибку? Или может есть ещё какие решения? Чтоб не изобретать велосипеды. У меня была ещё мысль сделать для этого типа временную табличку (табличек таких может быть много под разные наборы данных) и в неё инсертом передавать. Типа снандартной командой SQL с перечислением заполняемых реквизитов и с их значением, а уже потом триггером на инсерте разбирать полученные данные и распихивать по нужным табличкам и потом удалять запись. Но опять таки.. там есть ограничения на триггерах... чот может не заработать как хотелось бы.
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #37132468
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jabЧтоб не изобретать велосипеды. Чтобы не изобретать велосипеды, читай про трех-звенную архитектуру: http://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture
Вопрос относится к топику Проектирования БД а не Sybase.
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #37132536
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jabНо вот для сохранения, изменения и удаления данных приходится программерам (у нас) писать тексты непосредственно в программах. Ну допустим удаление, по цепочке в связанных таблицах, ещё реализовывается в хранимке или на триггерах, а вот уйти от прямого доступа к таблицам при инсерте или упдейте не получилось пока.


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

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


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

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


Писать процедуры. А ещё лучше -- генерировать автоматом.
Проблем ваших в упор не понимаю.
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #37133413
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
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #37133492
Фотография Alexandr Nikolaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivСамое идиотское решение. Глупее ничего быть не может.
А обосновать забыли?
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #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
Переменное число аргументов в пранимой процедуре
    #37133738
Фотография Alexandr Nikolaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivчего стоит. Нарушение доменной целостности данных с далеко идущими последствиями.
Если значение параметра для процедуры с клиента на сервер передаётся посредством процедуры ("PROC_PARAM_VALUE_SET")
которая проверяет значение на допустимость("-- check @PARAM_VALUE") и если что не так то возвращает сообщение об ошибке или кидает исключение.
Если значение параметра допустимо, то записывает в таблицу ("PROC_PARAM_VALUE").
Далее вызывается процедура ("PROC_PARAM"), читает значения необходимых ей параметров и делает что нужно, вот тут уже и будет "доменная целостность", всё что выше бизнес(пользовательская) целостность.
Где нарушение доменной целостности?
...
Рейтинг: 0 / 0
Переменное число аргументов в пранимой процедуре
    #37133794
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 24.02.2011 14:26, Alexandr Nikolaev wrote:

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

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


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