使用Sybase SQL Anywhere拆分/分隔逗号分隔的字符串

时间:2013-10-12 12:50:45

标签: sql tsql split sybase sqlanywhere

  

更新       有人将此问题标记为重复       How do I split a string so I can access item x。       但它有所不同,我的问题是关于Sybase SQL Anywhere,另一个是关于MS SQL Server。这是两个不同的SQL引擎,即使它们具有相同的来源,它们也有不同的语法。所以它不重复。我首先在描述和标签中写道,它完全是关于 Sybase SQL Anywhere

我有字段id_list='1234,23,56,576,1231,567,122,87876,57553,1216'

我希望用它来搜索IN这个字段:

SELECT * 
FROM table1
WHERE id IN (id_list)
  • idinteger

  • id_listvarchar/text

但是这样做不起作用,所以我需要以某种方式将id_list拆分为选择查询。

我应该在这里使用什么解决方案?我正在使用T-SQL Sybase ASA 9数据库(SQL Anywhere)。

我看到这个,就是用while循环创建自己的函数, 并且每个元素提取基于分隔符位置搜索, 然后将元素插入到临时表中,该函数将返回结果。

5 个答案:

答案 0 :(得分:4)

这可以在不使用动态SQL的情况下完成,但您需要创建一些支持对象。第一个对象是一个表值函数,它将解析您的字符串并返回一个整数表。第二个对象是一个存储过程,它将有一个参数,您可以在其中传递字符串(id_list),将其解析为表,然后最终将其连接到您的查询。

首先,创建解析字符串的函数:

CREATE FUNCTION [dbo].[String_To_Int_Table]
(
         @list NVARCHAR(1024)
       , @delimiter NCHAR(1) = ',' --Defaults to CSV
)
RETURNS
    @tableList TABLE(
       value INT
       )
AS

BEGIN
   DECLARE @value NVARCHAR(11)
   DECLARE @position INT

   SET @list = LTRIM(RTRIM(@list))+ ','
   SET @position = CHARINDEX(@delimiter, @list, 1)

   IF REPLACE(@list, @delimiter, '') <> ''
   BEGIN
          WHILE @position > 0
          BEGIN 
                 SET @value = LTRIM(RTRIM(LEFT(@list, @position - 1)));
                 INSERT INTO @tableList (value)
                 VALUES (cast(@value as int));
                 SET @list = RIGHT(@list, LEN(@list) - @position);
                 SET @position = CHARINDEX(@delimiter, @list, 1);

          END
   END   
   RETURN
END

现在创建存储过程:

    CREATE PROCEDURE ParseListExample
    @id_list as nvarchar(1024)
    AS
    BEGIN

    SET NOCOUNT ON;

    --create a temp table to hold the list of ids
    CREATE TABLE #idTable (ID INT);

    -- use the table valued function to parse the ids into a table.
    INSERT INTO #idTable(ID)
    SELECT Value FROM   dbo.String_to_int_table(@id_list, ',');

    -- join the temp table of ids to the table you want to query...
    SELECT T1.* 
    FROM table1 T1
    JOIN #idTable T2
    on T1.ID = T2.ID

执行示例:

 exec ParseListExample @id_list='1234,23,56,576,1231,567,122,87876,57553,1216'

我希望这会有所帮助......

答案 1 :(得分:1)

您在查询中使用文本,但这不起作用。 使用动态查询。

答案 2 :(得分:1)

Mikael Eriksson 所说, dba.stackexchange.com 的答案有两个非常好的解决方案,首先使用sa_split_list系统程序,使用CAST语句慢一点。

对于Sybase SQL Anywhere 9 sa_split_list系统过程不存在,所以我更换了sa_split_list系统过程(我使用了来自 bsivel 的代码的部分代码):

CREATE PROCEDURE str_split_list
(in str long varchar, in delim char(10) default ',')
RESULT(
  line_num integer,
  row_value long varchar)
BEGIN
  DECLARE str2 long varchar;
  DECLARE position integer;

   CREATE TABLE #str_split_list (
   line_num integer DEFAULT AUTOINCREMENT,
   row_value long varchar null,
   primary key(line_num));

   SET str = TRIM(str) || delim;
   SET position = CHARINDEX(delim, str);

   separaterows:
   WHILE position > 0 loop
       SET str2 = TRIM(LEFT(str, position - 1));
       INSERT INTO #str_split_list (row_value)
       VALUES (str2);
       SET str = RIGHT(str, LENGTH(str) - position);
       SET position = CHARINDEX(delim, str);
    end loop separaterows;

   select * from #str_split_list order by line_num asc;

END

执行与sa_split_list相同的默认分隔符,

select * from str_split_list('1234,23,56,576,1231,567,122,87876,57553,1216')

或使用可更改的指定分隔符:

select * from str_split_list('1234,23,56,576,1231,567,122,87876,57553,1216', ',')

答案 3 :(得分:0)

bsivel 答案的好贡献,但要概括它(对于其他分隔符而不是逗号),那么行

SET @list = LTRIM(RTRIM(@list))+ ','

必须成为

SET @list = LTRIM(RTRIM(@list))+ @delimiter

第一个版本仅适用于以逗号分隔的列表。

答案 4 :(得分:-1)

动态查询方法如下所示:

create procedure ShowData @IdList VarChar(255)
as
  exec ('use yourDatabase; select * from MyTable where Id in ('+@IdList+')')