sql >> Database >  >> RDS >> Sqlserver

Een variabele doorgeven aan een IN-clausule binnen een SQL-functie?

Hier is een iets efficiëntere manier om een ​​lijst met gehele getallen te splitsen. Maak eerst een getallentabel, als je die nog niet hebt. Dit maakt een tabel met 100.000 unieke gehele getallen (je hebt misschien meer of minder nodig):

;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);

Dan een functie:

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
   );

U kunt de prestaties hier vergelijken met een iteratieve aanpak:

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

Om de getallentabel te vermijden, kunt u ook een op XML gebaseerde versie van de functie proberen - deze is compacter maar minder efficiënt:

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
   );

Hoe dan ook, als je eenmaal een functie hebt, kun je gewoon zeggen:

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


  1. wat is de beste manier om een ​​willekeurige mysql-ID te maken met behulp van PHP?

  2. Meerdere waarden in één kolom of niet?

  3. mysql join-queryvolgorde in twee kolommen

  4. Praktische beperkingen van expressie-indexen in PostgreSQL