Вставка данных из временной таблицы в несколько соединенных таблиц - PullRequest
0 голосов
/ 17 февраля 2012

Я хотел бы высказать несколько мнений о том, каков наилучший подход к следующему.

Я импортировал некоторые данные из клиента во временную таблицу, очистил их, и теперь мне нужно вставить новые записи в нашу систему.

У клиента есть внутренние и внешние местоположения, в каждом из которых хранится различная информация о них, но в некоторых случаях (создание отчетов или назначение элементов) все местоположения должны рассматриваться как просто местоположение, тип (внутренний или внешний) не важен.

У меня есть 4 таблицы:

  1. Temp_Table - содержит данные от клиента о внешних местоположениях

  2. Locations - содержит a Location ID, время обновления и т. Д. Эта ссылка на другие таблицы местоположений зависит от типа местоположения

  3. Internal Locations

  4. 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, но есть ли более эффективный способ с точки зрения чистого кодирования производительности.

Могу ли я:

  1. перебрать оператором while и вставить каждую строку, вероятно, с помощью хранимой процедуры

  2. Сделайте что-нибудь с такой функцией, как Select my_Insert_Func(Val_1, Val_2, Val_3) From #Temp_Table;, затем верните 0 или 1 для функции. Я никогда не пытался использовать функцию для вставки данных, и это кажется «неправильным». Я считаю, что функции возвращают данные, но может ли это быть и будет ли это лучше или хуже, чем цикл while?

  3. Любая другая идея, которую может придумать гений 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());

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

преобразовал комментарии в ответ.

Вопрос 1: какими будут ваши запросы?Если вы (скорее всего) узнаете местоположение, а затем захотите узнать внешнее местоположение этого местоположения, поместите FK в таблицу местоположений.если вместо этого вам случится узнать внешнее местоположение и захотите узнать соответствующее местоположение, сделайте наоборот.

Вопрос 2: вам не нужны «функции», просто пара SQL INSERT инструкций (в сделке).Он возьмет записи из временной таблицы и вставит их в целевую таблицу (таблицы).

Если вы точно опишете таблицы, кто-то даст вам правильный запрос.

0 голосов
/ 17 февраля 2012

Предположение: External_Location_Id и Internal_Location_Id никогда не будут совпадать.
Если приведенное выше предположение верно, то вы можете объединить его только с LocationId.

Цикл внутри хранимого процесса:
Я сделал это с помощью LABELS и GOTO, и он отлично работает!
Вот заглушка кода

СОЗДАНИЕ ПРОЦЕДУРЫ spProcessClientData
as
DECLARE @RecCount int
DECLARE @I int

CREAT TABLE # TempData
(
Идентификатор RowId int (1,1),
/ *
ClientData1
ClientData2
ClientData3
* /
)

/ *
Вставка ClientData в таблицу #TempData
Значение идентификатора RowId будет использоваться для управления циклом
* /

SET @RecCount = (ВЫБРАТЬ МАКС. (RowId) ИЗ #TempData)
SET @I = 0

WHILE @I <@ RecCount <br>НАЧАТЬ
SET @I =@I + 1
GOTO DetailProcessing
DetailProcessingReturn:
END

DROP # TempTable
RETURN

DetailProcessing:
/ *
Поместить вселогика обработки
, которую вы хотите выполнить для каждой
записи, где @I = # TempData.RowId
Когда закончите, вернитесь в цикл
, используя другой GOTO иd Label
* /
GOTO DetailProcessingReturn

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...