【问题标题】:Table-Based Function using variables and OpenQuery使用变量和 OpenQuery 的基于表的函数
【发布时间】:2020-07-31 04:35:41
【问题描述】:

我正在尝试通过我们的 SQL 服务器从我们的 Oracle 服务器查询数据。为了以瘦客户端方式执行此操作,我使用了 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()中突出显示

【问题讨论】:

  • 每当您使用动态 SQL 时,您几乎总是会走下坡路。您是否考虑过不需要动态 SQL 的解决方案?
  • 调试是程序员工作的一部分。您是否尝试在执行之前打印每个变量以查看它的外观??? PRINT @TSQL, PRINT @OPENQUERY + @TSQL
  • 另外,你不能从函数中调用存储过程。

标签: sql-server oracle tsql dynamic-sql openquery


【解决方案1】:

不推荐这样做的原因有很多,但最大的一个原因是,正如MS doc 中所指出的,您不能从用户定义的函数中使用动态 SQL:

开始之前

限制和约束

  • ...

  • 用户定义的函数不能使用动态 SQL 或临时表。允许使用表变量。

  • ...


以下是这种方法的一些其他问题:

  • 您的动态 SQL 是可注入的。除非您了解什么是 SQL 注入和how to prevent it in your dynamic SQL code,否则您永远不应该使用动态 SQL。
  • 使用动态sql有潜在的安全requirements和限制。在这种情况下,动态 SQL 可能与您的帐户没有相同的权限,并且可能无法使用 OPENQUERY。
  • 数据库和服务器可信设置的性质可能会阻止此操作。
  • 恕我直言,不建议使用 OPENQUERY(有些人不同意),使用链接服务器和远程执行命令可以更好地处理远程查询。
  • 您正在尝试在此处编写“通用查询”。通用查询通常不是一个好主意并且存在安全问题,即使在您修复了 SQL 注入问题之后也是如此。最好定义您的应用所需的特定查询,并将它们编码为存储过程和/或仅使用 WHERE 条件的参数的固定查询。
  • 无论如何,SQL 函数并不是处理所有这些的正确位置。您应该将 SQL 表函数视为类似于视图,但带有用于 WHERE 子句的参数。您不应该将其视为一种神奇地做任何事情的方式。

我会做一些链接的方式如下:

  1. 从 Oracle 数据库中定义您的应用所需的显式查询/数据集。

  2. 将这些查询编写为存储过程,在 Oracle 数据库中

  3. 在您的 SQL Server 数据库中将链接服务器定义设置为 Oracle 数据库。适当配置每一方的安全性。

  4. 在您的 SQL Server 上编写特定的存储过程,以调用 Oracle 数据库中的相应过程。使用远程 EXEC 通过链接服务器定义来执行此操作。

(注意:远程 EXEC 执行是使用 AT <linkedServer> clause 完成的)。

【讨论】:

    【解决方案2】:

    rpc out 启用链接服务器并将其简化为

    EXEC (@sql) at [TEST-Link]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2023-03-11
      相关资源
      最近更新 更多