powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Процедура Update + select
16 сообщений из 16, страница 1 из 1
Процедура Update + select
    #35741632
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго всем дня!
Написал процедурку которая тупо увеличивает число.

Например:
Код: plaintext
1.
2.
3.
4.
select @ret = (select ret from tab1)
update tab1 set ret = @ret +  1 
select @ret = (select ret from tab1)

return @ret

допустим в таблице ret = 4
считываю ret = 4
обновляю ret на 5
теперь должно считывать ret = 5

и вернуть мне 5, но возвращает 4
почему?
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741649
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASE 12.5
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741764
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ImperousASE 12.5

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table tst (i int)
go
insert into tst select  1 
go

declare @ret int
select @ret = (select i from tst)
select @ret
update tst 
    set i = @ret +  1 
select @ret = (select i from tst)
select @ret
go


результат



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
1 row(s) affected.

1
   

1 row(s) affected.
1 row(s) affected.

2

select @@version

Adaptive Server Enterprise/12.5.3/EBF 12869 ESD#4/P/Sun_svr4/OS 5.8/ase1253/1923/64-bit/FBO/Thu Sep 8 16:05:41 2005
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741833
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чтоб не ходить вокруг да около
Код: 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.
CREATE PROCEDURE dbo.id_num; 1  

  @ctable char( 15 ),@cfield char( 20 )

AS     

     declare @nnumber int
     declare @curdate date
     declare @dat_start date
     declare @period char( 1 ) 
  

BEGIN  
/* ищем текущий номер */
   select nnumber from nsi_numb where ctable=@ctable and cfield=@cfield
/* ищем текущий номер */

/* если нет такой записи, то создаем со значением 1 */
   if @@rowcount =  0  
       insert into nsi_numb (ctable,cfield,nnumber,dat_mode,note)
       values (@ctable,@cfield, 1 ,getdate(),"Идентификатор")  
/* если нет такой записи, то создаем со значением 1 */

/* проверяем надо ли обнулить и обнуляем если надо */
select @curdate = getdate()
select @dat_start = (select dat_start from nsi_numb where ctable=@ctable and cfield=@cfield)

