Табличная функция с использованием переменных и OpenQuery - PullRequest
1 голос
/ 17 апреля 2020

Я пытаюсь запросить данные с нашего Oracle сервера через наш SQL сервер. Чтобы выполнить это в режиме тонкого клиента, я использую OpenQuery. Я хотел бы создать одну табличную функцию, которая может использоваться для запроса различных связанных таблиц по мере необходимости. Я не могу понять синтаксис, чтобы заставить это работать. Вот что у меня так далеко. Любая помощь очень ценится!

CREATE FUNCTION [dbo].[fnTEST](
@Table  varchar (100),
@Fields varchar (1000),
@Condition  varchar(5000)
)

RETURNS 
@TEST TABLE()

AS

BEGIN
DECLARE @OPENQUERY nvarchar(4000);
DECLARE @TSQL nvarchar(4000);

SET @OPENQUERY = 'SELECT * FROM OPENQUERY([TEST-Link],'''
SET @TSQL = 'SELECT ' + @Fields + ' FROM TEST.' + @Table + ' WHERE ' + @Condition + ''')'

EXEC (@OPENQUERY+@TSQL) 
END;

Я получаю в настоящее время ошибку:

Msg 102, Level 15, State 1, Procedure fnTEST, Line 12 [Batch Start Line 7]
Incorrect syntax near ')'.

Выделено в @TEST TABLE ()

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Это все не рекомендуется по ряду причин, но вот главная из них заключается в том, что, как указано в MS do c, вы не можете использовать Dynami c SQL от пользовательская функция:

Перед началом работы

Ограничения и ограничения

  • ...

  • Пользовательские функции не могут использовать динамические c SQL или временные таблицы. Табличные переменные допускаются.

  • ...


Вот некоторые другие проблемы этого подхода:

  1. Ваш динамик c SQL для инъекций. Вы никогда не должны использовать Dynami c SQL, если вы не понимаете, что такое SQL Инъекция и , как предотвратить это в вашем Dynami c SQL код .
  2. Использование Dynami c sql имеет потенциальные требования безопасности и ограничения. В этом случае Dynami c SQL может не обладать теми же правами, что и ваша учетная запись, и может не иметь возможности использовать OPENQUERY.
  3. Характер параметров надежных баз данных и серверов может в любом случае заблокировать это.
  4. ИМХО, OPENQUERY не рекомендуется (некоторые не согласны), и удаленные запросы лучше обрабатываются с помощью связанных серверов и команды Remote EXE C.
  5. Вы пытаетесь написать «Универсальный запрос» Вот. Универсальные запросы, как правило, не очень хорошая идея и имеют проблемы с безопасностью, даже после устранения проблем SQL Inject. Лучше определить конкретные c запросы, необходимые для вашего приложения, и закодировать их как хранимые процедуры и / или фиксированные запросы, используя параметры только для условий WHERE.
  6. A SQL Функция не подходит для всех об этом в любом случае. Вы должны рассматривать табличную функцию SQL как родственную View, но с параметрами для вашего предложения WHERE. Вы не должны рассматривать это как способ магическим образом что-либо делать.

Способ, которым я бы сделал что-то связывающий, заключается в следующем: A. Определите явные запросы / наборы данных, которые нужны вашему приложению, из Oracle База данных. Б. Запишите эти запросы как хранимые процедуры, *, в базу данных Oracle . C. Настройте определение связанного сервера в базе данных SQL Server для базы данных Oracle. Настройте безопасность для каждой стороны соответствующим образом. D. Запишите указанные c хранимые процедуры на вашем SQL сервере, чтобы вызвать соответствующие процедуры в базе данных Oracle. Используйте удаленные EXE C для этого через определение Связанного сервера.

Удаленное выполнение EXE C выполняется с помощью AT <linkedServer> предложения .

0 голосов
/ 17 апреля 2020

Включите связанный сервер для rpc out и упростите это до

EXEC (@sql) at [TEST-Link]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...