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

Например:
Код: 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
30.12.2008, 15:11
    #35741649
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
ASE 12.5
...
Рейтинг: 0 / 0
30.12.2008, 15:55
    #35741764
komrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
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
30.12.2008, 16:23
    #35741833
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
чтоб не ходить вокруг да около
Код: 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
30.12.2008, 16:41
    #35741878
up
up
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
Вообще-то можно делать так:

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

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

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

Таким образом, один раз выполняя запрос, делаем 2 действия (и обновляем значение в таблице и в переменную его сохраняем).
да, наверное..
но вот мой код зараза возвращает не то что надо и не могу понять почему...
...
Рейтинг: 0 / 0
30.12.2008, 16:54
    #35741898
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
другими словами у меня происходит глюк когда срабатывает условие о обнулениии
Код: 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
30.12.2008, 22:08
    #35742176
maxATC
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
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
30.12.2008, 23:24
    #35742223
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
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
30.12.2008, 23:29
    #35742226
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
т.е. тогда когда надо чтоб сработал IF, получается что сначала он берет старое значение (его и возвращает), затем делает IF, затем увеличивает на один.
А надо в таком порядке:
- IF
- select @nnumber
- update nsi_numb set nnumber+1 where ....

и возвратить мне @nnumber
...
Рейтинг: 0 / 0
31.12.2008, 00:15
    #35742251
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
Код: 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
31.12.2008, 11:18
    #35742513
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
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
31.12.2008, 18:09
    #35742830
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
Imperousработает как надо, только чуток подправилНу да, переменную я объявить забыл...
А вот в BEGIN/END тело процедуры прятать не обязательно. TransactSQL этого не требует.
...
Рейтинг: 0 / 0
05.01.2009, 11:50
    #35744615
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
поторопился я... :(
и опять немного дописал

Код: 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
05.01.2009, 12:13
    #35744633
Imperous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
потестил и снова исправил :)
...
Рейтинг: 0 / 0
09.01.2009, 15:56
    #35748834
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура Update + select
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
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Процедура Update + select / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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