Esiste una combinazione di "LIKE" e "IN" in SQL?


341

In SQL I (purtroppo) spesso devo usare " LIKE" condizioni dovute a database che violano quasi ogni regola di normalizzazione. Non posso cambiarlo adesso. Ma questo è irrilevante per la domanda.

Inoltre, utilizzo spesso condizioni come WHERE something in (1,1,2,3,5,8,13,21)per una migliore leggibilità e flessibilità delle mie istruzioni SQL.

Esiste un modo possibile per combinare queste due cose senza scrivere sotto-selezioni complicate?

Voglio qualcosa di facile come WHERE something LIKE ('bla%', '%foo%', 'batz%')invece di questo:

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

Sto lavorando con SQl Server e Oracle qui, ma mi interessa se questo è possibile in qualsiasi RDBMS.


1
Devi fare e come o: E (qualcosa COME '% cosa%' o qualcosa COME '% cosa%' o qualcosa COME '% cosa%')
Falco cosmico

Vorrei che avessimo Teradata di like any/ like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all . (Per la cronaca, questo è stato richiesto sul forum Oracle Community Ideas community.oracle.com/ideas/11592 )
William Robertson,

Risposte:


196

Non esiste una combinazione di LIKE & IN in SQL, tanto meno in TSQL (SQL Server) o PLSQL (Oracle). Parte del motivo è che la ricerca di testo completo (FTS) è l'alternativa consigliata.

Entrambe le implementazioni Oracle e SQL Server FTS supportano la parola chiave CONTAINS, ma la sintassi è ancora leggermente diversa:

Oracolo:

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

Server SQL:

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

La colonna che stai interrogando deve essere indicizzata full-text.

Riferimento:


11
Salve, con Oracle, devi creare indici di testo in chiaro sulle colonne a cui vuoi applicare l'operatore "CONTAINS". A seconda del volume di dati, questo potrebbe essere piuttosto lungo.
Pierre-Gilles Levallois,

18
Con SQL Server (almeno la versione 2008) si applica anche il commento di @Pilooz, è necessario creare indici di testo completo.
Marcel,

La lunghezza massima è di 4000.
ʙᴀᴋᴇʀ ʙᴀᴋᴇʀ

59

Se vuoi rendere la tua dichiarazione facilmente leggibile, puoi utilizzare REGEXP_LIKE (disponibile dalla versione 10 di Oracle in poi).

Una tabella di esempio:

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.

La sintassi originale:

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.

E una query dall'aspetto semplice con REGEXP_LIKE

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

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

MA ...

Non lo consiglierei a me stesso a causa delle prestazioni non così buone. Continuerei con i vari predicati LIKE. Quindi gli esempi erano solo per divertimento.


4
+1 bella illustrazione dell'uso di REGEXP in 10g. Sono curioso, però, se la performance sarebbe davvero molto peggio. Entrambi richiederanno scansioni complete di tabelle e / o indici, no?
DCookie,

12
Vero. Ma le espressioni regolari bruciano la CPU come un matto, non I / O. Se è peggio e quanto è peggio, dipende da quanto è grande il tuo elenco di espressioni e se la colonna è indicizzata o meno, tra gli altri. È solo un avvertimento, quindi il poster originale non è sorpreso quando inizia a implementarlo.
Rob van Wijk,

49

sei bloccato con il

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

a meno che non popoli una tabella temporanea (includi i caratteri jolly nei dati) e ti unisci in questo modo:

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

provalo (usando la sintassi di SQL Server):

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

PRODUZIONE:

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

(2 row(s) affected)

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

(2 row(s) affected)

Ok, questo funzionerebbe, ma non sta andando nella mia direzione prevista di rendere più semplice la lettura
dell'istruzione

10
in SQL si utilizza l'utilizzo e le prestazioni dell'indice. Utilizzare solo rientro e denominazione per la leggibilità di SQL, quando si apportano altre modifiche per la leggibilità, si rischia solo di modificare il piano di esecuzione (che influisce sull'utilizzo e sulle prestazioni dell'indice). Se non stai attento, puoi facilmente cambiare una query in esecuzione istantanea in una molto lenta apportando modifiche banali.
KM.

