在 sql 的 where 子句中使用变量作为列名

use variable as column name in where clause in sql

我想在我的 SQL 查询中使用一个变量作为列名。

问题:

我不能使用动态 SQL,因为我的 SQL 查询在用户定义的内联 table 函数中。

所以, 1.不能使用动态SQL 2. 不能用存储过程替换此函数,因为这只能从用户定义的函数中调用

还有哪些其他可能的选择?

我的代码如下:

create function MatchStringPercent(@parameterFromUser nvarchar(20), @parameterInTable nvarchar(20))
RETURNS table As Return 
SELECT Top(1)
cast(LEN(@parameterInTable) as float)/(Abs(LEN(@parameterFromUser) - LEN(@parameterInTable)) + LEN(@parameterInTable))* 100 As Match
FROM Demo
WHERE @parameterInTable = LEFT( @parameterFromUser , LEN(@parameterInTable) ) 
ORDER BY LEN(@parameterInTable) DESC 
Go

注意:这是转贴。我确实问过这个问题 here,但被告知这是不可能的。或许。但只是想知道是否有任何该死的可能替代方案。

你唯一真正的选择是一个巨大的case声明:

where (case when @parameterInTable = 'col1' then col1
            when @parameterInTable = 'col2' then col2
            . . .
       end) = . . .

不幸的是,更简洁的解决方案是使用动态 SQL,您不能从函数中执行此操作。

我确实曾经看到一些奇怪的机制,其中一个函数可以调用 xp_cmdshell,然后使用 cmd_shell 执行动态 SQL,然后在命令 [= =31=]。函数 允许 运行 扩展存储过程。我非常、非常不鼓励你朝那个方向前进。它太复杂了,它可能会在某个时候停止工作,并且它需要摆弄权限,这可能会使您的系统更容易受到攻击。

编辑:

您可能想要稍微复杂一点的表达式(我没有意识到参数在右侧和左侧):

where ( (@parameterInTable = 'col1' and col1 = LEFT(@parameterFromUser , LEN(col1)) ) or
        (@parameterInTable = 'col2' and col2 = LEFT(@parameterFromUser , LEN(col2)) ) or
        . . .
      )

或使用 case:

where @parameterFromUser like
       (case when @parameterInTable = 'col1' then col1
             when @parameterInTable = 'col2' then col2
            . . .
        end) + '%';