我在Windows窗体应用程序中有更多控件(假设有10个带文本框,下拉列表,单选按钮的控件),用于过滤所有非强制性的数据,因此用户可以使用1个或更多控件过滤数据。
现在我必须根据输入创建一个过滤数据的存储过程。
例如:如果用户在1个文本框控件中输入了一些文本,并将剩余的9个控件保留为空数据,则必须仅根据用户输入的文本框过滤数据。
如果用户在1个文本框控件和1个下拉列表中输入了一些文本,剩下的8个控件中包含空数据,我必须仅根据用户输入的文本框和下拉列表来过滤数据。
我应该做什么?
源代码:
如果用户在任何控件上输入/选择了文本,我将值作为参数传递,否则我传递为“null”以保留所有其他参数。
在存储过程中:
我提供了所有10个控件参数,以根据我过滤数据的参数从源代码中获取值。
if @Param1=null && @Param2=null && @Param3='SomeText'
begin
sELECT * FROM tABLE1 wHERE TableCOLUMN3=@Param3
END
if @Param1=null && @Param2='SomeText' && @Param3='SomeText'
begin
sELECT * FROM tABLE1 wHERE TableCOLUMN2=@Param2 AND TableCOLUMN3=@Param3
END
注意:我需要将每个表列的数据过滤到每个参数,只需假设@Param1 - TableCOLUMN1,@ param2 - TableCOLUMN2,过滤器的变化取决于参数文本。
如果我这样做,我的存储过程会更加庞大而且非常大,因为我有10个参数需要检查(仅供参考,我在样本上面提供了3个参数)。
我想要的是:
由于我提供了10个参数,基于具有值的参数(某些文本不是NULL),我只需要使用where条件过滤数据。
有没有其他方法可以做到这一点,或者有没有其他方法可以做到这一点?
答案 0 :(得分:1)
我会建议这样的事情:
SELECT *
FROM TABLE1
WHERE TableCOLUMN1=ISNULL(@Param1,TableCOLUMN1)
AND TableCOLUMN2=ISNULL(@Param2,TableCOLUMN2)
AND TableCOLUMN3=ISNULL(@Param3,TableCOLUMN3)
AND TableCOLUMN4=ISNULL(@Param4,TableCOLUMN4)
... and so on...
如果指定了param1,这将过滤一个值的column1,否则它将使用始终为true的columnvalue本身。 但是,只有在你不使用它们的情况下,如果@Param值在每种情况下都为NULL,那么这只会起作用。
答案 1 :(得分:1)
只要你使params默认为null并且不传递你不需要的params的值或传入dbnull值,那么你可以像这样过滤
CREATE PROC dbo.SAMPLE
(
@Param1 VARCHAR(255) = NULL,
@Param2 VARCHAR(255) = NULL,
@Param3 VARCHAR(255) = NULL,
@Param4 VARCHAR(255) = NULL,
@Param5 VARCHAR(255) = NULL,
@Param6 VARCHAR(255) = NULL
)
AS
BEGIN
SELECT *
FROM Table1
WHERE (@Param1 IS NULL OR TableCOLUMN1 = @Param1)
AND (@Param2 IS NULL OR TableCOLUMN2 = @Param2)
AND (@Param3 IS NULL OR TableCOLUMN3 = @Param3)
AND (@Param4 IS NULL OR TableCOLUMN4 = @Param4)
AND (@Param5 IS NULL OR TableCOLUMN5 = @Param5)
OPTION (RECOMPILE) -- as JamesZ suggested to prevent caching
END
EXEC dbo.SAMPLE @Param2 = 'SomeText' -- only filter where TableCOLUMN2 = @Param2
答案 2 :(得分:1)
如果表很大/你需要使用索引来获取行,那么这种逻辑的问题是,索引真的无法使用。基本上有两种方法可以做到:
通过@Ionic或@ user1221684将option (recompile)
添加到select语句的末尾。这将导致语句重新编译每次执行,如果经常调用它,可能会产生大量的CPU开销。
创建动态SQL并使用sp_executesql
示例:
set @sql = 'SELECT * FROM TABLE1 WHERE '
if (@Param1 is not NULL) set @sql = @sql + 'TableCOLUMN1=@Param1 AND '
if (@Param2 is not NULL) set @sql = @sql + 'TableCOLUMN2=@Param2 AND '
if (@Param3 is not NULL) set @sql = @sql + 'TableCOLUMN3=@Param3 AND '
-- Note: You're not concatenating the value of the parameter, just it's name
set @sql = @sql + ' 1=1' -- This handles the last 'and'
EXEC sp_executesql @sql,
N'@Param1 varchar(10), @Param2 varchar(10), @Param3 varchar(10)',
@Param1, @Param2, @Param3
作为一个额外的选项,你可以在你的原始想法和完全动态的想法之间进行某种混合,这样它至少可以处理最常见的搜索标准,从而可以有效地获取。