La prima affermazione di questa risposta è la chiave: (la maggior parte?) I sistemi e i linguaggi basati su SQL non supportano ciò che desideri, non senza implementare soluzioni alternative. (Nel server SQL, l'indicizzazione del testo completo sarebbe di aiuto?)
Philip Kelley,

@Philip Kelley, può fare l'indicizzazione di testo completo di SQL Server LIKE 'bla%' , quale nel codice di esempio dell'OP? o puoi fare solo LIKE '%bla%'ricerche?
KM.

Onestamente non lo so, non ho mai usato l'indicizzazione FT. L'ho inserito come esempio di un possibile rimedio che è già incluso nel prodotto. Per quello che sta facendo (A o B o C), sospetto che non lo faccia, sono abbastanza fiducioso che ci vorrebbe molto sforzo per determinarlo, e so che è al di fuori dell'ambito della sua domanda originale (lo fa SQL lo fa in modo nativo).
Philip Kelley,

20

Con PostgreSQL esiste il modulo ANYo ALL:

WHERE col LIKE ANY( subselect )

o

WHERE col LIKE ALL( subselect )

dove la sottoselezione restituisce esattamente una colonna di dati.


1
Sono LIKE ANYe LIKE ALLcomune a tutti i dialetti SQL, ovvero parte del linguaggio di base, o specifici per un dialetto?
Assad Ebrahim,

1
@AssadEbrahim, no sono specifici. Oracle ha = ANYo <> ALLfunziona solo in SQL, non in PLSQL per esempio.
Benoit,

Penso che questa sia sintassi standard (ma non molti DBMS l'hanno implementata)
ypercubeᵀᴹ


13

Un'altra soluzione, dovrebbe funzionare su qualsiasi RDBMS:

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
Ma è più brutto di una serie di dichiarazioni OR
Fandango68,

1
@ Fandango68, ma l'unione delle selezioni può essere sostituita da un'altra fonte di schemi come una tabella, una vista, ecc.
mik

10

Suggerirei di utilizzare una funzione utente TableValue se desideri incapsulare le tecniche di join interno o tabella temporanea mostrate sopra. Ciò consentirebbe di leggere un po 'più chiaramente.

Dopo aver utilizzato la funzione split definita su: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

possiamo scrivere quanto segue in base a una tabella che ho creato chiamato "Fish" (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.

Uscite

1 basso
2 Pike
7 pescatore
8 Walleye

1
Una riga verrà duplicata se soddisfatta da più condizioni contemporaneamente.
mik,

7

Un approccio sarebbe quello di archiviare le condizioni in una tabella temporanea (o variabile di tabella in SQL Server) e unirle in questo modo:

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

Una riga verrà duplicata se soddisfatta da più condizioni contemporaneamente.
mik,

7

Utilizzare invece un join interno:

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
Bene, questo è esattamente ciò che vorrei evitare. Anche se funziona.
selfawaresoup,

Perché evitare questa soluzione? Funziona velocemente come la soluzione accettata ed è altrettanto versatile.
Phil Factor,

3
@PhilFactor Questa soluzione può creare righe duplicate.
Jakub Kania,

5

Sto lavorando con SQl Server e Oracle qui, ma mi interessa se questo è possibile in qualsiasi RDBMS.

Teradata supporta la sintassi LIKE ALL / ANY :

TUTTE le stringhe dell'elenco.
QUALSIASI stringa nell'elenco.

┌──────────────────────────────┬────────────────────────────────────┐
      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%'                    
└──────────────────────────────┴────────────────────────────────────┘

MODIFICARE:

jOOQ versione 3.12.0 supporta questa sintassi:

Aggiungi operatori sintetici [NOT] LIKE ANY e [NOT] LIKE ALL

Molte volte, gli utenti SQL vorrebbero essere in grado di combinare i predicati LIKE e IN, come in:

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

La soluzione alternativa consiste nell'espandere manualmente il predicato all'equivalente

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

jOOQ potrebbe supportare un predicato così sintetico pronto all'uso.


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 <> demo violino


Snowflake supporta anche la corrispondenza LIKE ANY / LIKE ALL :

COME QUALSIASI / TUTTO

Consente la corrispondenza con distinzione tra maiuscole e minuscole di stringhe in base al confronto con uno o più pattern.

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

Esempio:

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

4

puoi anche provare questo

Funzione

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

domanda

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

Ho una soluzione semplice, che funziona almeno in postgresql , usando like anyseguito dall'elenco di regex. Ecco un esempio, cercando di identificare alcuni antibiotici in un elenco:

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

3

Mi chiedevo anche qualcosa del genere. Ho appena provato usando una combinazione di SUBSTRINGed INed è una soluzione efficace per questo tipo di problema. Prova la query seguente:

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

1
un problema con questo approccio è perdere la possibilità di utilizzare un indice su t1. qualcosa se esiste ..
ShoeLace

1
questo non troverà mai "batz"
mik il

3

In Oracle è possibile utilizzare una raccolta nel modo seguente:

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

Qui ho usato un tipo di raccolta predefinito ku$_vcnt, ma puoi dichiararne uno tuo come questo:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);

2

Per SQL Server è possibile ricorrere a SQL dinamico.

Il più delle volte in tali situazioni hai il parametro della clausola IN basato su alcuni dati dal database.

L'esempio che segue è un po '"forzato", ma può corrispondere a vari casi reali trovati in database legacy.

Supponiamo di avere una tabella Persone in cui i nomi delle persone sono memorizzati in un singolo campo PersonName come FirstName + '' + LastName. Devi selezionare tutte le persone da un elenco di nomi, memorizzati nel campo NameToSelect nella tabella NamesToSelect , oltre ad alcuni criteri aggiuntivi (come filtrati per genere, data di nascita, ecc.)

Puoi farlo come segue

-- @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

Potrei avere una soluzione per questo, anche se funzionerà solo in SQL Server 2008 per quanto ne so. Ho scoperto che puoi usare il costruttore di righe descritto in https://stackoverflow.com/a/7285095/894974 per unirti a una tabella "fittizia" usando una clausola simile. Sembra più complesso di quello che è, guarda:

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

Ciò comporterà tutti gli utenti con un indirizzo e-mail come quelli forniti nell'elenco. Spero che sia utile a chiunque. Il problema mi dava fastidio da un po '.


1
Interessante. Tuttavia, tieni presente che questo dovrebbe essere usato solo su una tabella smal poiché l'istruzione like non può usare gli indici. Questo è il motivo per cui la ricerca full-text, sebbene sia più difficile da impostare inizialmente, è la scelta migliore se si dispone di molti dati.
HLGEM,

2

A partire dal 2016, SQL Server include una STRING_SPLIT funzione . Sto usando SQL Server v17.4 e ho avuto questo per funzionare per me:

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

Funziona con valori separati da virgola

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 ''%') + '%'')''

Valuta a:

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

Se vuoi che utilizzi gli indici, devi omettere il primo '%'carattere.


1

In Oracle RBDMS è possibile ottenere questo comportamento utilizzando la funzione REGEXP_LIKE .

Il seguente codice verificherà se la stringa tre è presente nell'espressione di elenco una | due | tre | quattro | cinque (in cui il simbolo " | " del tubo indica un'operazione logica OR).

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

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

