powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / То ли сервер глюкавый, то ли руки кривые... HELP!
20 сообщений из 20, страница 1 из 1
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005091
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется такое вот чудо ... мысли.

CREATE PROCEDURE ЖурналДвижений (@КодФирмы int =4)as
begin
declare @ЖурналРасходов table (КодДвижения int , КодПрихода int , ОстатокПрихода decimal (9, 3) , КоличествоРасхода decimal (9, 3) , ФлагПартии bit )
declare @КодДвижения int , @КоличествоРасхода decimal (9, 3) , @ФлагПартии bit
declare ПереченьРасходов CURSOR FOR
select КодДвижения, КоличествоРасхода=Количество, ФлагПартии
from dbo.ДвиженияПоКорреспонденту(null, @КодФирмы, null, null)
where ТипДвижения<>'Приход'
open ПереченьРасходов
WHILE @@FETCH_STATUS = 0
begin
fetch next from ПереченьРасходов
into @КодДвижения , @КоличествоРасхода , @ФлагПартии
insert into @ЖурналРасходов
select * from dbo.СписаниеFIFOРасходы(@КодДвижения)
end
select * from @ЖурналРасходов
end

Общий смысл в том, что на каждую запись во входном наборе данных функцией СписаниеFIFOРасходы() возвращаеся несколько записей. Обе, использующиеся UDF работают как часы (китайские само собой ).
И я не буду спрашивать почему оно не работает, потому что оно работает и очень хорошо...
Но только один раз.
Т.е на Open или Debug в QA возвращается нормальный набор записей. А
exec ЖурналДвижений default первый раз отрабатывает нормально, а потом возвращает пустой набор .
На клиенте (MSAccess2000 adp) - аналогично.
Такие дела. Может кто чего знает?
P.S. Кириллица используется по настоянию клиента. Да и раньше особых проблем не было.
P.P.S. Тестовый набор в размере 2-х таблиц, двух UDF и сего творения (всего 100kb в архиве) готов сбросить по e-mail любому.
Помогите кто может!!!
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005093
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А deallocate ПереченьРасходов не пробовали делать
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005098
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще циклы с курсорами пишуться чуть по-другому
open ПереченьРасходов
fetch next from ПереченьРасходов
into @КодДвижения , @КоличествоРасхода , @ФлагПартии
WHILE @@FETCH_STATUS = 0
begin
insert into @ЖурналРасходов
select * from dbo.СписаниеFIFOРасходы(@КодДвижения)
fetch next from ПереченьРасходов
into @КодДвижения , @КоличествоРасхода , @ФлагПартии
end

У Вас же получается, что первый раз переменная @@FETCH_STATUS была нуль, затем при выходе из цикла она стала не нулевой и соответственно в цикл больше никогда не войти. Опять же могут быть проблеммы если курсор пустой, а Вы будете думать что считали оттуда одну запись.
Насчет deallocate тоже верно, но мне кажется что при выходе из процедуры они(курсоры) сами должны убиться(но не уверен) и это не должно было влиять.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005117
GreenSunrise
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
После использования курсора надо его явно закрыть и удалить.
close cur1
deallocate cur1

Сам он при выходе из процедуры не удалится.

Правда, при вторичном проходе по open cur1 (без удаления в предыдущем) вывалилась бы ошибка "курсор cur1 уже есть". А вот если молча возвращает пустой набор записей, то дело, скорее всего, не в этом.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005120
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, GreenSunrise прав, конечно
должно быть сообщение об ошибке, не сообразил сразу
хотя считаю что все рано лучше явно все прописывать.
Да и если в рамках одного и того же коннекта вызывалась процедура, ошибка должна быть однозначно, сам по забывчивости нарывался не раз, я правда работаю в основном на семерке, поэтому в качестве источника функцию не использовал.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005138
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых: Большое спасибо всем откликнувшимся.
Во-вторых:
2Genady:
close ПереченьРасходов
deallocate ПереченьРасходов в процедуре само собой были. Это я сократил для читабельности. Видимо напрасно.
В случае незакрытия и неубиения курсора сервер аккуратно выдает сообщение об ошибке. Так что проблема не в этом.
2SergSuper: Теоретически с Вами согласен. Практически, если курсор не пустой, все должно работать. Впрочем Ваш вариант работает точно также т.е. - один раз. Так что проблема и не в этом тоже.
2GreenSunrise and ALL:
>А вот если молча возвращает пустой набор записей, то дело, скорее всего, не в этом.
Дело судя по всему действительно не в этом. Ошибка начала возникать после переустановки сервера и не только в этой процедуре, а во всех процедурах, использующих в теле вызовы UDF . В том числе в тех, которые написаны в точном соответствии с советом SergSuper.
А особая мистика в том, что вновь созданная процедура, дословно повторяющая старую работает нормально. Такие дела.
Судя по всему дело в каких-то установках сервера.
Может у кого есть идеи в каких? А то чего то пересоздавать все SP не очень хочется.
Как все-таки получается, что на Open и Debug в QA одна и та же SP отрабатывет нормально, а на exec начинает фокусничать?
Сталкивался ли кто-либо с подобными вещами, и как боролся?
Еще раз спасибо Всем.
А я продолжу пока эксперимент .
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005140
Moth
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если вместо declare
create table #Tmp1 ()
Insert into #TMP1
Select
...
/* или Построчно */
...
Select * from #tmp1
drop table #tmp1
Moth
P.S.
Если что кидай на мыло /*3 MB*/
moth@mail.primorye.ru
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005142
hermit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У тебя что, все на русском названия таблиц и функций?

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

