Вы можете иметь глобальный флаг, который немедленно выходит из функции, если предыдущий вызов не завершился
document.addEventListener('wheel', doStg, false)
let isExecuting = false;
let numb = 0
function doStg() {
if(isExecuting) return; // exit if there is already executing something
isExecuting = true; // prevent next call
console.log(numb++)
// do something
isExecuting = false; // enable for next
}
Вы понимаете, что у вас будут правильные коллизии?
вам нужно сделать что-то подобное, и это может привести к тупикам, так что будьте очень уверены, что вы пытаетесь сделать здесь
DECLARE @id int
BEGIN TRAN
SELECT @id = MAX(id) + 1 FROM Table1 WITH (UPDLOCK, HOLDLOCK)
INSERT INTO Table1(id, data_field)
VALUES (@id ,'[blob of data]')
COMMIT TRAN
Объяснить Что касается коллизий, я предоставил некоторый код
, сначала создайте эту таблицу и вставьте одну строку
CREATE TABLE Table1(id int primary key not null, data_field char(100))
GO
Insert Table1 values(1,'[blob of data]')
Go
Теперь откройте два окна запроса и запустите это одновременно
declare @i int
set @i =1
while @i < 10000
begin
BEGIN TRAN
INSERT INTO Table1(id, data_field)
SELECT MAX(id) + 1, '[blob of data]' FROM Table1
COMMIT TRAN;
set @i =@i + 1
end
Вы увидите кучу этих
Серверов : Сообщение 2627, уровень 14, состояние 1, строка 7 Нарушение ограничения PRIMARY KEY 'PK__Table1__3213E83F2962141D'. Невозможно вставить дубликат ключа в объект 'dbo.Table1'. Заявление было прекращено.
Попробуйте вместо этого:
INSERT INTO Table1 (id, data_field)
SELECT id, '[blob of data]' FROM (SELECT MAX(id) + 1 as id FROM Table1) tbl
Я бы не рекомендовал делать это таким образом по ряду причин (производительность, безопасность транзакций и т. Д.)
Это может быть из-за отсутствия записей, поэтому подзапрос возвращает NULL ... try
INSERT INTO tblTest(RecordID, Text)
VALUES ((SELECT ISNULL(MAX(RecordID), 0) + 1 FROM tblTest), 'asdf')
Если вы делаете это в триггере, вы можете убедиться, что это триггер «INSTEAD OF», и сделать это в паре операторов:
DECLARE @next INT
SET @next = (SELECT (MAX(id) + 1) FROM Table1)
INSERT INTO Table1
VALUES (@next, inserted.datablob)
Единственное, что у вас будет быть осторожным с параллелизмом - если две строки вставляются одновременно, они могут попытаться использовать одно и то же значение для @next, что приведет к конфликту.
Достигает ли это того, чего вы хотите?
Кажется очень странным делать подобные вещи без столбца IDENTITY (автоинкремент), что заставляет меня подвергать сомнению саму архитектуру. Я имею в виду, серьезно, это идеальная ситуация для столбца IDENTITY. Это может помочь нам ответить на ваш вопрос, если вы объясните причину этого решения. =)
Сказав это, некоторые варианты:
Извините за бессмысленность. Надеюсь, это поможет.
declare @nextId int
set @nextId = (select MAX(id)+1 from Table1)
insert into Table1(id, data_field) values (@nextId, '[blob of data]')
commit;
Но, возможно, лучшим подходом будет использование скаляра функция getNextId ('table1')
Это должно работать:
INSERT INTO Table1 (id, data_field)
SELECT (SELECT (MAX(id) + 1) FROM Table1), '[blob of data]';
Или вот это (заменить LIMIT для других платформ):
INSERT INTO Table1 (id, data_field)
SELECT TOP 1
MAX(id) + 1, '[blob of data]'
FROM
Table1
ORDER BY
[id] DESC;