sql >> Databasteknik >  >> RDS >> Sqlserver

Skicka en variabel till en IN-sats i en SQL-funktion?

Här är ett lite mer effektivt sätt att dela upp en lista med heltal. Skapa först en siffertabell, om du inte redan har en. Detta kommer att skapa en tabell med 100 000 unika heltal (du kan behöva mer eller färre):

;WITH x AS
(
   SELECT TOP (1000000) Number = ROW_NUMBER() OVER 
   (ORDER BY s1.[object_id])
   FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
   ORDER BY s1.[object_id]
)
SELECT Number INTO dbo.Numbers FROM x;

CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers(Number);

Sedan en funktion:

CREATE FUNCTION [dbo].[SplitInts_Numbers]
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN
   (
       SELECT Item = CONVERT(INT, SUBSTRING(@List, Number,
         CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number))
       FROM dbo.Numbers
       WHERE Number <= CONVERT(INT, LEN(@List))
         AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter
   );

Du kan jämföra prestandan med en iterativ metod här:

http://sqlfiddle.com/#!3/960d2/1

För att undvika taltabellen kan du också prova en XML-baserad version av funktionen - den är mer kompakt men mindre effektiv:

CREATE FUNCTION [dbo].[SplitInts_XML]
(
   @List       VARCHAR(MAX),
   @Delimiter  CHAR(1)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN ( SELECT Item = CONVERT(INT, Item) FROM ( 
     SELECT Item = x.i.value('(./text())[1]', 'int') FROM ( 
       SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(@List, @Delimiter, '</i><i>') 
       + '</i>').query('.') ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y
     WHERE Item IS NOT NULL
   );

Hur som helst när du väl har en funktion kan du helt enkelt säga:

WHERE ID IN (SELECT Item FROM dbo.SplitInts_Numbers(@MyList, ','));


  1. sammanfogade tabellrader till kolumner med kolumntitlar från ursprungliga rader

  2. Turkisk teckenkodning med MySQL

  3. Välj i MySQL där alla rader uppfyller ett villkor

  4. Använda Microsoft Access-data i Wolfram Mathematica