if (@dat_start <= @curdate and @dat_start is not null)
    begin
        select @period = (select period from nsi_numb where ctable=@ctable and cfield=@cfield)
            if upper(@period) = 'Y'
                begin
                    update nsi_numb set dat_start = dateadd(year,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield                    
                 end
                
            if upper(@period) = 'M'
                begin
                    update nsi_numb set dat_start = dateadd(month,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
            if upper(@period) = 'W'
                begin
                    update nsi_numb set dat_start = dateadd(week,  1 , @dat_start),nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
            if upper(@period) = 'D'
                begin
                    update nsi_numb set dat_start = dateadd(day,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
    end
/* проверяем надо ли обнулить и обнуляем если надо */


select @nnumber = (select nnumber from nsi_numb where ctable=@ctable and cfield=@cfield)
update nsi_numb set nnumber=@nnumber+ 1 ,dat_mode=getdate() where ctable=@ctable and cfield=@cfield 

END 

select @nnumber
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741878
up
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то можно делать так:

update ... set col_name=col_name + 1, @var=col_name+1 where ...

Таким образом, один раз выполняя запрос, делаем 2 действия (и обновляем значение в таблице и в переменную его сохраняем).
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741883
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
upВообще-то можно делать так:

update ... set col_name=col_name + 1, @var=col_name+1 where ...

Таким образом, один раз выполняя запрос, делаем 2 действия (и обновляем значение в таблице и в переменную его сохраняем).
да, наверное..
но вот мой код зараза возвращает не то что надо и не могу понять почему...
...
Рейтинг: 0 / 0
Процедура Update + select
    #35741898
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
другими словами у меня происходит глюк когда срабатывает условие о обнулениии
Код: 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.
if (@dat_start <= @curdate and @dat_start is not null)
    begin
        select @period = (select period from nsi_numb where ctable=@ctable and cfield=@cfield)
            if upper(@period) = 'Y'
                begin
                    update nsi_numb set dat_start = dateadd(year,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield                    
                 end
                
            if upper(@period) = 'M'
                begin
                    update nsi_numb set dat_start = dateadd(month,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
            if upper(@period) = 'W'
                begin
                    update nsi_numb set dat_start = dateadd(week,  1 , @dat_start),nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
            if upper(@period) = 'D'
                begin
                    update nsi_numb set dat_start = dateadd(day,  1 , @dat_start), nnumber= 1 ,dat_mode=getdate() 
                    where ctable=@ctable and cfield=@cfield
                 end
                
    end
тут я устанавливаю значение в единицу, мне его в итоге надо вернуть и увеличить на 1
Код: plaintext
1.
select @nnumber = (select nnumber from nsi_numb where ctable=@ctable and cfield=@cfield)
update nsi_numb set nnumber=@nnumber+ 1 ,dat_mode=getdate() where ctable=@ctable and cfield=@cfield 
но вместо единицы, мне возвращается старое значение которое было в поле nnumber
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742176
maxATC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Imperous,

select @nnumber = (select nnumber from nsi_numb where ctable=@ctable and cfield=@cfield
Присвоили значение из базы (старое значение)
update nsi_numb set nnumber=@nnumber+1,dat_mode=getdate() where ctable=@ctable and cfield=@cfield
Записали в nnumber это @nnumber+1

select @nnumber - выбрали значение переменной
но nnumber=@nnumber+1 не @nnumber=@nnumber+1 т.е саму переменную не увеличил
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742223
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maxATCImperous,

select @nnumber = (select nnumber from nsi_numb where ctable=@ctable and cfield=@cfield
Присвоили значение из базы (старое значение)
update nsi_numb set nnumber=@nnumber+1,dat_mode=getdate() where ctable=@ctable and cfield=@cfield
Записали в nnumber это @nnumber+1

select @nnumber - выбрали значение переменной
но nnumber=@nnumber+1 не @nnumber=@nnumber+1 т.е саму переменную не увеличил
в том то и дело, что мне надо вытянуть единицу, а затем ее увеличить в базе, затем очередное чтение из базы - он вытягивает двойку, возвращает ее, и после увеличивает на единицу
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742226
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. тогда когда надо чтоб сработал IF, получается что сначала он берет старое значение (его и возвращает), затем делает IF, затем увеличивает на один.
А надо в таком порядке:
- IF
- select @nnumber
- update nsi_numb set nnumber+1 where ....

и возвратить мне @nnumber
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742251
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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 PROCEDURE dbo.id_num; 1  
  @ctable char( 15 ),@cfield char( 20 )
AS

   /* если нет такой записи, то создаем со значением 1 */
   insert into nsi_numb (ctable,cfield,nnumber,dat_mode,note)
       select @ctable,@cfield, 1 ,getdate(),"Идентификатор"
       where not exist (select * from nsi_numb where ctable=@ctable and cfield=@cfield)

   /* проверяем надо ли обнулить и обнуляем если надо */
   update nsi_numb set nnumber= 1 , dat_mode=getdate(), 
          dat_start = (case upper(period) when 'Y' then dateadd(year,  1 , dat_start)
                                          when 'M' then dateadd(month,  1 , dat_start)
                                          when 'W' then dateadd(week,  1 , dat_start)
                                          else dateadd(day,  1 , dat_start)
                        end)
               where ctable=@ctable and cfield=@cfield and dat_start<=getdate()

   /* берем текущее значение в переменную и увеличиваем значение в поле */
   update nsi_numb set @number=nnumber, nnumber=nnumber+ 1 , dat_mode=getdate() where ctable=@ctable and cfield=@cfield

   /* показываем значение счетчика до увеличения */
    select @number
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742513
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,
ОГРОМНОЕ СПАСИБИЩЕ!!!! работает как надо, только чуток подправил
Код: 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.
CREATE PROCEDURE dbo.id_num; 1  
  @ctable char( 15 ),@cfield char( 20 )
AS
BEGIN
declare @nnumber int 
   /* если нет такой записи, то создаем со значением 1 */
   insert into nsi_numb (ctable,cfield,nnumber,dat_mode,note)
       select @ctable,@cfield, 1 ,getdate(),"Идентификатор"
       where not exists (select * from nsi_numb where ctable=@ctable and cfield=@cfield)

   /* проверяем надо ли обнулить и обнуляем если надо */
   update nsi_numb set nnumber= 1 , dat_mode=getdate(), 
          dat_start = (case upper(period) when 'Y' then dateadd(year,  1 , dat_start)
                                          when 'M' then dateadd(month,  1 , dat_start)
                                          when 'W' then dateadd(week,  1 , dat_start)
                                          else dateadd(day,  1 , dat_start)
                        end)
               where ctable=@ctable and cfield=@cfield and dat_start<=getdate()

   /* берем текущее значение в переменную и увеличиваем значение в поле */
   update nsi_numb set @nnumber=nnumber, nnumber=nnumber+ 1 , dat_mode=getdate() where ctable=@ctable and cfield=@cfield

   /* показываем значение счетчика до увеличения */
    select @nnumber
END

Всех с наступающим!!!!!
...
Рейтинг: 0 / 0
Процедура Update + select
    #35742830
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Imperousработает как надо, только чуток подправилНу да, переменную я объявить забыл...
А вот в BEGIN/END тело процедуры прятать не обязательно. TransactSQL этого не требует.
...
Рейтинг: 0 / 0
Процедура Update + select
    #35744615
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поторопился я... :(
и опять немного дописал

Код: 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.
CREATE PROCEDURE dbo.id_num; 1  
  @ctable char( 15 ),@cfield char( 20 )
AS
BEGIN
declare @nnumber int 
   /* если нет такой записи, то создаем со значением 1 */
   insert into nsi_numb (ctable,cfield,nnumber,dat_mode,note)
       select @ctable,@cfield, 1 ,getdate(),"Идентификатор"
       where not exists (select * from nsi_numb where ctable=@ctable and cfield=@cfield)

   /* проверяем надо ли обнулить и обнуляем если надо */
   update nsi_numb set nnumber= 1 , dat_mode=getdate(), 
          dat_start = (case upper(period) when 'Y' then dateadd(year, datediff(year, dat_start, getdate()) + 1 , dat_start)
                                          when 'M' then dateadd(month, datediff(month, dat_start, getdate()) + 1 , dat_start)
                                          when 'W' then dateadd(week, datediff(week, dat_start, getdate()) + 1 , dat_start)
                                          else dateadd(day, datediff(day, dat_start, getdate()) + 1 , dat_start)
                        end)
               where ctable=@ctable and cfield=@cfield and dat_start<=getdate()

   /* берем текущее значение в переменную и увеличиваем значение в поле */
   update nsi_numb set @nnumber=nnumber, nnumber=nnumber+ 1 , dat_mode=getdate() where ctable=@ctable and cfield=@cfield

   /* показываем значение счетчика до увеличения */
    select @nnumber
END
...
Рейтинг: 0 / 0
Процедура Update + select
    #35744633
Imperous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потестил и снова исправил :)
...
Рейтинг: 0 / 0
Процедура Update + select
    #35748834
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Imperous пишет:
> Автор: "Imperous"
> Доброго всем дня!
> Написал процедурку которая тупо увеличивает число.
>
> Например:
>
> select @ret = (select ret from tab1)
> update tab1 set ret = @ret + *1*

> и вернуть мне 5, но возвращает 4
> почему?

Потому что write skew скорее всего.

Надо писать

Код: plaintext
\nselect @ret = ret from tab1 for update\nupdate tab1 set ret = @ret +  1 \n

или проще
Код: plaintext
\nupdate tab1 set ret = ret +  1 \nselect @ret = ret -  1  from tab1\n

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


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