SQL'de “GİBİ” ve “GİRİŞ” birleşimi var mı?


341

SQL'de I (ne yazık ki) genellikle LIKEneredeyse her normalleştirme kuralını ihlal eden veritabanları nedeniyle " " koşullarını kullanmak zorunda kalıyorum . Bunu şimdi değiştiremem. Ama bu soru ile alakasız.

Ayrıca, WHERE something in (1,1,2,3,5,8,13,21)SQL ifadelerimin daha iyi okunabilirliği ve esnekliği gibi koşulları sık sık kullanıyorum .

Bu iki şeyi karmaşık alt seçimler yazmadan birleştirmenin olası bir yolu var mı?

Bunun WHERE something LIKE ('bla%', '%foo%', 'batz%')yerine kolay bir şey istiyorum :

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

Burada SQl Server ve Oracle ile çalışıyorum ama herhangi bir RDBMS mümkün olup olmadığını ilgileniyorum.


1
Yapmanız ve beğenmeniz gerekir veya: VE (GİBİ '% şey%' gibi bir şey veya '% şey%' GİBİ bir şey veya '% şey%' GİBİ bir şey)
Kozmik Şahin

Keşke Teradata'nın like any/ like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all . (Kayıt için bu, Oracle Community Ideas forum topluluğunda talep edilmiştir. Oracle.com/ideas/11592 )
William Robertson

Yanıtlar:


196

SQL'de LIKE & IN kombinasyonu yoktur, TSQL (SQL Server) veya PLSQL'de (Oracle) çok daha azdır. Bunun bir nedeni, Tam Metin Arama'nın (FTS) önerilen alternatif olmasıdır.

Hem Oracle hem de SQL Server FTS uygulamaları CONTAINS anahtar sözcüğünü destekler, ancak sözdizimi hala biraz farklıdır:

Oracle:

WHERE CONTAINS(t.something, 'bla OR foo OR batz', 1) > 0

SQL Server:

WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')

Sorguladığınız sütun tam metin dizine eklenmelidir.

Referans:


11
Merhaba, Oracle ile "CONTAINS" operatörünü uygulamak istediğiniz sütunlarda düz metin dizinleri oluşturmanız gerekir. Veri hacminize bağlı olarak bu oldukça uzun olabilir.
Pierre-Gilles Levallois

18
SQL Server'da (en azından 2008 sürümü) @Pilooz'un yorumu da geçerlidir, tam metin dizinleri oluşturmanız gerekir.
Marcel

Maksimum uzunluk
4000'dir

59

İfadenizi kolayca okunabilir hale getirmek istiyorsanız, REGEXP_LIKE (Oracle sürüm 10 ve sonrasında mevcuttur) kullanabilirsiniz.

Örnek bir tablo:

SQL> create table mytable (something)
  2  as
  3  select 'blabla' from dual union all
  4  select 'notbla' from dual union all
  5  select 'ofooof' from dual union all
  6  select 'ofofof' from dual union all
  7  select 'batzzz' from dual
  8  /

Table created.

Orijinal sözdizimi:

SQL> select something
  2    from mytable
  3   where something like 'bla%'
  4      or something like '%foo%'
  5      or something like 'batz%'
  6  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

Ve REGEXP_LIKE ile basit görünümlü bir sorgu

SQL> select something
  2    from mytable
  3   where regexp_like (something,'^bla|foo|^batz')
  4  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

FAKAT ...

Çok iyi olmayan performans nedeniyle kendim tavsiye etmem. Birkaç LIKE tahminine sadık kalacağım. Yani örnekler sadece eğlence içindi.


4
10 g'de REGEXP kullanımının +1 güzel illüstrasyonu. Yine de, eğer performans gerçekten çok daha kötü olursa, merak ediyorum. Her ikisi de tam tablo ve / veya dizin taramaları gerektirir, değil mi?
DCookie

12
Doğru. Ancak düzenli ifadeler CPU'yu G / Ç değil, deli gibi yakar. Daha kötü ve ne kadar kötü ise, ifade listenizin ne kadar büyük olduğuna ve diğerlerinin yanı sıra sütunun dizine eklenip eklenmediğine bağlıdır. Bu sadece bir uyarıdır, böylece orijinal poster onu uygulamaya başladığında şaşırmaz.
Rob van Wijk

49

ile sıkışıp kaldın

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

