0

T-SQL で条件を記述してLIKE、ワイルドカードを含むコンマ区切りのリストを文字列に一致させることは可能ですか。例を挙げてさらに説明しましょう。

フィールド内の URL のリストを区切った次のコマンドがあるとします。

'/, /news/%, /about/'

上記の文字列と一致させたい文字列の例を次に示します。

  1. '/'
  2. '/ニュース/'
  3. '/ニュース/2/'
  4. '/約/'

そして、一致しない文字列を次に示します。

  1. '/コンタクト/'
  2. '/私について/'

私は過去に、分割関数を作成し、それぞれに対して like を実行することでこれを達成しました。ただし、関数をサポートしていない SQL Server CE でクエリを機能させようとしています。

あなたが疑問に思っている場合は、分割機能を使用してそれをどのように達成したかを次に示します。

SELECT Widgets.Id 
FROM Widgets 
WHERE (SELECT COUNT(*) FROM [dbo].[Split](Urls, ',') WHERE @Input LIKE Data) > 0

そして、ここに分割機能があります:

CREATE FUNCTION [dbo].[Split]
(    
    @RowData NVARCHAR(MAX),
    @Separator NVARCHAR(MAX)
)
RETURNS @RtnValue TABLE 
(
    [Id] INT IDENTITY(1,1),
    [Data] NVARCHAR(MAX)
) 
AS
BEGIN 
    DECLARE @Iterator INT
    SET @Iterator = 1

    DECLARE @FoundIndex INT
    SET @FoundIndex = CHARINDEX(@Separator, @RowData)

    WHILE (@FoundIndex > 0)
    BEGIN
        INSERT INTO @RtnValue ([Data])
        SELECT Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))

        SET @RowData = SUBSTRING(@RowData, @FoundIndex + DATALENGTH(@Separator) / 2, LEN(@RowData))
        SET @Iterator = @Iterator + 1
        SET @FoundIndex = CHARINDEX(@Separator, @RowData)
    END

    INSERT INTO @RtnValue ([Data])
    SELECT Data = LTRIM(RTRIM(@RowData))

    RETURN
END

誰かが助けてくれれば幸いです。ありがとう

4

2 に答える 2

2

いくつかのオプションを考えることができます:

  1. セッション キー テーブルを使用します。現在の spid に一致する行を削除し、現在の spid で目的の行を挿入し、SP のテーブルから読み取り、テーブルから (再度) 削除します。

  2. 多くの OR ... LIKE ... 句を含むクエリをクライアントに送信させます。

  3. 関数と同じことを行い、レコードセットを返す SP を作成します。INSERT YourTable EXEC SP @Stringsこれで完了です。

  4. 文字列を分割する派生テーブル メソッド内で numbers-table-charindex-into-string を使用します。

アイデア 3 と 4 を組み合わせた例を使用して、これを少し詳しく説明します。もちろん、関数のコードも適合させることができます。

別のNumbersテーブルを作成します。作成スクリプトの例を次に示します。

--Numbers Table with 8192 elements (keeping it small for CE)
CREATE TABLE Numbers (
   N smallint NOT NULL CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED
);
INSERT Numbers VALUES (1);
WHILE @@RowCount < 4096
   INSERT Numbers SELECT N + (SELECT Max(N) FROM Numbers) FROM Numbers;

SP:

CREATE PROCEDURE dbo.StringSplitRowset
   @String varchar(8000)
AS
SELECT Substring(@String, l.StartPos, l.Chars) Item
FROM (
   SELECT
      S.StartPos,
      IsNull(NullIf(CharIndex(',', @String, S.StartPos), 0) - S.StartPos, 8000)
   FROM (
      SELECT 1 UNION ALL
      SELECT N.N + 1 FROM Numbers N WHERE Substring(@String, N.N, 1) = ','
   ) S (StartPos)
) L (StartPos, Chars);

そして使い方は、パイのように簡単です:

DECLARE @String varchar(8000);
SET @String = 'abc,def,ghi,jkl';
CREATE TABLE #Split (S varchar(8000));
INSERT #Split EXEC dbo.StringSplitRowset @String;
SELECT * FROM #Split;

結果:

abc
def
ghi
jkl

最後に、数値表を作成したくない場合は、この SP を使用できます。これら 2 つの SP のうちの 1 つが十分に機能することがわかると思います。同様に機能する可能性のある文字列分割の他の実装があります。

ALTER PROCEDURE dbo.StringSplitRowset
  @String varchar(8000)
AS
SELECT Substring(@String, l.StartPos, l.Chars) Item
FROM (
   SELECT
      S.StartPos,
      IsNull(NullIf(CharIndex(',', @String, S.StartPos), 0) - S.StartPos, 8000)
   FROM (
      SELECT 1 UNION ALL
      SELECT N.N + 1
      FROM (
         SELECT A.A * 4096 + B.B * 1024 + C.C * 256 + D.D * 64 + E.E * 16 + F.F * 4 + G.G N
         FROM
            (SELECT 0 UNION ALL SELECT 1) A (A),
            (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) G (G),
            (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) F (F),
            (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) E (E),
            (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) D (D),
            (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) C (C),
            (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) B (B)
      ) N (N)
      WHERE Substring(@String, N.N, 1) = ','
   ) S (StartPos)
) L (StartPos, Chars)

文字列をさまざまな方法で分割することによるパフォーマンスへの影響を真剣に理解している SQL ライターは、文字列の分割に関する Aaron Bertrand のブログ投稿を参照する必要があります。

また、真剣に SQL Server データベースを学んでいる人は、 Erland Sommarskog の How to Share Data between Stored Procedures を読むべきです。

于 2012-07-29T07:24:00.770 に答える
0

SQL Server CE では、XML 関数で分割して CROSS APPLY を使用できますか? もしそうなら、あなたはこのようなことをすることができます:

SELECT DISTINCT T1.id
FROM (
      SELECT id,  CAST(('<X>'+
                        REPLACE(REPLACE(urls,' ',''),',','</X><X>')+
                        '</X>'
                       ) AS xml
                      ) as URLsXML
      FROM dbo.Widgets
     ) AS T1
CROSS APPLY(
            SELECT N.value('.', 'varchar(50)') AS URLPattern 
            FROM URLsXML.nodes('X') AS S(N)
           ) AS T2
WHERE @Input LIKE T2.URLPattern

更新:確認しました。SQL Server CE は XML データ型または CROSS APPLY をサポートしていないようです。結合する ID とパターンを別のテーブルに入力する必要があると思います。

于 2012-07-29T07:08:28.497 に答える