SQL-запрос к нескольким базам данных

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть две базы данных на одном сервере sql, и я должен связать две таблицы с одного сервера БД с двумя таблицами на другом сервере БД, чтобы получить необходимую мне информацию. Проблема в том, что когда я пытаюсь связать две таблицы со второго сервера БД, запрос возвращает дубликаты из 1000 или более. Как я могу выполнить один запрос к двум базам данных? Все таблицы имеют общий столбец repair_ord. Кто-нибудь, пожалуйста, может мне помочь? Спасибо.

server 1 = CXADMIN
SERVER 2 = SAADMIN

Вот как пока выглядит мой запрос:

 SELECT RF.REPAIR_ORD, 
       RH.RECV_UNIT, 
       RH.RECV_SERIAL_NBR, 
       RP.FAULT_CODE, 
       RP.REPAIR_ACTION_CODE, 
       CG.TASK_CODE 
  FROM CXADMIN.RO_FAILURE_DTL RF,  
       CXADMIN.RO_HIST RH, 
       saadmin.sa_repair_part@elgsad rp, 
       saadmin.sa_code_group_task_dtl@elgsad cg 
 WHERE RF.REPAIR_ORD = RH.REPAIR_ORD 
   AND RP.REPAIR_ORD = CG.REPAIR_ORD 
   AND RF.FAILURE_CODE ='DISK'
   AND RH.CURR_FACILITY_ID ='23' 
   AND RF.CREATED_DATE >'1-JUN-2010' 
   AND RF.CREATED_DATE <  '1-JUL-2010' 
   AND (   CG.TASK_CODE ='PHMD' 
        OR CG.TASK_CODE ='PHSN' 
        OR CG.TASK_CODE ='CHMD' 
        OR CG.TASK_CODE ='CHSN')
  

Комментарии:

1. Почему бы вам просто не UNION ALL использовать их?

2. При использовании соединений возникают дубликаты (в вашем запросе используется синтаксис соединения ANSI-89), поскольку родительская запись имеет более одной дочерней записи. Мы не знаем ваших данных — закомментируйте таблицы и постепенно добавляйте их, чтобы узнать, за что отвечает join.

3. @zerkms, я попробовал функцию объединения, но я не понимаю, как ее использовать в этом запросе, поскольку все таблицы одинаковые. У них просто одинаковый столбец repair_ord.

Ответ №1:

Я думаю, что проблема с дубликатами заключается не в объединении двух баз данных, а скорее в вашем объединении в первую очередь. Я думаю, вам может понадобиться ВНУТРЕННЕЕ или ВНЕШНЕЕ соединение для обработки связывания. Что касается получения данных из двух разных баз данных, синтаксис довольно прост. Вы просто добавляете имя сервера, ставите точку над именем базы данных, ставите точку над именем владельца, ставите точку над именем таблицы.

Например:

 SELECT firstdb.*, seconddb.*
FROM Server1.Database1.dbo.myTable AS firstdb
INNER JOIN Server2.Database2.dbo.myTable AS seconddb
   ON firstdb.id = seconddb.id
  

В вашем примере звучит так, как будто вы получаете ссылку для работы, но у вас проблема с соединением в поле repair_ord. Хотя я не знаю вашей схемы, я бы предположил, что эта ссылка должна быть ВНУТРЕННИМ СОЕДИНЕНИЕМ. Если вы просто добавите обе таблицы в инструкцию FROM и не выполните свою инструкцию WHERE должным образом, вы столкнетесь с проблемами, которые вы описываете.

Я бы посоветовал вам упростить эту настройку и поместить ее в тестовую среду (на одной базе данных). Попробуйте объединить четыре таблицы, пока не получите все правильно. Затем добавьте сложности вызовов с несколькими базами данных.

Комментарии:

1. есть предложения по этому поводу? dba.stackexchange.com/questions/102170 /…

Ответ №2:

Если бы вы переписали свое предложение FROM, чтобы использовать ANSI 92, вы бы получили это

  FROM CXADMIN.RO_FAILURE_DTL RF
     INNER JOIN CXADMIN.RO_HIST RH
      ON  RF.REPAIR_ORD = RH.REPAIR_ORD
           ,
      saadmin.sa_repair_part@elgsad rp
      INNER JOIN saadmin.sa_code_group_task_dtl@elgsad cg
       ON RP.REPAIR_ORD = CG.REPAIR_ORD 
  

Затем становится легко видеть, что вы создали декартово произведение между RF join RH и RP JOIN CG

Вам нужно соединить RF с RP или CG, или RH с RP или CG

например

 FROM CXADMIN.RO_FAILURE_DTL RF
     INNER JOIN CXADMIN.RO_HIST RH
      ON  RF.REPAIR_ORD = RH.REPAIR_ORD
      INNER JOIN saadmin.sa_repair_part@elgsad rp
      ON  RF.REPAIR_ORD = RP.REPAIR_ORD
      INNER JOIN saadmin.sa_code_group_task_dtl@elgsad cg
       ON RP.REPAIR_ORD = CG.REPAIR_ORD 
  

Или, если вы настаиваете на использовании объединений в стиле ANSI-86, вы можете просто добавить AND RF.REPAIR_ORD = RP.REPAIR_ORD в свое предложение Where