SQL Server,将选择机制从“and”转换为变成“或”

发布于 2024-09-08 11:11:27 字数 3823 浏览 4 评论 0原文

我有一个基于网络的程序,它使用复选框列表从数据库中选择一些记录。 (我的复选框列表将参数发送到存储过程,并且我使用存储过程的结果)。

这是我的复选框列表的样子

Overflow              [] (sends param1)
Open Records          [] (sends param2)
Records with 4 groups [] (sends param3)

这是我的存储过程的样子,

SELECT * FROM myRecordsTable WHERE
        (Overflow LIKE '%O%' OR @param1= 'No')
        AND (OpenClose= 'Open' OR @param2= 'No')
        AND (4orMore = '4orMore' OR @param3 = 'No')

如您所见,我的复选框列表的工作方式类似于“与”过程,换句话说,当我在复选框列表中检查“溢出”和“打开记录”时,我的存储过程过程将返回(打开记录,其中有溢出

我喜欢做的是我希望我的复选框列表像“或”一样工作,换句话说,我想要能够获取(打开记录具有溢出的“OR”记录)

重要PS:我不能有两个存储过程(1用于OR,1用于AND),因为我的程序并不像上面的示例那么短,因为一旦我在一个程序中更改了某些内容,我就必须在第二个程序中进行完全相同的更改,这不是一个好的编码。

重要 PS2:我不想破坏存储过程的结构。我想随时使用我的存储过程作为“AND”或“OR”(可能使用另一个参数),我尝试执行此操作的方式是使用动态sql,如下面的链接所示

SQL Server,可以 T -SQL 运算符可以像变量一样使用吗?或者类似的事情

,但我无法解决它。

感谢您的帮助。

编辑:这里我将举一个例子来更清楚地展示问题

下面的代码,在checkboxlist中没有选择任何内容,返回42703(记住这个数字)行

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''No''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

下面的代码选择了ASIM ,返回9349

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

我不再给出相同的代码,因为逻辑是相同的,当复选框列表被选中时,“否”变成“是”,这就是结构代码。

选择 ASIM 和 SonGrup 将返回 5885 行 ASIM 和 SonGrup 和 DortUzeri 被选择返回 1385

上面的代码与 AND 完美配合,所以当我想使用 OR 运算符时,我应该得到结果 37696 ,这是下面代码的结果

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup' OR DortUzeri LIKE 'Dört ve Üzeri'

因此,我使用 OR 运算符执行了代码,其中选择了三个复选框列表组件,代码如下,它返回 37696 ,这是正确的。

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''Yes''=''No'') '
exec(@query)

当未检查清单组件之一时,就会出现问题,这是代码的第三个组件未检查版本,

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

上面的代码应该返回 34613 ,我使用以下代码发现它

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup'

,但它返回 42703 (我想让你记住的数字是因为 ''No''=''No'' 引起的),这就是我的问题出现的地方。在这里我找不到解决方案。

I have a web based program which chooses some records from a database using a checkboxlist. (my check box list sends parameters to a stored procedure and I use the result of stored procedure).

Here how my check box list looks like

Overflow              [] (sends param1)
Open Records          [] (sends param2)
Records with 4 groups [] (sends param3)

Here how my stored procedure looks like,

SELECT * FROM myRecordsTable WHERE
        (Overflow LIKE '%O%' OR @param1= 'No')
        AND (OpenClose= 'Open' OR @param2= 'No')
        AND (4orMore = '4orMore' OR @param3 = 'No')

So as you can see, my check box lists works like "And" procedure, in other words, when I check Overflow and Open records in my checkboxlist, my stored procedure will return (Open records which has Overflow)

What I like to do is I want my check box list to work like "Or", in other words, I want to be able to get (Open records "OR" records which has Overflow)

Important PS: I can't have two stored procedures (1 for OR and 1 for AND) since my procedures are not that short like the example above, because once I change something in one procedure I will have to do the exact same changes in the second one and that is not good coding.

Important PS2: I don't want to corrupt the structure of the stored procedure. I want to use my stored procedure as "AND" or "OR" whenever I want (using another parameter maybe), and the way I tried to do this was using dynamic sql as in the link below

