3

使用 SQL Server 2008,我想使用动态 SQL 指定内部联接的列名。我要加入的两个表对于我要加入的列具有相同的名称。我知道 SQL Server 不支持自然连接;如果是这样,动态 SQL 将如下所示:

DECLARE @join_columns   AS NVARCHAR(100)
DECLARE @sql_1          AS NVARCHAR(4000)

SET @join_columns = 'Age, Gender' 

SET @sql_1 = '
    SELECT ' + @join_columns + ', table_1.Field_x , table_2.Field_y
    FROM table_1 , table_2
    NATURAL JOIN ON ' + @join_columns

EXECUTE sp_executesql @sql_1

现在,我意识到这行不通,因为SQL Server 中没有自然连接。那么,下一个最好的方法是什么?

以下是我未能成功追求的几件事:

  • 标记@join_columns并形成一种动态WHERE table_1.<col_1> = table_2.<col_1> [AND...]的子句。但是,看起来 T-SQL 没有字符串标记化功能。

  • 使用动态 SQL 制作临时表,每个表都有一个名为的新键列temp_key,它是@join_column. 如果动态连接这些很容易,那么最终的连接可能总是ON #temp_table_1.temp_key = #temp_table_2.temp_key. 一种设置方法是使用该REPLACE函数将逗号替换为@join_column加号。我在这里遇到的问题是连接需要对非VARCHAR列进行强制转换。所以,我必须提前知道列类型——回到第一方。

理想情况下,我想保留@join_columns为逗号分隔的字符串,因为我在动态 SQLGROUP BY子句的其他地方使用它。

可能是上述失败的方法之一可以使用我错过的东西。或者,也许有更好的整体方法。

有什么建议么?

更新

解决方案是下面@usr 和@Karl 的帖子的组合。我使用@usr 的建议来追踪一个标记化的表值 UDF(最终选择了这个)。然后我使用@Karl 的COALESCE示例将结果表转换为WHERE子句。我还使用了@Karl 的完整示例来解决我刚刚遇到的另一个连接问题。我希望我能给两张海报提供答案状态 - 谢谢大家!

4

2 回答 2

1

将标记化/拆分功能封装在表值 UDF 中。这允许您以干净且架构合理的方式构建动态 SQL 字符串。您可以在 Web 上轻松找到此类拆分功能。遗憾的是它们不是内置的,但我们可以自己构建它们。

于 2012-08-14T22:02:31.157 回答
1

我发现这很好用:

declare @whereClause varchar(8000)
declare @table2 varchar(255)
declare @table1 varchar(255)

set @table1='SomeTable'
set @table2 = 'SomeOtherTable'

SELECT  COLUMN_NAME as [joincolumn]
into    #join_columns
FROM    INFORMATION_SCHEMA.COLUMNS
WHERE   TABLE_NAME = @table1
AND COLUMN_NAME not in ('list names of columns that are not to be joined on here')

select @whereClause=coalesce(@whereClause+' and ','')+ 
'['+@table2+'].'+joincolumn+'=['+@table1+'].'+joincolumn +'
'
from #join_columns

print @whereClause

You can then create a dynamic SQL script and tag the WHERE clause to the back of it

于 2012-08-15T09:54:45.043 回答