Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Предаване на променлива в клауза IN в рамките на SQL функция?

Ето малко по-ефективен начин за разделяне на списък от цели числа. Първо създайте таблица с числа, ако все още нямате такава. Това ще създаде таблица със 100 000 уникални цели числа (може да имате нужда от повече или по-малко):

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

След това функция:

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

Можете да сравните ефективността с итеративен подход тук:

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

За да избегнете таблицата с числа, можете също да опитате базирана на XML версия на функцията - тя е по-компактна, но по-малко ефективна:

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

Както и да е, след като имате функция, можете просто да кажете:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да изчисля еквивалента на SQL Server (hashbytes('SHA1',[ColumnName])) в C#?

  2. Как да обвържа ISO8601 TSQL параметър DATETIME с PDO?

  3. T-SQL Как да създавам динамично таблици в съхранени процедури?

  4. Филтриране на SQL Server 2008

  5. Как мога да покажа цялото време между 2 различни времеви параметъра