powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временные таблицы или что другое...
2 сообщений из 2, страница 1 из 1
Временные таблицы или что другое...
    #32005771
AlexUnik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем! У меня маленький вопрос - можно-ли использовать временные таблицы в процедуре, к которой будет в дальнейшем одновременно обращаться большое количество пользователей? Поясняю-иногда в эти временные таблицы кидается до 100 000 и более записей...
...
Рейтинг: 0 / 0
Временные таблицы или что другое...
    #32005772
AlexUnik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К своему вопросу привожу пример процедуры расчета остатков, только не судите слишком строго - делал наспех. Так следует ли использовать временные таблицы или можно обойтись без них? (У меня SQL.7)
CREATE PROCEDURE add_new_ost_03 (@base_s smallint, @date_1 smalldatetime, @date_en smalldatetime ) AS

--пересчет остатков за период, используется в форме пересчета остатков и в документах при активизации списка "Состояние"

DELETE FROM ostatok WHERE base_id=@base_s AND date >= @date_1

SET NoCount ON
DECLARE @det_s int
DECLARE @det_is int
DECLARE @cnt_det_max int -- qwontity records in cursor 'cur_detail'
DECLARE @cnt_det_tec int -- number of current record for cursor 'cur_detail'
DECLARE @det_ost int -- oaeouee inoaoie
DECLARE @det_qw int -- qwontity
DECLARE @det_qw_tec int -- current qwontity
DECLARE @det_sum float -- summa
DECLARE @det_sum_tec float -- current summa
DECLARE @dt_type smallint -- doc_type
DECLARE @dt_tec smalldatetime -- current date
DECLARE @dt_tec_1 smalldatetime
DECLARE @dt_tec_p smalldatetime
DECLARE @tim datetime
DECLARE @sc int

--Таймер
select @tim=getdate()
select 'Timer_start' = @tim
select @sc=0

--Временная таблица для остатка
create table #OST_VREM (base_id smallint, date smalldatetime, detail_id int, ostatok int, price_uchet float, last tinyint)

--Временная таблица для учетной цены
create table #OST_UCH (base_id smallint, date smalldatetime, detail_id int, price_uchet float)

--Наполнение временной таблицы движения из doc_records
create table #dvig (detal int null, data smalldatetime, type smallint, qw int null, summ float)
insert into #dvig
SELECT d_r.detail_id, d.doc_date_1, d.doc_type, SUM(d_r.detail_qwont), SUM(d_r.detail_qwont * d_r.detail_price)
FROM docs d, doc_records d_r
WHERE d.base_id=d_r.base_id AND d.base_id= @base_s AND d.doc_id=d_r.doc_id AND (d.doc_type IN (102, 105, 106, 202, 204, 205))
AND d.doc_date_1 BETWEEN @date_1 AND @date_en
GROUP BY d_r.detail_id, d.doc_date_1, d.doc_type

--Проверочный вывод в таблицу (по записям в данной таблице можно судить о расчете т.к. она является единственной в курсоре движения)
truncate table dvig
insert into dvig
SELECT d_r.detail_id, d.doc_date_1, d.doc_type, SUM(d_r.detail_qwont), SUM(d_r.detail_qwont * d_r.detail_price)
FROM docs d, doc_records d_r
WHERE d.base_id=d_r.base_id AND d.base_id= @base_s AND d.doc_id=d_r.doc_id AND (d.doc_type IN (102, 105, 106, 202, 204, 205))
AND d.doc_date_1 BETWEEN @date_1 AND @date_en
GROUP BY d_r.detail_id, d.doc_date_1, d.doc_type

--Что-то не получается с видами! (А вообще следует использовать виды в данном случае для избежания конфликтов блокировок и переполнения)
--if exists (select * from sysobjects where id = object_id('ost') and sysstat & 0xf = 2) drop view ost
--if exists (select * from sysobjects where id = object_id('ostatok_dat') and sysstat & 0xf = 2) drop view ostatok_dat

--EXEC ('Create view ost AS SELECT base_id, detail_id, date FROM ostatok
--WHERE date= "+CONVERT(DATETIME, @date_1, 102)+" base_id =" + @base_s+") ' )

