2012-10-25 44 views
1

我有一个字符串保持逗号分隔值=值1,值2,值3 .......替代使用SQL IN在此查询

我想执行以下操作:

SELECT col FROM table WHERE col IN :values 

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

是否有任何替代方法来执行此查询?编辑: 这是Oracle的商业智能发布应用程序。客户/用户可以使用下面的任何数据库。

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

  • 不能对静态字符串值使用EXISTS。
  • 无法使用存储过程或临时表。
+0

退房'EXISTS' –

+0

什么是您的RDBMS? 对于Oracle,您可以使用游标创建PL SQL函数。虽然这可能是一个过度杀伤力。只是一个想法... –

+0

MySQL,Oracle,PostGreSQL,SQL Server?他们都有不同的能力和语法。这是来自您自己的应用程序的查询吗?或者它是在某种查询管理器中完成的?您的值列表是从另一个表/查询派生的吗?等等,等等?请提供更多细节和上下文。 – MatBailie

回答

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; 
1

最具性能需要一些制作。我会建议建立一个内存临时表,它保存你的值,每一行都在一行中,然后将你的真实表加入到这个临时表中。这将使您的查询速度显着提高,并且作为额外的好处,临时表中的行数不受限制(或者说,仅限于内存)。

0

你可以值插入到一个临时表,然后做一个连接:

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

谢谢@ jalynn2。 我无法控制代码。我所能做的就是从UI屏幕中选择'n'值并使用这些值编写查询。 – hohenhiem

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/

+0

正如你所看到的,我创建了一个临时表并添加了它的所有列,然后获取此临时表内的所有记录,您应该传递一个以逗号分隔的数组 –

+0

假设SQL Server。由于OP使用':values'作为参数,这不太可能是正确的...... – MatBailie

+0

它是sql,因为它在标记:),并且它将在传递的参数是cols逗号分隔的数组的情况下起作用 –

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',',') 

(呵呵,这是BTW的MS SQL Server数据库)

+0

由于OP使用':values'作为参数,假设SQL Server不太可能是正确的... – MatBailie

+1

啊公平的做的,我想知道那是什么语法。噢,今天有一些得分的尝试...... – Ted