在此查询中使用SQL IN的替代方法

时间:2012-10-25 12:36:48

标签: sql database oracle

我有一个字符串,用逗号分隔值= value1,value2,value3 .......

我想执行以下操作:

SELECT col FROM table WHERE col IN :values

如果值少于1000个条目,则此方法可以正常工作。当值超过1000个条目时,它会出错。 IN的使用受到限制。

有没有其他方法可以执行此查询?

编辑: 它是Oracle的Business Intelligence Publisher应用程序。客户/用户可以使用下面的任何数据库。

我无法控制数据库。所以我无法创建临时表或存储过程。我所能做的就是从UI屏幕中选择多个值(它形成逗号分隔的字符串)并在SQL查询中使用它。具体取决于生成的报告。

  • 不能将EXISTS与静态字符串值一起使用。
  • 无法使用存储过程或临时表。

5 个答案:

答案 0 :(得分:1)

性能最高将需要一些精心设计。我建议构建一个内存临时表来保存您的值,每个表都在一行中,然后将您的真实表连接到此临时表。这将使您的查询明显更快,并且作为额外的奖励,临时表中的行数不受限制(或者更确切地说,仅受内存限制)。

答案 1 :(得分:1)

如果您无法创建全局临时表,则可以使用sys.dbms_debug_vc2coll()将分隔列表转换为行并加入此集合。

SELECT t.col 
FROM table t
JOIN TABLE(SELECT column_value 
             FROM sys.dbms_debug_vc2coll(:values)) c on t.col = c.column_value;

答案 2 :(得分:0)

您可以将值插入临时表,然后进行连接:

SELECT col from table t1 JOIN #temp t2 WHERE table.col = t2.col;

答案 3 :(得分:0)

创建一个存储过程来为您完成这项工作:

Create PROCEDURE [dbo].[spGetData] 
    -- Add the parameters for the stored procedure here
    @ids nvarchar(MAX)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

CREATE TABLE #TempTable(col int)
while len(@ids) > 0
begin
  insert into #TempTable values (left(@ids, charindex(',', @ids+',')-1))
  set @ids = stuff(@ids, 1, charindex(',', @ids+','), '')
end
    -- Insert statements for procedure here
    select col from table where col in (select col from #TempTable)
END 

来自我的博客:http://alisissa.wordpress.com/2012/10/24/pass-a-comma-separated-list-to-a-stored-procedure/

答案 4 :(得分:0)

我们多年来一直使用以下函数来分割传递给存储过程的CSV字符串。 (道歉,如果它不是最现代,优雅或有效的方式,但它对我们的目的很好)

CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(    
  position int IDENTITY,
  value varchar(8000)   
)
AS
BEGIN
DECLARE @index int 
SET @index = -1 
SET @text = LTRIM(RTRIM(@text))
WHILE (LEN(@text) > 0) 
  BEGIN  
    SET @index = CHARINDEX(@delimiter , @text)  
    IF (@index = 0) AND (LEN(@text) > 0)  
      BEGIN   
        INSERT INTO @Strings VALUES (@text)
          BREAK  
      END  

    IF (@index > 1)  
      BEGIN   
        INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))   
        SET @text = RIGHT(@text, (LEN(@text) - @index))  
      END  
    ELSE 
      SET @text = RIGHT(@text, (LEN(@text) - @index)) 
    END
  RETURN
END

使用它是:

select value from dbo.fn_Split('string1,string2,string3',',')

(哦,这是用于MS SQL Server数据库btw)