--EXEC ('Create view ostatok_dat as select base_id, detail_id, MAX(date) AS Max_dat
--FROM ost GROUP BY detail_id, base_id')

--Заполнение таблицы дат
create table #ost (base_id smallint, detail_id int null, date smalldatetime)
insert into #ost
SELECT base_id, detail_id, date FROM ostatok
WHERE date<@date_1 and base_id = @base_s

--Выборка последней даты остатка по каждой ТМЦ
create table #ostatok_dat (base_id smallint, detail_id int null, Max_dat smalldatetime)
insert into #ostatok_dat
select base_id, detail_id, MAX(date) AS Max_dat
FROM #ost GROUP BY detail_id, base_id

--Наполнение временной таблицы движения из остатков для ориентации на начальный приход
insert into #dvig
SELECT ostatok.detail_id, #ostatok_dat.Max_dat, 102 AS type, ostatok.ostatok, ostatok.price_uchet
FROM ostatok JOIN #ostatok_dat ON ostatok.base_id = #ostatok_dat.base_id AND ostatok.detail_id = #ostatok_dat.detail_id AND ostatok.date = #ostatok_dat.Max_dat

--Далее заполняем проверочную таблицу остатками, но тип остатка делаем =111 для сравнения
insert into dvig
SELECT ostatok.detail_id, #ostatok_dat.Max_dat, 111 AS type, ostatok.ostatok, ostatok.price_uchet
FROM ostatok JOIN #ostatok_dat ON ostatok.base_id = #ostatok_dat.base_id AND ostatok.detail_id = #ostatok_dat.detail_id AND ostatok.date = #ostatok_dat.Max_dat
--Конец заполнения

--Удаление тех остатков, которые запишутся заново-если не удалять то надо оформлять их не приходом (поле ost)
DELETE FROM ostatok
FROM ostatok JOIN #ostatok_dat ON ostatok.base_id = #ostatok_dat.base_id AND ostatok.detail_id = #ostatok_dat.detail_id AND DATE=#ostatok_dat.Max_dat

--Таймер
--select 'Timer_vrem' = getdate()-@tim

--Курсор по деталям
DECLARE cur_dvig CURSOR
FOR SELECT detal, data, type, qw, summ
FROM #dvig
ORDER BY detal, data, type
FOR READ ONLY

OPEN cur_dvig

--Таймер
--select 'Timer_curs' = getdate()-@tim

FETCH cur_dvig INTO @det_s , @dt_tec, @dt_type, @det_qw, @det_sum
SELECT @det_is = 0
SELECT @det_sum_tec = 0
SELECT @det_qw_tec = 0
SELECT @dt_tec_1 = @dt_tec

WHILE @@FETCH_STATUS = 0

--Начало цикла курсора
BEGIN

--SELECT 'Begin-detail_id_tec' = @det_s, 'detail_id' = @det_Is

If (@det_is<>@det_s)
BEGIN
SELECT @det_is = @det_s
SELECT @det_sum_tec = 0
SELECT @det_qw_tec = 0
SELECT @dt_tec_1 = @dt_tec
END

IF (@dt_type < 200)
BEGIN
SELECT @det_qw_tec = isnull(@det_qw_tec,0) + isnull(@det_qw,0)
SELECT @det_sum_tec = isnull(@det_sum_tec,0) + isnull(@det_sum,0)
--SELECT 'Prihod-detail_id' = @det_s, 'kw' = @det_qw_tec
END
ELSE

--Данные теряются в случае если расход внесен первым или приход<расхода
IF isnull(@det_qw_tec,0)<= 0
BEGIN
SELECT @det_qw_tec = 0
SELECT @det_sum_tec = 0
END
ELSE
BEGIN
--Занесение средневзв учетной цены
INSERT INTO #OST_UCH (base_id, date, detail_id, price_uchet)
values (@base_s, @dt_tec, @det_s, ROUND(@det_sum_tec/@det_qw_tec,2))

SELECT @det_sum_tec = @det_sum_tec - (@det_sum_tec*@det_qw)/@det_qw_tec
SELECT @det_qw_tec = ISNULL(@det_qw_tec,0) - ISNULL(@det_qw,0)
--SELECT 'Rashod-detail_id' = @det_s, 'kw' = @det_qw_tec
END

--select 'Timer_curs1' = getdate()-@tim
SELECT @dt_tec_p = @dt_tec
FETCH cur_dvig INTO @det_s , @dt_tec, @dt_type, @det_qw, @det_sum
--SELECT 'NEW-dt_tec_1' = @dt_tec_1, 'dt_tec' = @dt_tec, 'detail_id' = @det_s, 'kw' = @det_qw

--Занесение остатков во временную таблицу
--Остатки должны заноситься всякий раз, когда изменилась дата документа, иначе следующий расчет остатков с интервалом дат,
--перекрывающим данный, даст неверные остатки (либо надо точно соблюдать равенство: начальная дата следующего расчета остатков=
--конечной дате предыдущего расчета остатков)
IF @det_is<>@det_s or @@FETCH_STATUS <> 0 or (@det_is=@det_s and @dt_tec>@dt_tec_p) -- для внесения остатков по каждой дате их изменения
--IF @det_is<>@det_s -- для внесения остатка по последней дате изменения, т. е. единстенная запись остатка по каждой ТМЦ (на складе УДСТ)
BEGIN
--Анализ на конец таблицы
--IF ISNULL(@det_is,0)<> 0
--BEGIN
INSERT INTO #OST_VREM (base_id, date, detail_id, ostatok, price_uchet, last)
VALUES (@base_s, @dt_tec_p, @det_is, @det_qw_tec, @det_sum_tec, 1)
--SELECT 'dt_tec' = @dt_tec_p, 'detail_id' = @det_is, 'qwont'=@det_qw_tec
--END
END
--Конец цикла курсора
END

--select 'Timer_cicl' = getdate()-@tim

--Заполнение реальной таблицы остатков
BEGIN
INSERT INTO ostatok (base_id, date, detail_id, ostatok, price_uchet, last)
select base_id, date, detail_id, ostatok, price_uchet, last
FROM #OST_VREM
END

--Заполнение реальной таблицы документов учетной ценой
BEGIN
--drop table OST_UCH
--create table OST_UCH (base_id smallint, date smalldatetime, detail_id int, price_uchet float)
TRUNCATE TABLE OST_UCH
INSERT INTO OST_UCH (base_id, date, detail_id, price_uchet)
select base_id, date, detail_id, price_uchet
FROM #OST_UCH

UPDATE slg_rashod_uch
SET price_s = price_o
TRUNCATE TABLE OST_UCH
END

select 'Timer-end' = getdate()-@tim

CLOSE cur_dvig


Deallocate cur_dvig
return 0
set nocount on
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временные таблицы или что другое...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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