1

更新: 誰かがこの質問を 「文字列を分割して項目 x にアクセスできるようにする方法」の重複としてマークしました。私の質問は Sybase SQL Anywhere に関するもので、もう 1 つは MS SQL Server に関するものです。これらは 2 つの異なる 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ループを使用して独自の関数を作成し、各要素を区切り位置検索による分割に基づいて抽出し、関数が結果として返す一時テーブルに要素を挿入することです。

4

5 に答える 5

5

これは動的 SQL を使用しなくても実行できますが、いくつかのサポート オブジェクトを作成する必要があります。最初のオブジェクトは、文字列を解析して整数のテーブルを返すテーブル値関数です。2 番目のオブジェクトは、文字列 (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'

これが役立つことを願っています...

于 2013-10-12T15:34:11.913 に答える
2

Mikael Erikssonが言ったように、 dba.stackexchange.comには 2 つの非常に優れたソリューションがあり、最初はsa_split_listシステム プロシージャを使用し、2 つ目はCASTステートメントを使用して遅くなります。

Sybase SQL Anywhere 9 のsa_split_listシステム プロシージャが存在しないため、システム プロシージャを置き換えました ( bsivelsa_split_list answerのコードの一部を使用しました)。

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デフォルトの delimiter と同じ方法で実行し,ます。

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', ',')
于 2013-12-28T16:35:02.650 に答える
-1

動的クエリのアプローチは次のようになります。

create procedure ShowData @IdList VarChar(255)
as
  exec ('use yourDatabase; select * from MyTable where Id in ('+@IdList+')')
于 2013-10-12T15:53:03.403 に答える