【问题标题】:SQL LIKE % FOR INTEGERSSQL LIKE % FOR INTEGERS
【发布时间】:2011-05-03 05:58:08
【问题描述】:

在 T-SQL 中,如何编写查询来为列的任何整数值选择行??

比如数据是这样的

NAME,AGE
A,10
B,20
C,10
D,20

还有一个<asp:dropdownlist> 有两个选项10,20,因此用户可以选择1020。如果用户选择1020,则数据被正确拉取,但我如何说* 条件? - 就像为age 列中的任何值选择所有数据一样??

我的代码如下,

select ...where (AGE = @AGE)

<SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="AGE" PropertyName="SelectedValue" DbType="Int32" DefaultValue="ANY"

另外,跟随查询在 SSMS 中完美运行,但是如何在 asp.net SqlDataSource 中实现此行为?

SELECT * FROM [TABLE] where AGE is not null

如果 AGE 列是 varchar 类型,我可以使用 '%',但它是一个数字字段

谢谢,

【问题讨论】:

  • 为什么不跳过 WHERE 子句?如果你想选择任何年龄,我不明白你为什么要添加一个条件。
  • 我想将它放在 WHERE 子句中,因为如果用户从下拉列表中选择一个值,则需要提取数据。从 WHERE 中删除它会有效地使下拉列表无用..
  • @user331225 不,您将“ANY”添加为下拉框中的第一个(或最后一个)选项。然后您的代码会检查用户是否选择了“ANY”字段。如果他这样做了,您就不会在 SQL 中添加 where age=@age。如果用户选择了任何其他选项,则添加 where 子句。
  • 无论用户选择什么,您是否都尝试对所有情况使用一个 SQL 查询?

标签: asp.net sql sql-server tsql


【解决方案1】:

回答最初的问题,或者至少回答“SQL LIKE % FOR INTEGERS”问题的标题,因为会有其他人因为标题而来到这个页面——就像我一样。

假设您有表“年龄”

NAME,AGE
A,10
B,20
C,10
D,20
E,11

如果你想要所有年龄在 10-19 岁或四舍五入 (*0) 的人,你需要一个 LIKE % FOR INTEGERS 这是如何使用子查询来完成的:

SELECT * FROM (SELECT CAST(AGE AS VARCHAR) as Age FROM Ages) tmp where Age like '1%'

SELECT * FROM (SELECT CAST(AGE AS VARCHAR) as Age FROM Ages) tmp where Age like '%0'

玩得开心

