2012-05-31 31 views
0

我将参数传递给存储过程。其中一个参数是varchar(50),可以是类似" > 5000"" <= 10000"的字符串。包含运算符的SQL条件语句

下面是一些代码:

.... 
.... 
@colourid int = 0, 
@regionid int = 0, 
@sellingPrice varchar(50) = '-1' 
AS 
SELECT 
.... 
.... 
WHERE 
(dbo.tbl_Listings.fld_ColourID = CASE WHEN @colourid = 0 THEN dbo.tbl_Listings.fld_ColourID ELSE @colourid END) 
AND (dbo.tbl_Listings.fld_RegionID = CASE WHEN @regionid = 0 THEN dbo.tbl_Listings.fld_RegionID ELSE @regionid END) 
AND 

如何添加@sellingPrice到哪里办理?我无法模仿int参数的做法,因为它并不总是使用=。我需要说“如果卖价不是-1,那么fld_SellingPrice @ sellingPrice”。

回答

0

您不能直接在SQL中执行此操作 - 参数将不会被解析和解释为带谓词的查询的一部分。

做到这一点(通过运营商)的唯一方法是使用dynamic SQL,它有自己的陷阱。

您可能会考虑传入一个参数,以指定要使用的操作符,并为每个受支持的参数拥有一组if部分 - 这可能比动态SQL更糟。

1

您可以通过使用动态SQL,在本地变量中生成查询,然后通过(最好)sp_executesql执行该查询来实现该目的。

因此,像

DECLARE @sql nvarchar(MAX) 

SET @sql = 'SELECT .... WHERE ' + @sellingPrice 

sp_executesql @sql 

然而,这确实打开你到SQL注入的可能性,因此,你必须要么

一个。请确保程序仅由您完全信任的来电者拨打
b。在程序中添加对形成参数很差的参数的保护,这比听起来要难得多
c。找到一种完全解决问题的方法。

1

如果您知道要使用一组通用比较,我会在您的SP中为每个比较创建一个参数,并根据需要使用它们。所以,你的SP可能

@greaterThan int, 
@lessThan int, 
@equalTo int 

然后在SP你可以做

if @greaterThan IS NULL 
    SELECT @greaterThan = MAX(field) FROM table -- or some arbitrary value that will always evaluate to true 
if @lessThan IS NULL 
    SELECT @lessThan = MIN(field) FROM table 

然后,只需使用那些你WHERE子句。否则,在发布之后,您将不得不通过构建带有WHERE子句片段的SQL字符串来执行动态SQL。

+0

+1避免了动态SQL。 –

1

我会用一个从和一个变量。 所以当你想要小于5000时,设置为变量= 5000并且保留空白

.... 
.... 
@colourid int = 0, 
@regionid int = 0, 
@fromsellingprice int = 5000 
@tosellingprice int = null 
AS 
SELECT 
.... 
.... 
WHERE 
(dbo.tbl_Listings.fld_ColourID = CASE WHEN @colourid = 0 THEN dbo.tbl_Listings.fld_ColourID ELSE @colourid END) 
AND (dbo.tbl_Listings.fld_RegionID = CASE WHEN @regionid = 0 THEN dbo.tbl_Listings.fld_RegionID ELSE @regionid END) 
AND 
sellingPrice >= coalesce(@fromsellingprice, sellingprice) 
and sellingPrice <= coalesce(@tosellingprice, sellingprice) 
+0

+1,或者:'卖价合并(@fromsellingprice,sellingprice)AND coalesce(@tosellingprice,sellingprice)' –

+0

@AndriyM是的,同样的事情。想法是为了避免动态sql,并给出一个更好的替代方案来传递像'<5000'这样的条件varchar,这是对未来问题的解决方法。我想这就是为什么你高举我。 –