2

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

我想执行以下操作:

SELECT col FROM table WHERE col IN :values

如果值的条目少于 1000 个,这可以正常工作。当值有超过 1000 个条目时,它会出错。IN 的使用有限制。

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

编辑:它是 Oracle 的商业智能发布者应用程序。客户/用户可以使用下面的任何数据库。

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

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

5 回答 5

2

最大的性能需要一些精心制作。我建议建立一个内存临时表来保存你的值,每一个都在一行中,然后将你的真实表加入到这个临时表中。这将使您的查询显着更快,并且作为额外的好处,临时表中的行数不受限制(或者更确切地说,仅受内存限制)。

于 2012-10-25T12:39:45.420 回答
2

如果您无法创建全局临时表,则可以将分隔列表转换为使用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;
于 2012-10-25T20:27:35.320 回答
0

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

SELECT col from table t1 JOIN #temp t2 WHERE table.col = t2.col;
于 2012-10-25T12:40:42.530 回答
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/

于 2012-10-25T12:42:02.370 回答
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 数据库顺便说一句)

于 2012-10-25T12:43:49.157 回答