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

Sende en variabel ind i en IN-sætning i en SQL-funktion?

Her er en lidt mere effektiv måde at opdele en liste over heltal på. Først skal du oprette en taltabel, hvis du ikke allerede har en. Dette vil skabe en tabel med 100.000 unikke heltal (du kan have brug for mere 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);

Derefter 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 sammenligne ydeevnen med en iterativ tilgang her:

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

For at undgå taltabellen kan du også prøve en XML-baseret version af funktionen - den er mere 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
   );

Uanset hvad, når du har en funktion, kan du bare sige:

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


  1. mysqli eller PDO - hvad er fordele og ulemper?

  2. PDO:tjek for opdateret eller indsat post ved hjælp af mysql INSERT ON DUPLICATE KEY UPDATE

  3. fjerne huller i automatisk stigning

  4. MySQL tæller på hinanden følgende datoer for den aktuelle streak