geçici bir tablo doldurmazsanız (jokerleri verilerle birlikte eklemezseniz) ve şöyle katılmazsanız:

FROM YourTable                y
    INNER JOIN YourTempTable  t On y.something LIKE t.something

deneyin (SQL Server sözdizimini kullanarak):

declare @x table (x varchar(10))
declare @y table (y varchar(10))

insert @x values ('abcdefg')
insert @x values ('abc')
insert @x values ('mnop')

insert @y values ('%abc%')
insert @y values ('%b%')

select distinct *
FROM @x x
WHERE x.x LIKE '%abc%' 
   or x.x LIKE '%b%'


select distinct x.*  
FROM @x             x
    INNER JOIN  @y  y On x.x LIKE y.y

ÇIKTI:

x
----------
abcdefg
abc

(2 row(s) affected)

x
----------
abc
abcdefg

(2 row(s) affected)

Tamam, bu işe yarayacaktı, ancak SQL ifadesini daha kolay okunabilir hale getirme
hedefime

10
SQL'de dizin kullanımı ve performansı için gidersiniz. SQL okunabilirliği için yalnızca girinti ve adlandırma kullanın, okunabilirlik için başka değişiklikler yaptığınızda, yalnızca yürütme planını (risk kullanımını ve performansını etkiler) değiştirme riskiyle karşı karşıya kalırsınız. Dikkatli değilseniz, önemsiz değişiklikler yaparak anında çalışan bir sorguyu çok yavaş bir soruyla kolayca değiştirebilirsiniz.
KM.

Bu cevabın ilk ifadesi anahtar - (en çok?) SQL tabanlı sistemler ve diller, geçici çözümler uygulamadan değil, istediğinizi desteklemez. (SQL sunucusunda Tam Metin indeksleme yardımcı olur mu?)
Philip Kelley

@Philip Kelley, SQL Server'ın Tam Metin indekslemesi LIKE 'bla%' OP'nin örnek kodunda hangisini yapabilir ? ya da sadece LIKE '%bla%'arama yapabilir mi?
KM.

Dürüst olmak gerekirse bilmiyorum, FT indekslemeyi hiç kullanmadım. Ürüne zaten dahil edilmiş olası bir çözümün örneği olarak fırlattım. Yaptığı şey için (A veya B veya C), şüphesiz bunu yapmaz, bunu belirlemek için çok çaba sarf edeceğinden ve orijinal sorunun kapsamı dışında ( SQL bunu doğal olarak yapar).
Philip Kelley

20

PostgreSQL ile ANYveya ALLformu vardır:

WHERE col LIKE ANY( subselect )

veya

WHERE col LIKE ALL( subselect )

burada alt seçim tam olarak bir veri sütunu döndürür.


1
Are LIKE ANYve LIKE ALLtüm SQL lehçelerde bir lehçesi çekirdek dil veya spesifik yani parçası ortak?
Esad Ebrahim

1
@AssadEbrahim, hayır onlar belli değil. Oracle vardır = ANYveya <> ALLsadece SQL'de çalışır, örneğin PLSQL'de çalışmaz.
Benoit

Bu standart sözdizimi olduğunu düşünüyorum (ancak pek çok DBMS uyguladı)
ypercubeᵀᴹ 15:17


13

Başka bir çözüm, herhangi bir RDBMS üzerinde çalışmalıdır:

WHERE EXISTS (SELECT 1
                FROM (SELECT 'bla%' pattern FROM dual UNION ALL
                      SELECT '%foo%'        FROM dual UNION ALL
                      SELECT 'batz%'        FROM dual)
               WHERE something LIKE pattern)

1
Ancak bir dizi OR ifadesinden daha çirkin
Fandango68

1
@ Fandango68, ancak seçimlerin birliği, bir tablo, bir görünüm,
vb.Gibi

10

Yukarıda gösterilen İç Birleştirme veya geçici tablo tekniklerini kapsüllemek istiyorsanız bir TableValue kullanıcı işlevi kullanmanızı öneririm. Bu, biraz daha net okumasına izin verir.

Http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx adresinde tanımlanan ayırma işlevini kullandıktan sonra

"Balık" adlı tabloya dayanarak aşağıdakileri yazabiliriz (int id, varchar (50) Name)

SELECT Fish.* from Fish 
    JOIN dbo.Split('%ass,%e%',',') as Splits 
    on Name like Splits.items  //items is the name of the output column from the split function.