1 row selected.

L'espressione precedente equivale a:

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

Quindi ci riuscirà.

D'altra parte, il seguente test fallirà.

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

no rows selected

Esistono diverse funzioni relative alle espressioni regolari (REGEXP_ *) disponibili in Oracle dalla versione 10g. Se sei uno sviluppatore Oracle e sei interessato a questo argomento, questo dovrebbe essere un buon inizio usando le espressioni regolari con il database Oracle .


1

Forse pensi che la combinazione in questo modo:

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

Se hai definito l'indice di testo completo per la tabella di destinazione, puoi utilizzare questa alternativa:

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

Grazie. Questa dovrebbe essere la risposta accettata dall'IMO. Non tutti hanno un indice di testo completo definito (qualunque cosa significhi) I tuoi primi suggerimenti funzionano come un incantesimo. Puoi anche inserire i caratteri jolly nei valori della tabella temporanea stessa invece di concatenare il LIKE.
Il matto

0

Nessuna risposta in questo modo:

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

In oracolo nessun problema.


0

In Teradata puoi usare LIKE ANY ('%ABC%','%PQR%','%XYZ%'). Di seguito è riportato un esempio che ha prodotto gli stessi risultati per me

--===========
--  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

So che è molto tardi, ma ho avuto una situazione simile. Avevo bisogno di un operatore "Like In" per un set di procedure memorizzate che ho, che accettano molti parametri e quindi li utilizza per aggregare i dati da più sistemi RDBMS, quindi nessun trucco specifico RDBMS funzionerebbe, tuttavia la procedura memorizzata e tutte le funzioni verrà eseguito su MS SQL Server, quindi possiamo utilizzare T-SQL per la funzionalità di generazione delle istruzioni SQL complete per ogni RDBMS, ma l'output deve essere abbastanza indipendente da RDBMS.

Questo è quello che mi è venuto in mente per il momento di trasformare una stringa delimitata (come un parametro che entra in una procedura memorizzata) in un blocco di SQL. Lo chiamo "Lichen" per "LIKE IN". Prendilo?

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

Il rilevamento del delimitatore è probabilmente pianificato, ma per impostazione predefinita è un punto e virgola in modo da poterlo inserire default. Probabilmente ci sono bug in questo. Il@leadingAnd parametro ha solo un valore in bit per determinare se si desidera che un "AND" iniziale venga inserito davanti al blocco in modo che si adatti perfettamente alle altre aggiunte della clausola WHERE.

Esempio di utilizzo (con delimitatore in argString)

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

Restituirà un nvarchar (512) contenente:

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

Salterà anche il blocco se l'ingresso non contiene un delimitatore:

Esempio di utilizzo (senza delimitatore in argString)

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

Restituirà un nvarchar (512) contenente:

 AND foo.bar LIKE '01%'

Continuerò a lavorare su questo, quindi se ho trascurato qualcosa (palesemente evidente o meno), non esitate a commentare o contattare.


-3

Fai questo

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

o

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

1
Come funzionerà? L'LHS è una stringa con un% e che% non è quindi un carattere jolly
Darius X.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.