2

使用 SQL Server 我试图基于 if 语句将字符串注入 SQL 语句,请注意我试图在存储过程中完成此操作。

我目前收到此代码的错误:

Declare @topString varchar(240)

IF @topRecords > 0
SET @topString = 'top 500'
ELSE
SET @topString = ''

SELECT @topString * FROM( //incorrect syntax near FROM

SELECT  top 500 c.Id as [Customer Id],....
    UNION
    SELECT  top 500 c.Id as [Customer Id],....
)as table1 
Order by 1 desc

编辑

if somethingTrue
@whereCondition = '1 = 1 '
else 
@whereCondition = branch = @branch

select * from table 
where @whereCondition AND etc...

正确的

对于 if 语句中的注入,请使用 Jodrell
,但如果您需要动态顶部,请使用 Kaf 建议的内容。
谢谢你们的帮助!

4

2 回答 2

4

如果您愿意decide number of top records depending on @topRecords,您可以使用INTBIGINT根据所需记录的数量来执行此操作。

DECLARE @top INT --This is declared as an int here

IF @topRecords > 0
  SET @top = 500
ELSE
  SET @top = 5000000 --Make it more than records if you need all 
                              --or make it 0 if no records needed.
                              --@top has to be >=0

--How to use it
SELECT TOP (@top) * FROM YourTable

编辑:您的问题最初只有一次注射。但是,如果您需要更多注射(根据您最近的问题编辑),那么我建议您使用动态查询@Jordell's answer.

于 2012-12-07T09:50:01.070 回答
3

您不能将语句部分作为变量注入,但是您可以更改参数的大多数值。

让存储过程根据参数执行可能需要不同查询计划的操作是一个坏主意,此 SP 的结果可能会根据@topRecords参数的值而大不相同。您将需要使用该RECOMPILE选项来警告查询引擎,从而减少 SP 的大部分好处。您是否考虑过只有两个存储过程?

如果你想动态地做,你可以动态地构建整个语句,创建一个大字符串,然后执行它。

您应该调查使用sp_executesql来执行string/ VarChar。然后类似的查询将受益于查询计划重用。

一如既往,Sommarskog 是一个很好的参考


像这样的东西

DECLARE @topString varchar(240);
DECLARE @statement varchar(max);

IF @topRecords > 0
    SET @topString = 'TOP 500';
ELSE
    SET @topString = '';

SET @statement = 'SELECT ' + @topString + ' * FROM
    (
        SELECT TOP 500 c.Id as [Customer Id], ....
        UNION
        SELECT TOP 500 c.Id as [Customer Id], ....
    ) table1 
    ORDER BY 1 DESC'

/* Then execute @statement */
EXEC sp_executesql @statement
于 2012-12-07T09:44:19.213 回答