çıktılar

1 Bas
2 Pike
7 Fenerbalığı
8 Duvar Gözü

1
Bir kerede birçok koşulla eşleşirse bir satır çoğaltılır.
mik

7

Bir yaklaşım, koşulları bir geçici tabloda (veya SQL Server'da tablo değişkeni) saklamak ve şuna katılmak olacaktır:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue

Bir kerede birçok koşulla eşleşirse bir satır çoğaltılır.
mik

7

Bunun yerine bir iç birleşim kullanın:

SELECT ...
FROM SomeTable
JOIN
(SELECT 'bla%' AS Pattern 
UNION ALL SELECT '%foo%'
UNION ALL SELECT 'batz%'
UNION ALL SELECT 'abc'
) AS Patterns
ON SomeTable.SomeColumn LIKE Patterns.Pattern

1
Bundan kaçınmak istediğim şey tam olarak bu. Çalışmasına rağmen.
selfawaresoup

Neden bu çözümü kullanmıyorsunuz? Kabul edilen çözüm kadar hızlı çalışır ve çok yönlüdür.
Phil Factor

3
@PhilFactor Bu çözüm yinelenen satırlar oluşturabilir.
Jakub Kania

5

Burada SQl Server ve Oracle ile çalışıyorum ama herhangi bir RDBMS mümkün olup olmadığını ilgileniyorum.

Teradata ALL / ANY sözdizimini destekler :

TÜM listedeki her dize.
HERHANGİ listedeki herhangi bir dize.

┌──────────────────────────────┬────────────────────────────────────┐
      THIS expression         IS equivalent to this expression  
├──────────────────────────────┼────────────────────────────────────┤
 x LIKE ALL ('A%','%B','%C%')  x LIKE 'A%'                        
                               AND x LIKE '%B'                    
                               AND x LIKE '%C%'                   
                                                                  
 x LIKE ANY ('A%','%B','%C%')  x LIKE 'A%'                        
                               OR x LIKE '%B'                     
                               OR x LIKE '%C%'                    
└──────────────────────────────┴────────────────────────────────────┘

DÜZENLE:

JOOQ sürüm 3.12.0 bu sözdizimini destekler:

HERHANGİ BİR GİBİ sentetik [NOT] ve TÜM operatörleri GİBİ [NOT] gibi ekleyin

Çoğu zaman, SQL kullanıcıları aşağıdaki gibi LIKE ve IN tahminlerini birleştirmek ister:

SELECT *
FROM customer
WHERE last_name [ NOT ] LIKE ANY ('A%', 'E%') [ ESCAPE '!' ]

Çözüm yüklemi manüel olarak eşdeğerine genişletmektir.

SELECT *
FROM customer
WHERE last_name LIKE 'A%'
OR last_name LIKE 'E%'

jOOQ, kutudan çıktığı gibi sentetik bir yüklemi destekleyebilir.


PostgreSQL LIKE/ILIKE ANY (ARRAY[]):

SELECT *
FROM t
WHERE c LIKE ANY (ARRAY['A%', '%B']);

SELECT *
FROM t
WHERE c LIKE ANY ('{"Do%", "%at"}');

db <> keman demosu


Kar Tanesi TÜM GİBİ GİBİ / TÜM GİBİ eşleştirmeyi de destekler :

HERHANGİ / TÜM GİBİ

Bir veya daha fazla desenle karşılaştırmaya göre dizelerin büyük / küçük harfe duyarlı eşleşmesine izin verir .

<subject> LIKE ANY (<pattern1> [, <pattern2> ... ] ) [ ESCAPE <escape_char> ]

Misal:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')

4

bunu bile deneyebilirsin

fonksiyon

CREATE  FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
RETURNS @Strings TABLE
(   
  position int IDENTITY PRIMARY KEY,
  value varchar(8000)  
)
AS
BEGIN

DECLARE @index int
SET @index = -1

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

Sorgu

select * from my_table inner join (select value from fn_split('ABC,MOP',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';

4

Ben regex listesini takip kullanarak, en azından postgresql çalışır basit bir çözüm var like any. Listedeki bazı antibiyotikleri tanımlamaya bakan bir örnek:

select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')

3

Ben de böyle bir şey merak ediyordum. Sadece bir kombinasyonunu kullanarak test ettim SUBSTRINGve INbu tür bir problem için etkili bir çözüm. Aşağıdaki sorguyu deneyin:

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')

1
Bu yaklaşım ile ilgili bir sorun, eğer varsa t1.something üzerinde bir dizin kullanma yeteneğini kaybetmek olduğunu ..
ShoeLace

1
bu asla 'batz' bulamaz
mik

3

In Oracle aşağıdaki şekilde bir koleksiyon kullanabilirsiniz:

WHERE EXISTS (SELECT 1
                FROM TABLE(ku$_vcnt('bla%', '%foo%', 'batz%'))
               WHERE something LIKE column_value)

Burada önceden tanımlanmış bir koleksiyon türü kullandım ku$_vcnt, ancak kendi böyle bir ilan edebilirsiniz:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);

2

SQL Server için Dinamik SQL'e başvurabilirsiniz.

Bu gibi durumlarda çoğu zaman veritabanından bazı verilere dayalı olarak IN yan tümcesi parametresi vardır.

Aşağıdaki örnek biraz "zorlanmış", ancak bu eski veritabanlarında bulunan çeşitli gerçek durumlarla eşleşebilir.

Kişi adlarının FirstName + '' + LastName olarak tek bir alanda PersonName'in saklandığı tablo Kişileriniz olduğunu varsayalım . NamesToSelect tablosunda NameToSelect alanında saklanan bir ad listesinden tüm kişileri seçmeniz ve ayrıca bazı ek ölçütler (cinsiyet, doğum tarihi vb. Gibi filtrelenmiş gibi)

Aşağıdaki gibi yapabilirsiniz

-- @gender is nchar(1), @birthDate is date 

declare 
  @sql nvarchar(MAX),
  @subWhere nvarchar(MAX)
  @params nvarchar(MAX)

-- prepare the where sub-clause to cover LIKE IN (...)
-- it will actually generate where clause PersonName Like 'param1%' or PersonName Like 'param2%' or ...   
set @subWhere = STUFF(
  (
    SELECT ' OR PersonName like ''' + [NameToSelect] + '%''' 
        FROM [NamesToSelect] t FOR XML PATH('')
  ), 1, 4, '')

-- create the dynamic SQL
set @sql ='select 
      PersonName
      ,Gender
      ,BirstDate    -- and other field here         
  from [Persons]
  where 
    Gender = @gender
    AND BirthDate = @birthDate
    AND (' + @subWhere + ')'

set @params = ' @gender nchar(1),
  @birthDate Date'     

EXECUTE sp_executesql @sql, @params,    
  @gender,  
  @birthDate

2

Ben sadece bildiğim kadarıyla SQL Server 2008'de çalışmasına rağmen, bunun için bir çözüm olabilir. Benzer bir cümle kullanarak 'kurgusal' bir masaya katılmak için https://stackoverflow.com/a/7285095/894974 adresinde açıklanan satır oluşturucuyu kullanabileceğinizi keşfettim . Kulağa göre daha karmaşık geliyor, bak:

SELECT [name]
  ,[userID]
  ,[name]
  ,[town]
  ,[email]
FROM usr
join (values ('hotmail'),('gmail'),('live')) as myTable(myColumn) on email like '%'+myTable.myColumn+'%' 

Bu, tüm kullanıcıların listede verilenler gibi bir e-posta adresine sahip olmasına neden olur. Umarım herkes için yararlıdır. Sorun bir süredir beni rahatsız ediyordu.


1
İlginç. Bununla birlikte, like ifadesi dizinleri kullanamayacağı için bunun sadece küçük bir tabloda kullanılması gerektiğini unutmayın. Bu nedenle, tam metin araması, intial olarak ayarlanması daha zor olsa da, çok fazla veriye sahipseniz daha iyi bir seçimdir.
HLGEM

2

2016'dan başlayarak, SQL Server bir STRING_SPLIT işlev içerir . SQL Server v17.4 kullanıyorum ve bu benim için çalışmak için var:

DECLARE @dashboard nvarchar(50)
SET @dashboard = 'P1%,P7%'

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value


1

Bu, virgülle ayrılmış değerler için çalışır

DECLARE @ARC_CHECKNUM VARCHAR(MAX)
SET @ARC_CHECKNUM = 'ABC,135,MED,ASFSDFSF,AXX'
SELECT ' AND (a.arc_checknum LIKE ''%' + REPLACE(@arc_checknum,',','%'' OR a.arc_checknum LIKE ''%') + '%'')''

Şunun için değerlendirir:

 AND (a.arc_checknum LIKE '%ABC%' OR a.arc_checknum LIKE '%135%' OR a.arc_checknum LIKE '%MED%' OR a.arc_checknum LIKE '%ASFSDFSF%' OR a.arc_checknum LIKE '%AXX%')

Dizin kullanmasını istiyorsanız, ilk '%'karakteri atlamanız gerekir .


1

Oracle RBDMS'de bu davranışı REGEXP_LIKE işlevini kullanarak gerçekleştirebilirsiniz .

Dize eğer aşağıdaki kod test edecek üç listesi ifadesi mevcuttur one | iki | üç | dört | beş (içinde boru " | " sembolü VEYA mantık işlemi anlamına gelir).

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('three', 'one|two|three|four|five');

RESULT
---------------------------------
Success !!!

1 row selected.

Önceki ifade şuna eşdeğerdir:

three=one OR three=two OR three=three OR three=four OR three=five

Böylece başarılı olacak.

Öte yandan, aşağıdaki test başarısız olacaktır.

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('ten', 'one|two|three|four|five');

no rows selected

10g sürümünden beri Oracle'da bulunan normal ifadelerle (REGEXP_ *) ilgili çeşitli işlevler vardır. Oracle geliştiricisiyseniz ve bu konuyla ilgileniyorsanız , Oracle Database ile Normal İfadeler Kullanmanın iyi bir başlangıç ​​olması gerekir .


1

Kombinasyonu şöyle düşünebilirsiniz:

SELECT  * 
FROM    table t INNER JOIN
(
  SELECT * FROM (VALUES('bla'),('foo'),('batz')) AS list(col)
) l ON t.column  LIKE '%'+l.Col+'%'

Hedef tablonuz için tam metin dizini tanımladıysanız, bu alternatifi kullanabilirsiniz:

SELECT  * 
FROM    table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')

Teşekkür ederim. Bu kabul edilen cevap IMO olmalıdır. Herkesin tanımlanmış bir tam metin dizini yoktur (ne anlama gelirse) İlk önerileriniz bir cazibe gibi çalışır. Joker karakterleri LIKE üzerinde birleştirmek yerine geçici tablo değerlerine bile koyabilirsiniz.
Aptal

0

Böyle bir cevap yok:

SELECT * FROM table WHERE something LIKE ('bla% %foo% batz%')

Kahin içinde sorun yok.


0

Teradata'da kullanabilirsiniz LIKE ANY ('%ABC%','%PQR%','%XYZ%'). Aşağıda benim için aynı sonuçları üreten bir örnek var

--===========
--  CHECK ONE
--===========
SELECT *
FROM Random_Table A
WHERE (Lower(A.TRAN_1_DSC) LIKE ('%american%express%centurion%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%bofi%federal%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%american%express%bank%fsb%'))

;
--===========
--  CHECK TWO
--===========
SELECT *
FROM Random_Table  A
WHERE Lower(A.TRAN_1_DSC) LIKE ANY 
('%american%express%centurion%bank%',
'%bofi%federal%bank%',
'%american%express%bank%fsb%')

0

Bunun çok geç olduğunu biliyorum, ama benzer bir durum yaşadım. Birçok parametreyi kabul eden ve birden çok RDBMS sisteminden veri toplamak için bu parametreleri kullanan bir dizi saklı yordam için "Beğen" operatörüne ihtiyacım vardı, bu nedenle RDBMS'ye özgü hileler işe yaramaz, ancak saklı yordam ve herhangi bir işlev MS SQL Server üzerinde çalışacağından, her RDBMS için tam SQL ifadeleri oluşturma işlevi için T-SQL'i kullanabiliriz, ancak çıktının RDBMS'den bağımsız olması gerekir.

Şimdilik, bir SQL bloğuna ayrılmış bir dizeyi (saklı yordam haline gelen bir parametre gibi) çevirmek için bulduğum şey budur. Buna "GİBİ" için "Liken" diyorum. Anla?

Lichen.sql

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =======================================================================
-- Lichen - Scalar Valued Function
-- Returns nvarchar(512) of "LIKE IN" results.  See further documentation.
-- CREATOR: Norman David Cooke
-- CREATED: 2020-02-05
-- UPDATED:
-- =======================================================================
CREATE OR ALTER FUNCTION Lichen 
(
    -- Add the parameters for the function here
    @leadingAnd bit = 1,
    @delimiter nchar(1) = ';',
    @colIdentifier nvarchar(64),
    @argString nvarchar(256)
)
RETURNS nvarchar(512)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @result nvarchar(512)

    -- set delimiter to detect (add more here to detect a delimiter if one isn't provided)
    DECLARE @delimit nchar(1) = ';'
    IF NOT @delimiter = @delimit 
        SET @delimit = @delimiter


    -- check to see if we have any delimiters in the input pattern
    IF CHARINDEX(@delimit, @argString) > 1  -- check for the like in delimiter
    BEGIN  -- begin 'like in' branch having found a delimiter
        -- set up a table variable and string_split the provided pattern into it.
        DECLARE @lichenTable TABLE ([id] [int] IDENTITY(1,1) NOT NULL, line NVARCHAR(32))
        INSERT INTO @lichenTable SELECT * FROM STRING_SPLIT(@argString, ';')

        -- setup loop iterators and determine how many rows were inserted into lichen table
        DECLARE @loopCount int = 1
        DECLARE @lineCount int 
        SELECT @lineCount = COUNT(*) from @lichenTable

        -- select the temp table (to see whats inside for debug)
        --select * from @lichenTable

        -- BEGIN AND wrapper block for 'LIKE IN' if bit is set
        IF @leadingAnd = 1
            SET @result = ' AND ('
        ELSE
            SET @result = ' ('

        -- loop through temp table to build multiple "LIKE 'x' OR" blocks inside the outer AND wrapper block
        WHILE ((@loopCount IS NOT NULL) AND (@loopCount <= @lineCount))
        BEGIN -- begin loop through @lichenTable
            IF (@loopcount = 1) -- the first loop does not get the OR in front
                SELECT @result = CONCAT(@result, ' ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            ELSE  -- but all subsequent loops do
                SELECT @result = CONCAT(@result, ' OR ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            SET @loopcount = @loopCount + 1     -- increment loop
        END -- end loop through @lichenTable

        -- set final parens after lichenTable loop
        SET @result = CONCAT(@result, ' )')
    END  -- end 'like in' branch having found a delimiter
    ELSE -- no delimiter was provided
    BEGIN   -- begin "no delimiter found" branch
        IF @leadingAnd = 1 
            SET @result = CONCAT(' AND ', @colIdentifier, ' LIKE ''' + @argString + '''')
        ELSE
            SET @result = CONCAT(' ', @colIdentifier, ' LIKE ''' + @argString + '''')
    END     -- end "no delimiter found" branch

    -- Return the result of the function
    RETURN @result
END  -- end lichen function

GO

Sınırlayıcı algılaması muhtemelen planlanmıştır, ancak şimdilik varsayılan olarak noktalı virgül kullanmaktadır, böylece defaultoraya koyabilirsiniz . Muhtemelen bunda hatalar var. @leadingAndParametre diğer WHERE yan tümcesi eklemelerle güzel uyuyor böylece bloğun önünde lider "AND" put istiyorum belirlemek için sadece biraz değerdir.

Örnek Kullanım (argString içinde ayırıcı ile)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%;02%;%03%' -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

Aşağıdakileri içeren bir nvarchar (512) döndürür:

 AND ( foo.bar LIKE '01%' OR foo.bar LIKE '02%' OR foo.bar LIKE '%03%' ) 

Giriş bir sınırlayıcı içermiyorsa bloğu da atlar:

Örnek Kullanım (argString içinde sınırlayıcı olmadan)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%'          -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

Aşağıdakileri içeren bir nvarchar (512) döndürür:

 AND foo.bar LIKE '01%'

Bu konuda çalışmaya devam edeceğim, bu yüzden (göze batan belirgin veya başka bir şey) göz ardı edersem, lütfen yorum yapmaktan veya ulaşmaktan çekinmeyin.


-3

Bunu yap

WHERE something + '%' in ('bla', 'foo', 'batz')
OR '%' + something + '%' in ('tra', 'la', 'la')

veya

WHERE something + '%' in (select col from table where ....)

1
Bu nasıl olacak? LHS,% ile bir dizedir ve bu nedenle%, bir joker karakter değildir
Darius X.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.