Я хотел бы высказать несколько мнений о том, каков наилучший подход к следующему.
Я импортировал некоторые данные из клиента во временную таблицу, очистил их, и теперь мне нужно вставить новые записи в нашу систему.
У клиента есть внутренние и внешние местоположения, в каждом из которых хранится различная информация о них, но в некоторых случаях (создание отчетов или назначение элементов) все местоположения должны рассматриваться как просто местоположение, тип (внутренний или внешний) не важен.
У меня есть 4 таблицы:
Temp_Table
- содержит данные от клиента о внешних местоположениях
Locations
- содержит a Location ID
, время обновления и т. Д. Эта ссылка на другие таблицы местоположений зависит от типа местоположения
Internal Locations
External Locations
Locations
таблица содержит -
Location_ID int PK
?External_Location_ID? int
?Internal_Location_ID? int
- другая неактуальная информация
External Locations
таблица содержит
External_Location_ID int PK
?Location_ID?
- другая неактуальная информация
Вопрос 1
Лучше ли иметь ?External_Location_ID?
в таблице Locations
ИЛИ хранить ?Location_ID?
в таблице External_Locations
? Это всегда будет отношение 1 к 1 и проиндексировано.
Вопрос 2
Теперь я хочу получить данные из временной таблицы во внешнюю таблицу местоположений и таблицу местоположений, одна таблица должна ссылаться на другую.
Это было бы легко сделать зацикливанием таблицы по одной строке за раз, используя курсоры (которые я не буду использовать) или цикл while, но есть ли более эффективный способ с точки зрения чистого кодирования производительности.
Могу ли я:
перебрать оператором while и вставить каждую строку, вероятно, с помощью хранимой процедуры
Сделайте что-нибудь с такой функцией, как Select my_Insert_Func(Val_1, Val_2, Val_3) From #Temp_Table;
, затем верните 0 или 1 для функции. Я никогда не пытался использовать функцию для вставки данных, и это кажется «неправильным». Я считаю, что функции возвращают данные, но может ли это быть и будет ли это лучше или хуже, чем цикл while?
Любая другая идея, которую может придумать гений SQL.
Производительность не является серьезной проблемой, так как она запускается только один раз за ночь и не является большим набором данных, но, по мнению клиентов, «ложью», один раз в день каждые 15 минут и небольшой набор данных становится большим плюс то, что я получу это право, позволит мне продолжить те же теории.
Спасибо за любые ответы.
PS Я ищу способ, основанный на множестве, если это возможно, а не зацикливание
Спасибо за вклад, ребята.
@ HGLEM
Полезная ссылка, все остальные запросы, которые у меня есть, уже заданы на основе, но так как для этого требуются два оператора ввода, я не могу придумать способ, основанный на наборе, для этого я и использовал (просто не мог придумать набор терминов основываясь на написании этого). Тем не менее, я только что убрал один из своих запросов, используя функцию слияния в отправленной вами ссылке, теперь гораздо удобнее и проще для чтения, но мне все равно нужно получить ссылку в таблицу местоположений, хотя, к сожалению, MERGE не позволяет EXEC разрешены только DELETE, SELECT и UPDATE.
MERGE Locations_Internal AS Target
USING (select #CSVTemp.Val_1, #CSVTemp.Val_2, #CSVTEMP.Val_3, #CSVTemp.Val_4 from #CSVTemp)
AS Source
ON (Target.Val_1 = Source.Val_1 )
WHEN MATCHED AND
((COALESCE(Source.Val_2, '') <> COALESCE(Target.Val_2, '')
OR COALESCE(Source.Val_3, '') <> COALESCE(Target.Val_3, '')
OR COALESCE(Source.Val_4, '') <> COALESCE(Target.Val_4, '')))
THEN
UPDATE
SET Target.Val_1= Source.Val_1,
Target.Val_2= Source.Val_2,
Target.Val_4= Source.Val_3,
Target.Val_5= Source.Val_5,
Target.Row_Updated = GETDATE()
WHEN NOT MATCHED BY TARGET THEN
INSERT(Val_1, Val_2, Val_3, Val_4, Row_Updated)
VALUES(Source.Val_1, Source.Val_2, Source.Val_3, Source.Val_4, GETDATE());