Есть способ сделать то, что требует спрашивающий:
Я сделал что-то внутри триггера, который проверяет, действительно ли все столбцы конкретной таблицы участвовали в вставке в эту таблицу.Если они это сделали, я позже скопировал их в таблицу истории.Если этого не произошло, то в таблицу отчета можно вставить откат и напечатать только полные строки.Возможно, они могли бы адаптировать это к своим потребностям:
вот оно:
[
if exists (select 1 from inserted) and not exists (select 1 from deleted) -- if an insert has been performed
begin -- and we want to test whether all the columns in the report table were included in the insert
declare @inserted_columncount int, @actual_num_of_columns int, @loop_columns int, @current_columnname nvarchar(300),
@sql_test nvarchar(max), @params nvarchar(max), @is_there bit
set @actual_num_of_columns = (
select count(*) from (
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'renameFilesFromTable_report') as z)
set @inserted_columncount = 0
set @loop_columns = 1
declare inserted_columnnames cursor scroll for -- these are not really the inserted ones, but we are going to test them 1 by 1
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'renameFilesFromTable_report'
set @params = '@is_there_in bit output'
open inserted_columnnames
fetch next from inserted_columnnames into @current_columnname
select * into #temp_for_dynamic_sql from inserted -- this is necessary because the scope of sp_executesql does not include inserted pseudo table
while (@loop_columns <= @actual_num_of_columns) -- looping with independent integer arithmetic
begin
set @sql_test = '
set @is_there_in = 0
if exists (select ['+@current_columnname+'] from #temp_for_dynamic_sql where ['+@current_columnname+'] is not null)
set @is_there_in = 1'
exec sp_executesql @sql_test, @params, @is_there output
if @is_there = 1
begin
fetch next from inserted_columnnames into @current_columnname
set @inserted_columncount = @inserted_columncount + 1
set @loop_columns = @loop_columns + 1
end
else if @is_there <> 1
begin
fetch next from inserted_columnnames into @current_columnname
set @loop_columns = @loop_columns + 1
end
end
close inserted_columnnames
deallocate inserted_columnnames
-- at this point we hold in two int variables the number of columns participating in the insert and the total number of columns
]
Тогда вы можете просто сделать это, если @inserted_columncount <@actual_num_of_columns .......... </p>
Я сделал это, потому что у меня есть sp, который вставляет 1 полную строку в таблицу отчета при каждом запуске.Это хорошо, но я не хочу, чтобы кто-нибудь еще случайно дотронулся до этого стола.даже не я.Я тоже хочу сохранить историю.Поэтому я сделал этот триггер, чтобы сохранить историю, а также проверить, была ли предпринята попытка вставки без значений для всех столбцов таблицы отчета, и далее по коду, который он проверяет, предпринимались ли попытки обновления или удаления, и происходит ли откат.
Я думал о расширении этого, чтобы позволить обновление, но в котором установлены все столбцы.возможно, это можно сделать следующим образом:
в случае попытки обновления
and exists (
select possibly_excluded.COLUMN_NAME from (
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'renameFilesFromTable_report') as possibly_excluded
group by possibly_excluded.COLUMN_NAME
having COLUMN_NAME not in (
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'renameFilesFromTable_report' and
sys.fn_IsBitSetInBitmask(@ColumnsUpdated, COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME), COLUMN_NAME, 'ColumnID')) <> 0)
)
begin
rollback transaction
print 'Only updates that set the values for a complete row are allowed on the report table..'
end