[mssql] вопрос про delete ...
Где-то что-то не так.
> mysql> DELETE FROM tbl_name WHERE 1>0;
> This is much slower than TRUNCATE tbl_name, because it deletes rows one at a time.
---
...Я работаю...
> mysql> DELETE FROM tbl_name WHERE 1>0;
> This is much slower than TRUNCATE tbl_name, because it deletes rows one at a time.
---
...Я работаю...
При чем здесь mysql?
в общем случае без триггера не обойтись. А так если по одной удалять - завести какой нить PK и удалять по одному используя этот PK
Всю жизнь думал, что если написать delete from table where id>5 то триггер исполнится для каждой удаленной строчки по отдельности, разве нет? 

нет
пишет ошибку
нада то ли триггер переделать, либо какую нить процедуру замутить, чтобы построчно удаляла, либо хз
пишет ошибку
Server: Msg 512, Level 16, State 1, Procedure table_trigg_del, Line 10
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >=
or when the subquery is used as an expression.
The statement has been terminated.
нада то ли триггер переделать, либо какую нить процедуру замутить, чтобы построчно удаляла, либо хз
По моему не там проблему ищешь. Покажи что ли триггер и delete полностью...
ok
Если под условие в delete попадает больше 1 записи (например delete from sfsupp_dtl where ord_id = 123 при условии что ord_id = 123 больше чем в одной строке) вылезает вышеуказанная ошибка
ps. по поводу триггера прошу особо не стебацца - работает да и пох ... только удалять много не позволяет :-D
таблица :
CREATE TABLE [sfSupp_dtl] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[sfs_id] [int] NOT NULL ,
[ord_id] [int] NOT NULL ,
[bod_id] [int] NOT NULL ,
[pr_id] [int] NOT NULL ,
[amount] [decimal](9, 3) NOT NULL ,
[price] [decimal](18, 2) NOT NULL ,
[summ_nds] [decimal](18, 2) NOT NULL ,
PRIMARY KEY CLUSTERED
(
[id]
) ON [PRIMARY]
) ON [PRIMARY]
GO
триггер :
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
create trigger sfSupp_dtl_del on sfsupp_dtl for delete as
declare
@bod_id int,
@old_sfstatus_amount dec(9,3
@sfstatus_amount_toRemove dec(9,3
@sfs_id int,
@old_sfs_summ decimal(18,2
@summ_toRemove decimal(18,2)
select
@bod_id = (select bod_id from deleted
@old_sfstatus_amount = (select sfs_amount from sfstatus where bod_id = (select bod_id from deleted
@sfstatus_amount_toRemove = (select amount from deleted
@sfs_id = (select sfs_id from deleted
@old_sfs_summ = (select summ from sfSupp where id = (select sfs_id from deleted
@summ_toRemove = (select CONVERT(decimal(18,2price*amount) from deleted)
update sfSupp set summ = CONVERT(decimal(18,old_sfs_summ - @summ_toRemove summ_nds =
CONVERT(decimal(18,old_sfs_summ - @summ_toRemove)*1.18) where id = @sfs_id
update sfstatus set sfs_amount = @old_sfstatus_amount - @sfstatus_amount_toRemove where bod_id = @bod_id
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
Если под условие в delete попадает больше 1 записи (например delete from sfsupp_dtl where ord_id = 123 при условии что ord_id = 123 больше чем в одной строке) вылезает вышеуказанная ошибка
ps. по поводу триггера прошу особо не стебацца - работает да и пох ... только удалять много не позволяет :-D
Ну вобщем да, все логично что не работает
Можно переписать триггер с update на replace будет нормально. Ну и естественно вместо этих переменных временные таблицы надо будет сделать, а лучше вообще всё подставить и не парицца. SQL это вам не паскаль чтобы так писать
А как тут update-ом разрулить я не понимаю.
Можно переписать триггер с update на replace будет нормально. Ну и естественно вместо этих переменных временные таблицы надо будет сделать, а лучше вообще всё подставить и не парицца. SQL это вам не паскаль чтобы так писать
А как тут update-ом разрулить я не понимаю.Попробуй триггер AFTER DELETE. Вроде как он сначала все удалит, а потом для удаленных записей запустится
Блин, из-за этого пенартура суть вопроса при беглом прочтении понял неправильно - думал, проблема в скорости.
Используй UPDATE FROM:
Еще: такие конструкции "select @bod_id = (select bod_id from deleted)" более читабельны в виде "select @bod_id = bod_id from deleted"
Используй UPDATE FROM:
UPDATE table1
SET
field1 = table2.field1
, field2 = field2 + table2.field2
FROM
table2
WHERE
table1.id = table2.id
Еще: такие конструкции "select @bod_id = (select bod_id from deleted)" более читабельны в виде "select @bod_id = bod_id from deleted"

на досуге подумаю :-D
тот триггер я писал через день после того как вообще узнал, что бывают триггеры :-
тот триггер я писал через день после того как вообще узнал, что бывают триггеры :-
О! ты мне глаза открым... update from... пойду думать 
А он в mysql-е есть?

А он в mysql-е есть?
более читабельны в виде "select @bod_id = bod_id from deleted"
зато вместо той ошибки которую тут обсуждаем, получили бы код, который что называется silently wrong...
зато вместо той ошибки которую тут обсуждаем, получили бы код, который что называется silently wrong...Это почему? Вообще, во всех доках по MS SQL именно так и делают.
А насчет MySQL ничего сказать не могу - слишком мало с ним общался
что
select @bod_id = bod_id from deletedвыдает ошибку если в deleted >1 строки?
нет
ну? а
выдает. это и называется silently wrong - делает не то что задумано и молчит...
select @bod_id = (select bod_id from deleted)
выдает. это и называется silently wrong - делает не то что задумано и молчит...
На самом деле, думал, что выдаст ошибку... Это ж с умом надо делать. И не важно, DELETED там или просто табличка. Я сделал замечание по оформлению, не больше. Вообще, если есть "типа ключ", но на самом деле ключа нет, я пишу top 1
selectЧтобы триггер корректно обрабатывал удаление нескольких записей этот блок необходимо заключить в цикл, объявить курсор и фетчить данные на каждой итерации.
@bod_id = (select bod_id from deleted
@old_sfstatus_amount = (select sfs_amount from sfstatus where bod_id = (select bod_id from deleted
@sfstatus_amount_toRemove = (select amount from deleted
@sfs_id = (select sfs_id from deleted
@old_sfs_summ = (select summ from sfSupp where id = (select sfs_id from deleted
@summ_toRemove = (select CONVERT(decimal(18,2price*amount) from deleted)
update sfSupp set summ = CONVERT(decimal(18,old_sfs_summ - @summ_toRemove summ_nds =
CONVERT(decimal(18,old_sfs_summ - @summ_toRemove)*1.18) where id = @sfs_id
update sfstatus set sfs_amount = @old_sfstatus_amount - @sfstatus_amount_toRemove where bod_id = @bod_id
Оставить комментарий
Alena_08_11
в общем на таблицу повешен триггер (стрёмненький по исполнению) for delete, который при удалении записи берёт значение какого то поля из ... from Deleted, и уменьшает значение другого поля в другой таблице на эту величину.то есть таблица не позволяет удалять за раз больше одной записи.
( то есть например delete from table where id>5 - не прокатывает)
можно ли как нить простым путём осуществить такое удаление, так чтобы запрос был типа таким же, а само удаление производилось построчно.
(без написания процедуры, которая по очереди бы удаляла, без переделки триггера, и без генерации в приложении кучи удалятельных запросов )