SQL Server, Can a T-SQL operator be used like a variable ? Or something like that

but I couldn't manage to solve it.

Thanks for helps.

Edit: Here I will give an example to show the problem more clearly

Below code, nothing is selected in checkboxlist, returns 42703 (Remember this number) rows

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''No''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

Below code ASIM is selected, returns 9349 rows

declare @op varchar(3)
set @op = 'AND'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

I won't give the same code anymore, because the logic is same, the "No" turns into "Yes" when the checkbox list is selected, and this is the structure of the code.

ASIM and SonGrup is selected returns 5885 rows
ASIM and SonGrup and DortUzeri is selected returns 1385 rows

The above code works perfectly with AND, so when I wanted to use OR Operator I should get the result 37696 , which is the result of the below code

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup' OR DortUzeri LIKE 'Dört ve Üzeri'

So I executed the code with OR operator where the three checkbox list components is selected, the code is below and it returns 37696 , which is correct.

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''Yes''=''No'') '
exec(@query)

The problem arises when one of the checklist components is not checked, here is the 3rd component is not checked version of the code,

declare @op varchar(3)
set @op = 'OR'

declare @query nvarchar(4000)
set @query = 
'
SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
'
set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' 

set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' '

set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') '
exec(@query)

The above code should have returned 34613 which I found using the following

SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE
ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup'

However it returns 42703 (The number which I wanted you to remember caused because of ''No''=''No'') , that is where my problem arises. Here I couldn't find the solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

难忘№最初的完美 2024-09-15 11:11:27

您应该使用动态 sql - 并且语法更容易理解,这也将使您的查询有更好的执行机会。

如果可以的话,我可能会在您的应用程序中而不是在存储过程中构造动态sql,但是如果您确实必须调用存储过程,那么这也可以:

免责声明:我通常从不写存储过程中的动态 SQL,并且我也没有在这台计算机上安装 SQL Server 以确保以下功能正常工作,但希望这应该有一些帮助:需要

declare @op varchar(3)

IF @operator = "AND"
    set @op = "AND"
ELSE
    set @op = "OR"

declare @query varchar(max)
set @query = "select * from myRecordsTable WHERE" +

IF @param1 <> "No"
    set @query = @query + " Overflow LIKE '%O%' " + @op
IF @param2 <> ' No'
    set @query = " OpenClose = 'Open' " + @op

IF @operator = "AND"
    set @query = @query + " 1=1"
IF @operator = "OR"
    set @query = @query + " 1=0"

exec(@query)

注意的重要部分:

  • 我测试 的值@operator 显式避免 SQL 注入(永远不要相信你的调用者)
  • 我使用 1=11=0 来避免由于不知道而使用运算符的复杂逻辑我的哪个条件是第一个或最后一个。 SQL Server 优化器将在优化过程的早期将其优化为同义反复。

You should use dynamic sql - as well as the syntax being easier on the eye it will also give your query a better chance of performing.

If you can, then I would probably construct the dynamic sql in your application rather than in the stored procedure, however if you really have to call a stored procedure then that also works:

Disclaimer: I never usually write dynamic SQL inside a stored procedure, and I also don't have SQL server installed on this machine to make sure that the following works, however hopefully this should be of some help:

declare @op varchar(3)

IF @operator = "AND"
    set @op = "AND"
ELSE
    set @op = "OR"

declare @query varchar(max)
set @query = "select * from myRecordsTable WHERE" +

IF @param1 <> "No"
    set @query = @query + " Overflow LIKE '%O%' " + @op
IF @param2 <> ' No'
    set @query = " OpenClose = 'Open' " + @op

IF @operator = "AND"
    set @query = @query + " 1=1"
IF @operator = "OR"
    set @query = @query + " 1=0"

exec(@query)

Important parts to note:

  • I test the value of @operator explicitly to avoid SQL injection (never trust your caller)
  • I use 1=1 and 1=0 to avoid complicated logic with operators due to not knowing which of my conditions will be the first or the last. SQL server optimiser will optimise this away as a tautology early in the optimisation process.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文