【问题标题】:How to join dynamic sql statement in variable with normal statement如何将变量中的动态sql语句与普通语句连接起来
【发布时间】:2011-01-28 12:41:01
【问题描述】:

我有一个相当复杂的查询,它将动态构建并保存在一个变量中。

作为第二部分,我有另一个 普通 查询,我想在这两者之间进行内部连接。

为了让这里更容易一点,这里有一个小例子来说明我的问题。
对于这个小例子,我使用了AdventureWorks database

一些查询是动态建立的

(是的,我知道这里没有动态,因为这只是一个示例。)

DECLARE @query AS varchar(max) ;

set @query = '
select
    HumanResources.Employee.EmployeeID
    ,HumanResources.Employee.LoginID
    ,HumanResources.Employee.Title
    ,HumanResources.EmployeeAddress.AddressID
from
    HumanResources.Employee
    inner join HumanResources.EmployeeAddress
    on HumanResources.Employee.EmployeeID = HumanResources.EmployeeAddress.EmployeeID
;';

EXEC (@query);

我的正常查询

select
    Person.Address.AddressID
    ,Person.Address.City
from
    Person.Address

也许我想拥有但没用的东西

select
    @query.*
    ,Addresses.City
from
    @query as Employees
    inner join
    (
        select
            Person.Address.AddressID
            ,Person.Address.City
        from
            Person.Address
    ) as Addresses
    on Employees.AddressID = Addresses.AddressID

【问题讨论】:

  • 我认为您可以通过以下任一答案来解决它
  • @Mitch:仔细看看最后一个代码sn-p的标题。 ;-)

标签: sql sql-server sql-server-2005 tsql dynamic-sql


【解决方案1】:

使用临时表并将记录转储到其中(来自动态查询)并使用临时表加入您拥有的静态查询。

set @query = 'CREATE table #myTempTable AS
select
    HumanResources.Employee.EmployeeID
    ,HumanResources.Employee.LoginID
    ,HumanResources.Employee.Title
    ,HumanResources.EmployeeAddress.AddressID
from
    HumanResources.Employee
    inner join HumanResources.EmployeeAddress
    on HumanResources.Employee.EmployeeID = HumanResources.EmployeeAddress.EmployeeID
;';

EXEC (@query);

然后

select
    Employees.*
    ,Addresses.City
from
    #myTempTable as Employees
    inner join
    (
        select
            Person.Address.AddressID
            ,Person.Address.City
        from
            Person.Address
    ) as Addresses
    on Employees.AddressID = Addresses.AddressID

【讨论】:

  • 我认为临时表在我的情况下是正确的方法。感谢您的提示。
  • 我想使用这种方法,但是在像 Pentaho 这样的 ETL 工具中,像这个示例这样的临时表在 ETL 期间会产生错误。
【解决方案2】:

您可能走在正确的轨道上,但只要您信任参数的来源并且不暴露于 SQL 注入,您可能只需要在构建 @query 时更改您的选择,例如:

parameter to your function  '@YourAlternateTableParm'

DECLARE @query AS varchar(max) ; 

set @query = 'select ' + @YourAlternateTableParm 
  + '.*, Addresses.City
from ' + @YourAlternateTableParm
  + ' as Employees 
    inner join 
    ( ..... '

这样,就像您构建原始字符串一样,您正在将参数的实际值构建到函数/过程调用中,并使用表名将您的“Employees”文件表示到字符串中,然后执行它。 SQL 没有按照您尝试的方式动态解释 @query 内联。

【讨论】:

  • 是的,这是我已经想到的解决方案,但声明已经相当大,我认为如果我采用这种方法,我将达到 varchar(max) 范围。它还会导致进一步的硬链接,以后没有人能够分解语句以了解它在做什么。
  • 然后将您的字符串拆分为多个查询部分...例如选择字段为 1 或 2 个 @vars,为 from/where 条件设置第三个...然后 EXEC( var1 + var2 + var3 )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 2021-09-13
  • 2013-02-01
相关资源
最近更新 更多