а мой совет
не пользуйтеся курсорами
лучше перегоняйте во времянку с Identity
а потом пошагово в цикли считывайте записи и изменяйте
больше кода
но зато быстрей и безглючней будет работать

я от таких проблемм избавился когда перестал курсоры юзать...
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005143
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Andrew
В общем дело ясное, что дело темное Попробуйте просто перекомпилить все такие процедуры, ну в общем с моей стороны советы построены на гадании сам с такой проблемой не сталкивался.

2 hermit

Вы полагаете, что если прегонять во временную таблицу и читать потом из нее в цикле быстрее будет? Хм.... Непонятно, непротив услышать объяснение.


Сам всегда полагал, что решение использовать временную таблицу стоит того тогда, когда можно при этом избежать цикла
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005146
hermit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
To Genady

Да, Быстрее....
Не всегда но в большинстве случаев (покрайней мере не медленее)
особенно если в той таблице есть поля которые нужно прообдейтить в зависимости от некоторых факторов.
и полей таких до 10 штук

Это все проверенно на личном опыте
в некоторых местах быстрее в 5-6 раз получалось..

И что самое приятное... намного менее глючней.
У меня 2 года крутится база на 6.5 где с полтора десятка модулей.... около 300 сохраненок
вообщем автоматизированн полностью завод...
и поверь, отчеты довольно сложные есть
везде я обходился без курсоров..
и я уже забыл как сервер выглядит
пото му что к нему не подходил уже давно
все работает ....

а ведь были проблеммы которые были у товарисча который написал в самом первом письме
убрал курсоры, ушли проблеммы...

еще меня правда сумщает названия на русском языке
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005149
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Присоединяюсь. В процедуре собирал данные во временную таблицу курсором в цикле (7.0), но в итоге селект * из временной таблицы ничего не возврашал, хотя записи там точно были! Метод решения - отказ от курсоров. Хотя иногда удавалось завести процедурку, избавевшимь только от части курсоров (вложенные циклы). В общем никакой системы обнаружить не удалось. Microsoft, однако.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005153
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Genady
И я присоединяюсь. Быстрей и безглючней.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005160
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Всем присоеденившимся


То ли народ не понял мой вопрос, то ли я ничего не понимаю
Мне бы хотелось получить обоснование (объяснение) почему цикл на временной таблице быстрее цикла на курсоре?

P.S. Как и все нормальные люди, я тоже избегаю использования курсоров, посему о глюках с ними ничего сказать не могу, не встречал.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005168
Hermit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вот почему быстрей, это я уже не скажу Не знаю
видно при курсорах используется внутри еще что-то, что при больших данных
замедляет общий процесс.... (память выделяет, чегото запоминает для движения по записям..)
в при времянках один TSQL и ничего более
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005170
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>А вот почему быстрей, это я уже не скажу Не знаю

Жаль, тогда остается потестировать
если что нибудь интересное обнаружу - сообщу.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005188
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 всем присоеденившимся

Ребята, вы ничего не путаете?

Создал таблицу create table table3 (id int identity(1,1), name varchar(50))
загнал в нее 100000 записей и написал две процедуры
со временной таблицей

CREATE PROCEDURE test3t AS

begin
declare @vI int,
@stop int
create table #test (tempkey int identity(1,1), oldkey int, field varchar(50))
set @stop = @@identity
set @vI = 1
insert into #test select * from table3 where id between 20000 and 50000

while @vI <= @stop
begin
select field from #test where tempkey = @vI
set @vI = @vI + 1
end
drop table #test
end

и с курсором

CREATE PROCEDURE test3c AS
begin
declare @tempname varchar(50)
declare tempcur cursor for select name from table3 where id between 20000 and 50000

open tempcur

fetch next from tempcur into @tempname
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @tempname
fetch next from tempcur into @tempname