【讨论】:

    【解决方案2】:

    无论用户选择什么,您是否都尝试对所有情况使用一个 SQL 查询? 根据用户选择使用两个不同的查询会容易得多。当用户选择“ANY”时

    SELECT * FROM Table WHERE @Age > 0 
    

    这将匹配所有年龄。

    【讨论】:

      【解决方案3】:

      仅使用声明性数据源的标准答案是在 SQL 语句中使用 OR 子句

      WHERE (age = @age OR @age = -1)
      

      对于某些列类型,您需要与 NULL 进行比较,但您已经声明 -1 是此应用程序中此列的标记值。密切关注性能,最终您可能希望切换到动态 sql,但这种技术适用于大多数中等大小的数据集。

      【讨论】:

        【解决方案4】:

        如果您想要一个查询,您可以在其中传递一个参数并同时处理这两个条件,那么您可以使用类似

        Select Name, Age from 
        (
              SELECT 
               (CASE 
                WHEN @p1 = '*' THEN '*'   
                ELSE    CONVERT(NVarChar,Age)
                END) AS SearchCriteria, 
                Name, 
                Age
            FROM table
         ) 
         t
         where SearchCriteria = @p1
        

        参数必须是 NVarchar,但可以是 '*' 或 '10' 或 '20'

        警告。性能不会很好(好吧,如果表有很多行会很糟糕)。如果您希望所有年龄都不需要将所有内容转换为字符串,则使用 0 值可能会更好。

        【讨论】:

          【解决方案5】:

          您应该将其添加为可选的选择子句,例如...

          SELECT *
          FROM <Table>
          WHERE (@Age is Null OR @Age = '' OR @Age = Age)
          

          现在,如果您为年龄返回 null 或空白值,它将被忽略。

          【讨论】:

            【解决方案6】:

            典型的做法是从返回所有结果的基本查询开始:

            string sql = "SELECT * FROM [TABLE] WHERE 1=1";
            

            然后,如果您选择了可选参数,请添加到字符串中。

            sql += " AND AGE = @age";
            

            1=1 的计算结果始终为真,因此它可以消除是否需要在可选条件之前放置 AND 的决定。

            要在 SqlDataSource 中执行此操作,您可能会混合使用我的方法和 OMG Ponies 方法:

            datasource.SelectCommand = "SELECT * FROM [TABLE] WHERE 1=1 AND (AGE = @age OR @age = -1)";
            

            【讨论】:

            • hmm... 但“AND AGE=@age”仍然计算为某个年龄值,但不是年龄中的所有值。例如,如果@age=x,则 sql有效地变为...AND AGE=x,但我想满足 AGE 为 x 或 y 或 z 的情况 - AGE 的所有值。
            • 我刚刚更新,当你不需要过滤器时,使用 OR 和一个哨兵值。
            • 你需要括号包围 OR
            • no.. 它也不起作用。因为WHERE 1=1 OR AGE=@age@age的值会被完全忽略——基本上不会影响查询处理。
            • 我实际上写了AND age = @age。那是完全不同的。
            【解决方案7】:

            看看这是否适合你。 将“ANY”变成NULL,并使用COALESCE来匹配AGE。

            如果“param”是“ANY”,那么我们把它变成NULL,然后返回“age”,这样一切都匹配。如果 "param" 是其他任何内容,则只会返回匹配年龄的行。

            CREATE TABLE #table (
              age int
            )
            GO
            
            INSERT INTO #table VALUES (10)
            INSERT INTO #table VALUES (20)
            INSERT INTO #table VALUES (30)
            GO
            
            DECLARE @param varchar(10)
            SET @param = 10
            SELECT * FROM #table WHERE age = @param
            
            SET @param = 'ANY'
            SELECT * FROM #table WHERE age = COALESCE(NULLIF(@param,'ANY'),age)
            

            结果

            age
            -----------
            10
            
            (1 row(s) affected)
            
            age
            -----------
            10
            20
            30
            
            (3 row(s) affected)
            

            【讨论】:

            • 为什么不让@param 为NULL?如果需要进行 NULL 比较,age = age 将不起作用
            • 我的假设。原始查询排除了 NULL,所以我假设不会查询 NULL。选择“ANY”是因为它是 DropDownList1 中的 DefaultValue,用于选择要显示的年龄。如果此解决方案由于某种原因不起作用,OP 可以提供更多详细信息。
            【解决方案8】:

            要提供 ALL/ANY 选项,您需要指定一个标记值 - 一个永远不会存在于数据集中的值 - 这样您就可以检查提交给存储过程的变量,以便了解何时忽略变量并使用正确的 WHERE 子句。

            IE:如果下拉列表中有一个显示文本为“All”的元素,并且值为 -1,则以下动态 SQL 将是合适的:

            DECLARE @SQL NVARCHAR(MAX)
            
               SET @SQL = N'SELECT * 
                              FROM [YOUR_TABLE]
                             WHERE 1 = 1 '
            
               SET @SQL = @SQL + CASE 
                                   WHEN @age > 0 THEN 
                                     ' AND age = @age '
                                   ELSE 
                                     ' AND age IS NOT NULL '
                                 END
            
            BEGIN
            
              EXEC sp_executesql @SQL N'age INT', @age
            
            END
            

            this link for more details about dynamic SQL in TSQL/SQL Server

            但您不必使用动态 SQL - 这是等效的:

            IF @age > 0 
            BEGIN
            
               SELECT * 
                 FROM [YOUR_TABLE]
                WHERE age IS NOT NULL
            
            END
            ELSE
            BEGIN
            
               SELECT * 
                 FROM [YOUR_TABLE]
                WHERE age = @age
            
            END
            

            ...如果您有多个相互独立的参数,您可以想象这会变得多么笨拙。

            【讨论】:

            • 你想太多了。许多“AND (@age = age OR @age
            • @mootinator:不,因为您提供的内容是不可分割的。我非常了解这种方法——我不得不在许多场合中删除它,因为它的性能很糟糕。
            • 嗯,你有没有在什么地方解释过这个?我很感兴趣。我继承了一个充满这些类型条件的代码库,其中一些似乎确实表现得莫名其妙。
            • @mootinator:你的桌子有多大?以及多少个参数?我记得的参数超过十个,针对有 100K+ 行的表......
            • 我不明白为什么 1=1 没问题,但 @age = 1 是 baaad。
            【解决方案9】:

            不要在where中包含它

            【讨论】:

            • 我想将它放在 WHERE 子句中,因为如果用户从下拉列表中选择一个值,则需要提取数据。从 WHERE 中删除它会有效地使下拉列表无用..
            猜你喜欢
            • 2011-06-28
            • 1970-01-01
            • 1970-01-01
            • 2023-02-12
            • 1970-01-01
            • 1970-01-01
            • 2010-09-05
            • 2014-07-17
            • 2017-12-08
            相关资源
            最近更新 更多