Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Passaggio di una stringa delimitata alla procedura memorizzata per la ricerca nel database

Dal momento che non puoi utilizzare un parametro di tabella (non su SQL Server 2008), prova a passare una stringa CSV e fai in modo che la stored procedure la divida in righe per te.

Esistono molti modi per dividere la stringa in SQL Server. Questo articolo copre i PRO ei CONTRO di quasi tutti i metodi:

"Array ed elenchi in SQL Server 2005 e versioni successive, quando i parametri del valore della tabella non lo fanno Taglialo" di Erland Sommarskog

Devi creare una funzione di divisione. Ecco come è possibile utilizzare una funzione di divisione:

SELECT
    *
    FROM YourTable                               y
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value

Preferisco l'approccio della tabella dei numeri per dividere una stringa in TSQL ma ci sono molti modi per dividere le stringhe in SQL Server, vedi il link precedente, che spiega i PRO ei CONTRO di ciascuno.

Affinché il metodo della tabella dei numeri funzioni, devi eseguire questa configurazione dell'orario una tantum, che creerà una tabella Numbers che contiene righe da 1 a 10.000:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

Una volta impostata la tabella dei numeri, crea questa funzione di divisione:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(   ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''
);
GO 

Ora puoi facilmente dividere una stringa delimitata da uno spazio in una tabella e unirti ad essa o usarla come preferisci. Questi codici si basano sull'ultima modifica della domanda di OP:

CREATE TABLE YourTable (PK int, col1 varchar(20), col2 varchar(20), col3 varchar(20))
--data from question
INSERT INTO YourTable VALUES (1,'hello xyz','abc is my last name','and i''m a developer')
INSERT INTO YourTable VALUES (2,'hello xyz',null,'and i''m a developer')

CREATE PROCEDURE YourProcedure
(
    @keywords   varchar(1000)
)
AS

SELECT
    @keywords AS KeyWords,y.* 
    FROM (SELECT
              t.PK
              FROM dbo.FN_ListToTable(' ',@keywords) dt
                  INNER JOIN YourTable             t ON  t.col1 LIKE '%'+dt.ListValue+'%' OR t.col2 LIKE '%'+dt.ListValue+'%' OR t.col3 LIKE '%'+dt.ListValue+'%'
              GROUP BY t.PK
              HAVING COUNT(t.PK)=(SELECT COUNT(*) AS CountOf FROM dbo.FN_ListToTable(' ',@keywords))
         ) dt
        INNER JOIN YourTable y ON dt.PK=y.PK
GO

--from question   
EXEC YourProcedure 'xyz developer'-- returns 2 rows
EXEC YourProcedure 'xyz abc'-- returns 1 row
EXEC YourProcedure 'abc developer'-- returns 1 row
EXEC YourProcedure 'hello'--  returns 2 rows
EXEC YourProcedure 'hello developer'--  returns 2 rows
EXEC YourProcedure 'xyz'-- returns 2 rows

USCITA:

KeyWords       PK    col1       col2                 col3
-------------- ----- ---------- -------------------- --------------------
xyz developer  1     hello xyz  abc is my last name  and i'm a developer
xyz developer  2     hello xyz  NULL                 and i'm a developer

(2 row(s) affected)

KeyWords       PK    col1       col2                 col3
-------------- ----- ---------- -------------------- --------------------
xyz abc        1     hello xyz  abc is my last name  and i'm a developer

(1 row(s) affected)

KeyWords       PK    col1       col2                 col3
-------------- ----- ---------- -------------------- --------------------
abc developer  1     hello xyz  abc is my last name  and i'm a developer

(1 row(s) affected)

KeyWords       PK    col1       col2                 col3
-------------- ----- ---------- -------------------- --------------------
hello          1     hello xyz  abc is my last name  and i'm a developer
hello          2     hello xyz  NULL                 and i'm a developer

(2 row(s) affected)

KeyWords        PK    col1       col2                 col3
--------------- ----- ---------- -------------------- --------------------
hello developer 1     hello xyz  abc is my last name  and i'm a developer
hello developer 2     hello xyz  NULL                 and i'm a developer

(2 row(s) affected)

KeyWords       PK    col1       col2                 col3
-------------- ----- ---------- -------------------- --------------------
xyz            1     hello xyz  abc is my last name  and i'm a developer
xyz            2     hello xyz  NULL                 and i'm a developer

(2 row(s) affected)