1

我正在使用SQL参数允许用户使用视图中的下拉列表创建自己的SELECT查询。使用MVC控制器中的实体框架将参数值从视图传递到存储过程。 SQL参数不能直接用于列名,所以我决定使用case语句。问题是没有数据得到返回,所以他们必须在我如何使用语句中出现一些错误。在WHERE子句中为列名使用SQL参数

@topLeftInput varchar(100), 
    @topRightInput varchar(100) 
AS 
BEGIN 
     Select * from test 
      where 
       CASE @topRightInput 
        WHEN 'BasicReturnReasonId' THEN BasicReturnReasonId 
        WHEN 'ClientName' THEN ClientName 
        WHEN 'CreditDeniedReasonId' THEN CreditDeniedReasonId 
        WHEN 'ItemsnotReturnedReasonId' THEN ItemsnotReturnedReasonId 
        WHEN 'ManufacturerId' THEN ManufacturerId 
        WHEN 'ManufacturerOrderNumber' THEN ManufacturerOrderNumber 
        WHEN 'ProductConditionId' THEN ProductConditionId 
           ELSE NULL 
        END 
       = @topRightInput; 
END 

其中进入的值分别为'ProductConditionId'和'3'。

当我为整个查询使用if语句时,我确实有这个工作,但它太过于矫枉过正,并且完全太长了(看起来不像是因为我为了举例而将其裁减)。

下面是我在做什么了第一个选项的例子:

if @topLeftInput = 'BasicReturnReasonId' 
    Begin 
     Select * from test 
      where BasicReturnReasonId = @topRightInput; 
    End 

我怎样才能得到这跟case语句的工作?

谢谢!

+0

其实,刚刚意识到这只是一个错字,应该被关闭。 '@ topRightInput'应该是'@ topLeftInput'。更改完成后正常工作。还早,我只是错过了:/ – cfly24

+0

这是一个小技巧,可能会在稍后帮助你。很多时候(但显然不总是)。声明局部变量,将其定义为输入参数的值并在查询中使用局部变量要好得多。直接使用输入参数可能会导致重新编译问题,我发现速度减慢了数量级。 – SteveJ

+0

好的,谢谢你的提示 – cfly24

回答

2

一个简单的技术,你可以使用:

DECLARE @QUERY as varchar(max); 
SET @QUERY='Select * from test where '+ @topLeftInput +' = '[email protected] + ' ;' 
EXEC(@QUERY) 

注:这种方法容易受到SQL注入。所以,请确保您使用适当的验证。

+0

**警告**这易受sql注入的影响。 –

1
CREATE PROCEDURE myProc 
    @topLeftInput varchar(100), 
    @topRightInput varchar(100) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(MAX); 

SET @sql = N'Select * from test 
      where ' + 
      CASE @topLeftInput 
       WHEN 'BasicReturnReasonId'  THEN QUOTENAME(N'BasicReturnReasonId') 
       WHEN 'ClientName'    THEN QUOTENAME(N'ClientName') 
       WHEN 'CreditDeniedReasonId'  THEN QUOTENAME(N'CreditDeniedReasonId') 
       WHEN 'ItemsnotReturnedReasonId' THEN QUOTENAME(N'ItemsnotReturnedReasonId') 
       WHEN 'ManufacturerId'   THEN QUOTENAME(N'ManufacturerId') 
       WHEN 'ManufacturerOrderNumber' THEN QUOTENAME(N'ManufacturerOrderNumber') 
       WHEN 'ProductConditionId'  THEN QUOTENAME(N'ProductConditionId') 
      END 
      + N' = @topRightInput;' 

exec sp_executesql @sql 
        ,N'@topRightInput varchar(100)' 
        ,@topRightInput 

END 

如果参数@topLeftInput有列名的精确值,那么它就更简单

CREATE PROCEDURE myProc 
    @topLeftInput varchar(100), 
    @topRightInput varchar(100) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(MAX); 

SET @sql = N'Select * from test 
      where ' + QUOTENAME(@topLeftInput) + N' = @topRightInput;' 

exec sp_executesql @sql 
        ,N'@topRightInput varchar(100)' 
        ,@topRightInput 

END