как узнать, что побежало из запроса upsert

у меня есть вопрос

<cfquery name="qryTemp" datasource="someDSN">
if not exists (select someID from tempTable where someID = 20)
insert into tempTable (someID, colA, colB) values (1,2,3)
else
update tempTable set
colA = 2, colB =3
where someID = 1
</query> 

Есть ли какой-либо идентификатор, который может указать, была ли это вставка или обновление? Я могу добавить атрибут результата в запрос, если это поможет.


person CFML_Developer    schedule 13.06.2018    source источник
comment
Вместо того, чтобы запихивать все операции в один и тот же блок <cfquery>, вы можете разделить их на отдельные запросы.   -  person rrk    schedule 13.06.2018
comment
Какая версия SQL?   -  person Shawn    schedule 13.06.2018
comment
@RRK Использование методологии UPSERT является очень правильным SQL, и он пропускает проверку приложения и потенциальный дополнительный запрос, чтобы определить, хотите ли вы попробовать INSERT или UPDATE.   -  person Shawn    schedule 13.06.2018


Ответы (2)


Чтобы представить еще один вариант, SQL 2008+ также поддерживает MERGE для "upserts". Добавление предложения OUTPUT обеспечит доступ к специальной переменной $action. Как следует из названия, оно будет указывать на фактически выполненное действие («вставить» или «обновить»).

<cfquery name="qryTemp" datasource="#someDSN#">
    MERGE INTO tempTable tmp
    USING ( VALUES ( 1, 2, 3 )) 
        AS data (someID, colA, colB) 
        ON data.someID = tmp.someID
    WHEN MATCHED THEN
        UPDATE SET tmp.ColA = data.ColA
            , tmp.ColB = data.ColB
    WHEN NOT MATCHED THEN
        INSERT (someID, colA, colB)
        VALUES (data.someID, data.colA, data.colB)
    OUTPUT inserted.someID AS ModifiedID
            , $action AS Action;
</cfquery>

<!--- Demo: Was an insert or update peformed? --->
<cfif qryTemp.Action eq "INSERT">
    ID inserted = <cfoutput>#qryTemp.ModifiedID#</cfoutput>
<cfelse>
    ID updated = <cfoutput>#qryTemp.ModifiedID#</cfoutput>
</cfif>

NB: несмотря на то, что по умолчанию параллелизм все еще остается проблемой любыми методами.

person SOS    schedule 13.06.2018

person    schedule
comment
Отлично, это будет работать с небольшим изменением. GeneratedKey не будет частью структуры результата, если это обновление. Поэтому мне нужно будет добавить проверку на его существование. - person CFML_Developer; 13.06.2018
comment
@CFML_Developer, ха-ха, да... isNumeric() было бы плохим решением. Я заменил его на structKeyExists(). - person Matthew Moore; 13.06.2018
comment
@CFML_Developer. Вы также можете просто использовать ОБЪЕДИНЕНИЕ с OUTPUT inserted.id, $action AS Action; Действие указывает, была ли это вставка или обновление. Несмотря на то, что параллелизм изначально является проблемой для обоих методов michaeljswart.com /2011/09/ - person SOS; 13.06.2018