Существует ли способ ВЫБРАТЬ и ОБНОВИТЬ строки одновременно?

Использование ArrayList<Integer> может помочь вам решить проблему перетасовки, не применяя большую логику и потребляя меньше времени. Вот что я предлагаю:

ArrayList<Integer> x = new ArrayList<Integer>();
for(int i=1; i<=add.length(); i++)
{
    x.add(i);
}
Collections.shuffle(x);
40
задан Cade Roux 31 January 2009 в 11:32
поделиться

7 ответов

Рассмотрите рассмотрение ВЫХОДНОЙ пункт :

USE AdventureWorks2012;  
GO  

DECLARE @MyTableVar table(  
    EmpID int NOT NULL,  
    OldVacationHours int,  
    NewVacationHours int,  
    ModifiedDate datetime);  

UPDATE TOP (10) HumanResources.Employee  
SET VacationHours = VacationHours * 1.25,  
    ModifiedDate = GETDATE()   
OUTPUT inserted.BusinessEntityID,  
       deleted.VacationHours,  
       inserted.VacationHours,  
       inserted.ModifiedDate  
INTO @MyTableVar;  

--Display the result set of the table variable.  
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate  
FROM @MyTableVar;  
GO  
--Display the result set of the table.  
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate  
FROM HumanResources.Employee;  
GO 
71
ответ дан Mehdi 4 August 2019 в 22:29
поделиться

Один способ обработать это состоит в том, чтобы сделать это в транзакции и заставить Ваш Запрос Select взять блокировку обновления на строках, выбранных, пока транзакция не завершается.

BEGIN TRAN

SELECT Id FROM Table1 WITH (UPDLOCK)
WHERE AlertDate IS NULL;

UPDATE Table1 SET AlertDate = getutcdate() 
WHERE AlertDate IS NULL;

COMMIT TRAN 

Это устраняет возможность, что параллельный клиент обновляет строки, выбранные в момент между Вашим ВЫБОРОМ и Вашим ОБНОВЛЕНИЕМ.

, Когда Вы будете фиксировать транзакцию, блокировки обновления будут выпущены.

Другой способ обработать это состоит в том, чтобы объявить курсор для Вашего ВЫБОРА с помощью опции FOR UPDATE. Затем ОБНОВИТЕ КУРСОР WHERE CURRENT OF. Следующее не тестируется, но должно дать Вам основную идею:

DECLARE cur1 CURSOR FOR
  SELECT AlertDate FROM Table1 
  WHERE AlertDate IS NULL
  FOR UPDATE;

DECLARE @UpdateTime DATETIME

SET @UpdateTime = GETUTCDATE()

OPEN cur1;

FETCH NEXT FROM cur1;

WHILE @@FETCH_STATUS = 0
BEGIN

  UPDATE Table1 AlertDate = @UpdateTime
  WHERE CURRENT OF cur1;

  FETCH NEXT FROM cur1;

END
13
ответ дан Bill Karwin 4 August 2019 в 22:29
поделиться

Было бы легче сделать Ваше ОБНОВЛЕНИЕ сначала и затем выполнить 'ИЗБРАННЫЙ идентификатор ОТ ВСТАВЛЕННОГО'.

Смотрят на Подсказки SQL для большего количества информации и примеров.

9
ответ дан Kevin Fairchild 4 August 2019 в 22:29
поделиться

Возможно, что-то больше как это?

declare @UpdateTime datetime

set @UpdateTime = getutcdate()

update Table1 set AlertDate = @UpdateTime where AlertDate is null

select ID from Table1 where AlertDate = @UpdateTime
4
ответ дан Gordon Bell 4 August 2019 в 22:29
поделиться

если это будет в транзакции, то запирающая система базы данных будет заботиться о проблемах параллелизма. конечно, при использовании одного (mssql значение по умолчанию - то, что это использует блокировку, таким образом, это указывает, не переопределяете ли Вы это)

0
ответ дан zappan 4 August 2019 в 22:29
поделиться

в SQL 2008 представлен новый оператор TSQL "СЛИЯНИЕ", который работает, вставляют, обновляют или удаляют операции на целевой таблице на основе результатов соединения с исходной таблицей. Можно синхронизировать две таблицы путем вставки, обновляя или удаляя строки в одной таблице на основе различий, найденных в другой таблице.

http://blogs.msdn.com/ajaiman/archive/2008/06/25/tsql-merge-statement-sql-2008.aspx http://msdn.microsoft.com/en-us/library/bb510625.aspx

0
ответ дан 4 August 2019 в 22:29
поделиться

Редактирование: мое плохое, Вы хотели, чтобы выбор показал результаты после обновления, не обновил от выбора.

Вы попробовали подвыбор?

update mytable set mydate = sysdate 
where mydate in (select mydate from mytable where mydate is null);
0
ответ дан Jeff Bridgman 4 August 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: