url="jdbc:postgresql//localhost:5432/mmas"
Этот URL-адрес выглядит неправильно, вам нужно следующее:
url="jdbc:postgresql://localhost:5432/mmas"
Ваше предположение является правильным, это - оптимальный способ сделать это, и это звонило upsert/merge.
Важность UPSERT - с sqlservercentral.com :
Для каждого обновления в случае упомянул выше, мы удаляем одно дополнительное чтение из таблицы, если мы используем UPSERT вместо, СУЩЕСТВУЕТ. К сожалению для Вставки и UPSERT и ЕСЛИ СУЩЕСТВУЕТ методы, используют то же количество чтений на таблице. Поэтому проверка на существование должна только быть сделана, когда существует очень допустимая причина выровнять по ширине дополнительный ввод-вывод. Оптимизированный способ сделать вещи состоят в том, чтобы удостовериться, что у Вас есть мало чтений как возможное на DB.
лучшая стратегия состоит в том, чтобы делать попытку обновления. Если никакие строки не затронуты обновлением, тогда вставляют. При большинстве обстоятельств будет уже существовать строка, и только один ввод-вывод будет требоваться.
Редактирование : проверьте этот ответ и связанное сообщение в блоге для приобретения знаний о проблемах с этим шаблоном и как заставить его работать безопасный.
Читайте эти сообщение на моем блоге для хорошего, безопасного шаблона, который можно использовать. Существует много соображений, и принятый ответ по этому вопросу совсем не безопасен.
Для быстрого ответа пробуют следующий шаблон. Это будет хорошо работать на SQL 2000 и выше. SQL 2005 дает Вам обработку ошибок, которая открывает другие опции и SQL 2008, дает Вам команду MERGE.
begin tran
update t with (serializable)
set hitCount = hitCount + 1
where pk = @id
if @@rowcount = 0
begin
insert t (pk, hitCount)
values (@id,1)
end
commit tran
Если использоваться с SQL Server 2000/2005, исходный код должен быть включен в транзакцию, чтобы удостовериться, что данные остаются последовательными в параллельном сценарии.
BEGIN TRANSACTION Upsert
update myTable set Col1=@col1, Col2=@col2 where ID=@ID
if @@rowcount = 0
insert into myTable (Col1, Col2) values (@col1, @col2)
COMMIT TRANSACTION Upsert
Это понесет дополнительные расходы производительности, но гарантирует целостность данных.
Добавляют, как уже предложено, СЛИЯНИЕ должно использоваться где это возможно.
СЛИЯНИЕ является одной из новых возможностей в SQL Server 2008, между прочим.
Не только необходимо выполнить его в транзакции, этому также нужен высокий уровень изоляции. Я уровень изоляции значения по умолчанию факта являюсь Фиксировавшим Read и эта сериализуемая потребность кода.
SET transaction isolation level SERIALIZABLE
BEGIN TRANSACTION Upsert
UPDATE myTable set Col1=@col1, Col2=@col2 where ID=@ID
if @@rowcount = 0
begin
INSERT into myTable (ID, Col1, Col2) values (@ID @col1, @col2)
end
COMMIT TRANSACTION Upsert
, Возможно, добавление также @@ проверка на ошибки и откат могли быть хорошей идеей.
Если Вы не делаете слияния в SQL 2008, необходимо изменить его на:
, если @@ rowcount = 0 и @@ error=0
иначе, если обновление приводит к сбою по некоторым причинам тогда его, попытается к вставке впоследствии, потому что rowcount на неудавшемся операторе 0
Большой поклонник UPSERT, действительно сокращает код для управления. Вот иначе, я делаю это: Один из входных параметров является идентификатором, если идентификатор является ПУСТЫМ или 0, Вы знаете, что это - ВСТАВКА, иначе это - обновление. Предполагает, что приложение знает, существует ли идентификатор, таким образом, работа привычки во всех ситуациях, но сократит выполнение в половине, если Вы делаете.
Ваша логика кажется звуковой, но Вы могли бы хотеть полагать, что добавление некоторого кода предотвращает вставку, если Вы передали в определенном первичном ключе.
Иначе, если Вы всегда делаете вставку, если обновление не влияло ни на какие записи, что происходит, когда кто-то удаляет запись перед Вами выполнения "UPSERT"? Теперь запись, которую Вы пытались обновить, не существует, таким образом, она создаст запись вместо этого. Это, вероятно, не поведение, которое Вы искали.