|
|
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
Хочу убить двойные записи некоторые. Решил сначала пройтись курсором и выставить признак в NULL, а потом просто убить все эти NULL разом. Сделал хранимую процедуру CREATE PROCEDURE [dbo].[drop_worker_data_double] AS DECLARE @ErrNum integer, @OBJ_ID_ID decimal(38,0), @OLD_OBJ_ID_ID decimal(38,0), @YEAR_DATA varchar(4), @OLD_YEAR_DATA varchar(4), @DATEEVENT datetime, @OLD_DATEEVENT datetime, @STAY_IN decimal(1,0) DECLARE Worker_Curs CURSOR LOCAL FORWARD_ONLY DYNAMIC SCROLL_LOCKS TYPE_WARNING FOR SELECT OBJ_ID_ID, YEAR_DATA, DATEEVENT, STAY_IN FROM [dbo].[F_T_WORKER_CNT] ORDER BY OBJ_ID_ID ASC, YEAR_DATA ASC, DATEEVENT DESC FOR UPDATE OF STAY_IN SET NOCOUNT ON BEGIN TRANSACTION Drop_Worker_Data_Double -- открываем курсор OPEN Worker_Curs -- вытаскиваем из него первую строчку FETCH NEXT FROM Worker_Curs INTO @OLD_OBJ_ID_ID, @OLD_YEAR_DATA, @OLD_DATEEVENT, @STAY_IN -- теперь пошли перебор и сравнение WHILE @@FETCH_STATUS = 0 BEGIN -- вытащили следующую запись FETCH NEXT FROM Worker_Curs INTO @OBJ_ID_ID, @YEAR_DATA, @DATEEVENT, @STAY_IN -- если ID равны, то это один и тот же объект IF @OBJ_ID_ID = @OLD_OBJ_ID_ID BEGIN -- если годы равны??? IF @OLD_YEAR_DATA = @YEAR_DATA BEGIN IF @OLD_DATEEVENT = @DATEEVENT -- пометим эту запись UPDATE [dbo].[F_T_WORKER_CNT] SET STAY_IN = NULL WHERE CURRENT OF Worker_Curs SET @ErrNum = @@ERROR IF @ErrNum <> 0 GOTO RollBackTran ELSE -- запомним дату поступления данных SET @OLD_DATEEVENT = @DATEEVENT END ELSE -- заменим старый год SET @OLD_YEAR_DATA = @YEAR_DATA END ELSE BEGIN SET @OLD_OBJ_ID_ID = @OBJ_ID_ID SET @OLD_YEAR_DATA = @YEAR_DATA SET @OLD_DATEEVENT = @DATEEVENT END END CLOSE Worker_Curs DEALLOCATE Worker_Curs COMMIT TRANSACTION Drop_Worker_Data_Double GOTO ReturnRezult RollBackTran: CLOSE Worker_Curs DEALLOCATE Worker_Curs ROLLBACK TRANSACTION Drop_Worker_Data_Double RAISERROR ('Clear doubles failed from ais_drop_ul_worker_data_double',1,1) ReturnRezult: RETURN 0 GO И в отладчике валится, и при запуске. Ругается на то, что курсор объявлен как READ_ONLY и его UPDATE-ить нельзя. Как курсор объявить, чтобы он работал с UPDATE? А то весь MSDN перерыл по ключевым словам, а там примеров то и нету . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2002, 17:02:44 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
SQL не FoxPro и такие фокусы заканчиваються всегда печально. Не будь в обиду, но сейчас надаю кучу советов: 1. Создать уникальный индекс по полям. Тогда больше никаких проблем с дублированием записей не возникнет 2. Стараться всегда все делать через команды SQL, не использовать курсоры для простого перелопачивания и уж тем более изменения записей. Для этого использовать UPDATE и DELETE 3. Если у таблицы нет Primary Key, то создать его, тогда можно выполнить следующий запрос (в нем для примера как PK я использовал поле id int not null primary key): delete d from F_T_WORKER_CNT d inner join (select t1.id from F_T_WORKER_CNT t1 inner join (select OBJ_ID_ID, YEAR_DATA, DATEEVENT from F_T_WORKER_CNT group by OBJ_ID_ID, YEAR_DATA, DATEEVENT having Count(*) > 1) as t2 on t1.OBJ_ID_ID = t2.OBJ_ID_ID and t1.YEAR_DATA = t2.YEAR_DATA and t1.DATEEVENT = t2.DATEEVENT where not t1.id in (select Min(tx1.id) from F_T_WORKER_CNT tx1 inner join (select OBJ_ID_ID, YEAR_DATA, DATEEVENT from F_T_WORKER_CNT group by OBJ_ID_ID, YEAR_DATA, DATEEVENT having Count(*) > 1) as tx2 on tx1.OBJ_ID_ID = tx2.OBJ_ID_ID and tx1.YEAR_DATA = tx2.YEAR_DATA and tx1.DATEEVENT = tx2.DATEEVENT where tx1.OBJ_ID_ID = t1.OBJ_ID_ID and tx1.YEAR_DATA = t1.YEAR_DATA and tx1.DATEEVENT = t1.DATEEVENT)) as t on d.Id = t.Id По идее должно сработать, хотя наверное при желании скрипт можно соптимизировать и написать более красиво. 4. Если PK нет, и создать его не предстовляеться возможности, то вариант остается только такой: create table #F_T_WORKER_CNT (OBJ_ID_ID decimal(38, 0) not null, YEAR_DATA varchar(4) not null, DATEEVENT datetime not null) insert into #F_T_WORKER_CNT (OBJ_ID_ID, YEAR_DATA, DATEEVENT) select OBJ_ID_ID, YEAR_DATA, DATEEVENT from F_T_WORKER_CNT group by OBJ_ID_ID, YEAR_DATA, DATEEVENT having Count(*) > 1 delete d from F_T_WORKER_CNT d inner join (select OBJ_ID_ID, YEAR_DATA, DATEEVENT from F_T_WORKER_CNT group by OBJ_ID_ID, YEAR_DATA, DATEEVENT having Count(*) > 1) as t on d.OBJ_ID_ID = t.OBJ_ID_ID and d.YEAR_DATA = t.YEAR_DATA and d.DATEEVENT = t.DATEEVENT insert into F_T_WORKER_CNT (OBJ_ID_ID, YEAR_DATA, DATEEVENT) select OBJ_ID_ID, YEAR_DATA, DATEEVENT from #F_T_WORKER_CNT drop table #F_T_WORKER_CNT Получается, что мы сохраняем повторяющиеся записи как уникальные во временную таблицу, удаляем их с таблицы и переносим с временной обратно. Кстати - если не секрет, что храниться в поле OBJ_ID_ID, имеющего тип аж decimal(38, 0) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2002, 18:23:06 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
Черт, чего же все отсутпы то сьела ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2002, 18:26:45 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
Черт, чего же все отступы то сьела ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2002, 18:26:58 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток 2Query: Возможно, Вам будут интересны следующие статьи: http://www.swynk.com/friends/boyle/removeduplicate.asp http://www.sqlteam.com/item.asp?ItemID=3331 2ASCRUS: Вариант 4 не учитывает наличия полей кроме OBJ_ID_ID, YEAR_DATA, DATEEVENT. Удачи ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2002, 20:08:24 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2002, 06:56:41 |
|
||
|
Курсор FOR UPDATE OF.... не объевляется
|
|||
|---|---|---|---|
|
#18+
Есть хорошее слово DISTINCT BOL:The DISTINCT keyword eliminates duplicate rows from the results of a SELECT statement. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.05.2002, 07:09:32 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32030849&tid=1822649]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
172ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
| others: | 215ms |
| total: | 467ms |

| 0 / 0 |
