【问题标题】:SQL stored procedure IN clause varchar arraySQL 存储过程 IN 子句 varchar 数组
【发布时间】:2013-07-29 04:37:36
【问题描述】:

我有一个 c# 程序,想给存储过程一个参数。我的 c# 程序中的字符串类似于“'Food','Clothes','Blood'”。

ALTER PROCEDURE [dbo].[GetLocations]
    @longMax float =100,
    @longMin float=0,
    @latMax float=100,
    @latMin float=0,
    @categoryFilter char(200) = ''
AS
BEGIN
    SET NOCOUNT ON;

    SELECT *
    FROM dbo.Locations
    WHERE longitude BETWEEN @longMin AND @longMax
      AND latitude BETWEEN @latMin AND @latMax
      AND subCategory in (@categoryFilter) 
END

结果应该给我 3 个条目,但结果是空的。我试图用另外两个 ' 来转义参数,但结果没有任何变化。

它适用于其他列上的 int 值,但不适用于 chars。

如果有人能帮忙,那就太好了:)

【问题讨论】:

    标签: c# sql sql-server in-clause


    【解决方案1】:

    我认为您需要拆分字符串参数-

    DECLARE @categoryFilter VARCHAR(200) = 'Food,Clothes,Blood'
    
    SELECT t.c.value('.', 'VARCHAR(50)')
    FROM (
         SELECT ID = CAST ('<M>' + REPLACE(@categoryFilter, ',', '</M><M>') + '</M>' AS XML)
    ) r 
    CROSS APPLY ID.nodes ('/M') t(c)
    

    您的查询 -

    ALTER PROCEDURE [dbo].[GetLocations] 
    
    @longMax FLOAT = 100,
    @longMin FLOAT = 0,
    @latMax FLOAT = 100,
    @latMin FLOAT = 0,
    @categoryFilter VARCHAR(200) = 'Food,Clothes,Blood'
    
    AS
    BEGIN
         SET NOCOUNT ON;
    
         SELECT *
         FROM dbo.Locations
         WHERE longitude BETWEEN @longMin AND @longMax
              AND latitude BETWEEN @latMin AND @latMax
              AND (
                   @categoryFilter = '' 
                   OR 
                   subCategory IN (
                        SELECT t.c.value('.', 'VARCHAR(50)')
                        FROM (
                             SELECT ID = CAST ('<M>' + REPLACE(@categoryFilter, ',', '</M><M>') + '</M>' AS XML)
                        ) r 
                        CROSS APPLY ID.nodes ('/M') t(c))
              )
    
    END
    

    【讨论】:

      【解决方案2】:

      你可以使用 LIKE:

      ALTER PROCEDURE [dbo].[GetLocations]
          @longMax float =100,
          @longMin float=0,
          @latMax float=100,
          @latMin float=0,
          @categoryFilter char(200) = ''
      AS
      BEGIN
          SET NOCOUNT ON;
      
          SELECT *
          FROM dbo.Locations
          WHERE longitude BETWEEN @longMin AND @longMax
            AND latitude BETWEEN @latMin AND @latMax
            AND @categoryFilter LIKE '%' + subCategory + '%'
      END
      

      【讨论】:

        【解决方案3】:

        你得到一个空白的结果集,因为in clause 使用数据集。 你正在传递一个 200 个单词的字符串。 您的查询实际上是在比较 subCategory 和 categoryFilter

        您可以通过提供如下设置在管理工作室中明确尝试

        SELECT *
        FROM dbo.Locations
        WHERE longitude BETWEEN @longMin AND @longMax
        AND latitude BETWEEN @latMin AND @latMax
        AND subCategory in ('abc','bcd','cde');
        

        abc- 你的第一个类别过滤器,类似地 bcd 你的第二个等等。 如果您在@categoryfilter 中有一组用逗号(,)分隔的数据,则首先拆分该字符串,然后使用IN Clause

        【讨论】:

          【解决方案4】:

          尝试修剪传入的字符串 -> RTRIM(@string)。

          如果你使用的是 char,你总是需要修剪。

          【讨论】:

            【解决方案5】:

            试试这个

            ALTER PROCEDURE [dbo].[GetLocations]
            @longMax float =100,
            @longMin float=0,
            @latMax float=100,
            @latMin float=0,
            @categoryFilter char(200) = ''
            AS
            BEGIN
                SET NOCOUNT ON;
               SET @categoryFilter =  REPLACE(@categoryFilter,',',''',''')
            
               DECLARE @QUERY VARCHAR(MAX)
               SET @QUERY = 'SELECT *
                FROM dbo.Locations
                WHERE longitude BETWEEN @longMin AND @longMax
                  AND latitude BETWEEN @latMin AND @latMax
                  AND subCategory in ('''+RTRIM(@categoryFilter)+''')'
            
                --PRINT (@QUERY) 
            
                EXEC (@QUERY) 
            
            
            END
            

            【讨论】:

              【解决方案6】:

              你可以尝试如下

              ALTER PROCEDURE [dbo].[GetLocations]
                  @longMax float =100,
                  @longMin float=0,
                  @latMax float=100,
                  @latMin float=0,
                  @categoryFilter char(200) = '',
                  @Query varchar(2000)
              
              AS
              BEGIN
                  SET NOCOUNT ON;
              
                  Set @Query = 'SELECT *
                          FROM dbo.Locations
                         WHERE longitude BETWEEN @longMin AND @longMax
                                AND latitude BETWEEN @latMin AND @latMax
                                AND @categoryFilter IN (' + LTRIM(RTRIM(@categoryFilter)) + ')' 
              
                  Exec(@Query)
              
              END
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-09-19
                • 1970-01-01
                • 2014-05-24
                • 2014-01-24
                • 2013-07-12
                相关资源
                最近更新 更多