创建SQL命令以返回匹配或其他所有内容
我的申请表中有三个复选框。如果用户勾选了框的组合,我想返回与勾选框匹配的框,如果没有勾选框,我只想返回所有内容。我可以用一个SQL命令来实现这一点吗?我建议在WHERE子句中执行以下操作:创建SQL命令以返回匹配或其他所有内容,sql,Sql,我的申请表中有三个复选框。如果用户勾选了框的组合,我想返回与勾选框匹配的框,如果没有勾选框,我只想返回所有内容。我可以用一个SQL命令来实现这一点吗?我建议在WHERE子句中执行以下操作: ... AND (@OnlyNotApproved = 0 OR ApprovedDate IS NULL) 这不是一个SQL命令,但对我来说非常有效。基本上,第一部分检查开关是否已设置(选中复选框)。第二个是选中复选框后的过滤器。在这里,您可以做任何您通常会做的事情。当然。下面的示例假设使用SQL
...
AND (@OnlyNotApproved = 0 OR ApprovedDate IS NULL)
这不是一个SQL命令,但对我来说非常有效。基本上,第一部分检查开关是否已设置(选中复选框)。第二个是选中复选框后的过滤器。在这里,您可以做任何您通常会做的事情。当然。下面的示例假设使用SQL Server,但您得到了要点 您可以使用一些动态SQL轻松地完成这项工作 假设您将复选框作为位值传递给存储过程
DECLARE bit @cb1
DECLARE bit @cb2
DECLARE bit @cb3
DECLARE nvarchar(max) @whereClause
IF(@cb1 = 1)
SET @whereClause = @whereClause + ' AND col1 = ' + @cb1
IF(@cb2 = 1)
SET @whereClause = @whereClause + ' AND col2 = ' + @cb2
IF(@cb3 = 1)
SET @whereClause = @whereClause + ' AND col3 = ' + @cb3
DECLARE nvarchar(max) @sql
SET @sql = 'SELECT * FROM Table WHERE 1 = 1' + @whereClause
exec (@sql)
当然可以。
如果在代码中编写SQL SELECT语句,则只需生成:
WHERE子句
:
选择。。。从…起其中MyTypeID位于(3,5,7)现在,如果您想使用一个存储过程来完成这项工作,那么实现将取决于数据库引擎,因为您需要的是能够传递多个参数。我不建议使用只有3个参数的过程,因为当您添加另一个复选框时,您还必须更改SQL过程。您可以使用动态where子句构建SQL语句:
string query = "SELECT * FROM TheTable WHERE 1=1 ";
if (checkBlackOnly.Checked)
query += "AND Color = 'Black' ";
if (checkWhiteOnly.Checked)
query += "AND Color = 'White' ";
或者,您可以使用变量创建存储过程来执行此操作:
CREATE PROCEDURE dbo.GetList
@CheckBlackOnly bit
, @CheckWhiteOnly bit
AS
SELECT *
FROM TheTable
WHERE
(@CheckBlackOnly = 0 or (@CheckBlackOnly = 1 AND Color = 'Black'))
AND (@CheckWhiteOnly = 0 or (@CheckWhiteOnly = 1 AND Color = 'White'))
....
问题没有指定DB产品或编程语言。但是,它可以用ANSI SQL以跨产品的方式完成 假设一种编程语言使用$var$在字符串上插入变量 在服务器上,您可以在一个列表中获取所有选定的值,因此如果选择了前两个框,则会有一个get/POST变量,如
http://url?colors=black,white
因此,您可以构建这样的查询(伪代码)
您的数据库将看到:
WHERE ('black,white' == '') OR (color IN ('black','white')); -- some selections
WHERE ('' == '') OR (color IN ('')); -- nothing selected (matches all rows)
这是一个有效的SQL查询。当未选择任何内容时,第一个条件将匹配任何行,否则OR语句的右侧将匹配作为颜色之一的任何行。此查询可扩展到无限多个选项,无需修改。每个子句周围的括号也是可选的,但为了清楚起见,我使用了它们
当然,您需要根据需要使用参数或转义来保护字符串不受SQL注入的影响。否则,颜色的恶意值将允许您的DB受到攻击
SELECT *
FROM table
WHERE value IN
(
SELECT option
FROM checked_options
UNION ALL
SELECT option
FROM all_options
WHERE NOT EXISTS (
SELECT 1
FROM checked_options
)
)
内部子查询将返回选中选项的列表,如果列表为空,则返回所有可能的选项
对于MySQL
,最好使用以下选项:
SELECT *
FROM t_data
WHERE EXISTS (
SELECT 1
FROM t_checked
WHERE session = 2
)
AND opt IN
(
SELECT opt
FROM t_checked
WHERE session = 2
)
UNION ALL
SELECT *
FROM t_data
WHERE NOT EXISTS (
SELECT 1
FROM t_checked
WHERE session = 2
)
MySQL
将注意到不可能,其中
在任何一个上选择
,并且只执行适当的一个
有关性能详细信息,请参见我的博客中的此条目:
CREATE PROCEDURE MyCommand
(
@Check1 BIT = NULL,
@Check2 BIT = NULL,
@Check3 BIT = NULL
)
AS
SELECT *
FROM Table
WHERE Column1 = ISNULL(@Check1, Column1)
AND Column2 = ISNULL(@Check2, Column2)
AND Column3 = ISNULL(@Check3, Column3)
为什么?OP不会以这种或那种方式明确说明条件复选框是否为累加筛选器,因此它可以是累加筛选器。在我的示例中,我使用了
和。。。也许他确实想要一个或,这两个问题都没有明确地以这种或那种方式陈述,而是明确地,而不是或。对于动态SQL方法,+1。人们害怕动态SQL,但是智能地使用和参数化它是满足这种需求的最佳解决方案。AND(@MyParam=0或mycl=@MyParam)解决方案将扫描mycl,即使@MyParam=0。Erland Sommarskog写了一本关于动态搜索的书,以防您感兴趣并有几个小时;-)@Eoin&Aaron,在这种情况下为什么要使用动态SQL,我个人认为Thies的方法更好(@Col1Value=1或@Col1Value为NULL),在这种情况下dsql有优势吗?
CREATE PROCEDURE MyCommand
(
@Check1 BIT = NULL,
@Check2 BIT = NULL,
@Check3 BIT = NULL
)
AS
SELECT *
FROM Table
WHERE Column1 = ISNULL(@Check1, Column1)
AND Column2 = ISNULL(@Check2, Column2)
AND Column3 = ISNULL(@Check3, Column3)