Выберите запрос для 3 таблиц и 2 серверов

#sql #sql-server #tsql #sql-server-2008

#sql #sql-сервер #tsql #sql-server-2008

Вопрос:

Я пытаюсь создать хранимую процедуру, которая извлекает данные из 3 таблиц на 2 разных серверах. Это инструкция select, которая у меня есть.

 SELECT InvoiceLine.BranchNo, InvoiceLine.Type_IN_CR, InvoiceLine.Docket,InvoiceLine.ProductCode, 
   InvoiceLine.Inv_Price * (select OuterUnits From server.PopTables.dbo.Products Inner Join InvoiceLine ON server.PopTables.dbo.Products.ProductCode = InvoiceLine.ProductCode Where server.PopTables.dbo.Products.ProductCode = InvoiceLine.ProductCode) AS PricePT,
    InvoiceLine.Inv_Quantity * (select OuterUnits From server.PopTables.dbo.Products Inner Join InvoiceLine ON server.PopTables.dbo.Products.ProductCode = InvoiceLine.ProductCode Where server.PopTables.dbo.Products.ProductCode = InvoiceLine.ProductCode) AS QunatityPT,
    InvoiceLine.Inv_Total, InvoiceHeader.InvoiceDate
  

Он возвращает ошибку ниже 4 раз.

Сообщение 4104, уровень 16, состояние 1, Процедура IMFertiliserRebates, Строка 7 — многосоставный идентификатор «ПРОГРАММЫ.PopTables.dbo.Products.Не удалось привязать «ProductCode».

Я пытаюсь умножить два столбца в одной таблице на столбец в другой таблице на другом сервере на основе кода продукта.

Я очень потерян!

Любая помощь была бы оценена

Спасибо.

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

1. Я надеюсь, что серверы ссылок настроены правильно. Проверьте эту ссылку, чтобы настроить серверы ссылок. msdn.microsoft.com/en-us/library/aa213778 (v=sql.80).aspx

2. Да, это было отсортировано профессионалами!

3. Что такое Table3 в ServerB. Table3.dbo.Products. Код продукта

4. Я разместил неправильный код, но Таблица3 была бы базой данных. Надеюсь, теперь это будет иметь больший смысл.

Ответ №1:

Вам необходимо использовать псевдонимы таблиц в ваших связанных таблицах

например

 SELECT invoiceline.branchno, 
       invoiceline.type_in_cr, 
       invoiceline.docket, 
       invoiceline.productcode, 
       invoiceline.inv_price * (SELECT outerunits 
                                FROM   serverb.table3.dbo.products p 
                                       INNER JOIN invoiceline 
                                         ON p.productcode = 
                                            invoiceline.productcode 
                                WHERE  p.productcode = invoiceline.productcode) 
       AS 
       pricept, 
       invoiceline.inv_quantity * (SELECT outerunits 
                                   FROM   serverb.table3.dbo.productsinner ps 
                                          INNER JOIN invoiceline 
                                            ON ps.productcode = 
                                               invoiceline.productcode 
                                   WHERE  p.productcode = 
                                          invoiceline.productcode) AS 
       qunatitypt, 
       invoiceline.inv_total, 
       invoiceheader.invoicedate 
  

Поскольку ваш исходный SQL довольно большой, вот изменения, которые я внес

Без псевдонима

  • ON server.PopTables.dbo.Products.ProductCode = invoiceline.productcode
  • WHERE server.PopTables.dbo.Products.ProductCode...
  • ON serverb.table3.dbo.productsinner = invoiceline.productcode
  • WHERE serverb.table3.dbo.productsinner.productcode = invoiceline.productcode

С псевдонимом

  • ON p.ProductCode = invoiceline.productcode
  • WHERE p.ProductCode...
  • ON serverb.table3.dbo.productsinner = invoiceline.productcode
  • WHERE serverb.table3.dbo.productsinner.productcode = invoiceline.productcode

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

1. @Wellie Я обновил ответ, чтобы лучше отразить, где я внес свои изменения

Ответ №2:

Кажется, что вы используете связанные серверы. Как отмечали другие, используйте псевдоним для таблицы или представления со связанного сервера, иначе вы получите сообщение об ошибке «невозможно привязать многосоставный идентификатор».

Это ограничение соглашения об именовании из 4 частей. Например, сервер.PopTables.dbo.Products.Код продукта состоит из пяти частей и выдает ошибку. Однако ВЫБЕРИТЕ продукты.Код продукта С сервера.PopTables.dbo.Products В КАЧЕСТВЕ продуктов будут работать нормально.

Помните, что если связанный сервер является экземпляром, убедитесь, что вы заключили имя в квадратные скобки. Например, [ИМЯ_СЕРВЕРАИМЯ_ЭКЗАМЕНА]. Это было настоящей проблемой для меня, когда это произошло в первый раз.

Ответ №3:

У меня был бы один sp, возвращающий нужные вам данные со связанного сервера:

 select OuterUnits From ServerB.Table3.dbo.Products 
       where ServerB.Table3.dbo.Products.ProductCode = @ProductCode
  

и либо используйте этот результат непосредственно из sp в своем соединении, либо сохраните результат где-нибудь на сервере и используйте его в своем соединении. Я бы не запрашивал связанную таблицу больше, чем нужно.