END
close tempcur
deallocate tempcur
end

Время выполнения test3t - 11 мин 26 сек
Время выполнения test3c - 0 мин 22 сек

Затем модифицировал test3t добавил первичный ключ во временную таблицу - время выполнения - 0:40
т.е. все равно медленней!!!!!!!
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005196
Если ты используешь конструкцию типа

CREATE FUNCTION fncTest()
RETURNS @tbTable TABLE
( Field int PRIMARY KEY )
AS
BEGIN
INSERT @tbTable
SELECT
SrcField
FROM
tbSrcTable
RETURN
END

То советую попробовать с такой конструкцией

CREATE FUNCTION fncTest()
RETURNS TABLE
RETURN(
SELECT
SrcField
FROM
tbSrcTable
)

С первой у меня были проблемы с кол-вом возвращаемых записей

Удачи
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005249
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Genady:
Если сделать вложенную процедуру, то результат:

TextData CPU Reads Writes Duration
exec aaa_test1 2547 87531 0 13436
exec aaa_test2 2875 108085 0 12716

Т.е. разницы нет, но при использовании вр. таблиц иногда можно делать обработку не построчно, меньше глюков и т.д.

drop PROCEDURE aaa_test1
drop PROCEDURE aaa_test11
drop PROCEDURE aaa_test2
go
CREATE PROCEDURE aaa_test11
WITH RECOMPILE
AS

declare @vI int
declare @tempname varchar(50)

set @vI = 1

while 1=1
begin
select @tempname = field from #test where tempkey = @vI
if @@rowcount = 0 break
PRINT @tempname
set @vI = @vI + 1
end
go

CREATE PROCEDURE aaa_test1
AS

declare @vI int, @stop int
declare @tempname varchar(50)

create table #test (
tempkey int identity(1,1) primary key clustered,
oldkey int,
field varchar(50)
)

insert into #test(oldkey, field)
select ctID, Code from tblCatalog

exec aaa_test11

drop table #test
go

--и с курсором

CREATE PROCEDURE aaa_test2
AS

declare @tempname varchar(50)
declare tempcur cursor for select Code from tblCatalog

open tempcur

fetch next from tempcur into @tempname
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @tempname
fetch next from tempcur into @tempname

END
close tempcur
deallocate tempcur
go
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005252
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 alexeyvg
>но при использовании вр. таблиц иногда можно делать обработку не построчно

Так я с этим не спорю, я не поверил, что цикл на временной таблице быстрее курсора, и как видите не зря.
...
Рейтинг: 0 / 0
То ли сервер глюкавый, то ли руки кривые... HELP!
    #32005902
Andrew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем большое спасибо.
Главное заинтересовать общественность и уехать в командировку .
После неоднократных перустановок сервера и перекомпиляции процедур все заработало. Почему заработало определить не удалось. Воспроизвести ошибку на другом сервере не удалось так же. Жаль. Ну да ладно.
Подкину еще один интересный момент, имеющий отношение, как к выбору между переменными типа table и временными таблицами, так и к мистике, исполняемой иногда сервером. Итак:

CREATE procedure Numbers_p (@n bigint = 100000)
as
begin
declare @m bigint
declare @Table table (i bigint , k bigint)
set @m=0
while @m<@n
begin
set @m=@m+1
insert into @Table values (@m , @m)
end
select * from @Table
end

или так:

CREATE procedure Numbers_vr (@n bigint = 100000)
as
begin
declare @m bigint
create table #Table (i bigint , k bigint)
set @m=0
while @m<@n
begin
set @m=@m+1
insert into #Table values (@m , @m)
end
select * from #Table
end

Во первых работает быстрее на разных машинах то первый вариант, то второй (от чего зависит так и не понял). Но чаще первый быстрее (в среднем на 20-30%), оно и понятно, если памяти хватает, то таблицы-переменные по идее должны работать быстрее. А вот если оперетивки не хватает, да процессор слабый, да файл подкачки маловат и увеличивается по ходу выполнения процедуры, то запросто можно получить 100 000 записей, последняя из которых будет не 100000, 100000 , а например 99992, 99992. Я неоднократно воспроизводил подобное у клиентов на "серверах" типа Celeron 366, 64 MB, особенно если минимальный размер файла подкачки не увеличить заранее. Можно конечно иронизировать по поводу конфигурации машины. Но во-первых, чего еще нужно на рабочую группу из 5 пользователей? Во-вторых, если серверу не хватает ресурсов, IMHO, он должен об этом сообщить, а не выдавать после 4 минут работы неверный результат. Или может я чего неверно понимаю? Главное не понятно, как бороться с подобными вещами.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / То ли сервер глюкавый, то ли руки кривые... HELP!
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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