Die*_*ira 1 sql-server t-sql functions
我正在尝试传递要在NOT IN
操作中使用的项目数组:
ALTER FUNCTION [dbo].[fnTEST] (@CODES VARCHAR)
RETURNS TABLE
AS
RETURN
(
SELECT
T1.CODE AS 'CODE',
(SELECT COUNT(*)
FROM TABLE1 AS T2 WITH (NOLOCK)
WHERE T2.CODE NOT IN (@CODES)
) AS 'COUNT'
FROM TABLE1 T1 WITH (NOLOCK)
)
Run Code Online (Sandbox Code Playgroud)
然后我这样称呼它:
SELECT * FROM fnTEST ('500,250,202,900,204,200,300,400,600,800')
Run Code Online (Sandbox Code Playgroud)
那行不通。如果我尝试在没有引号的情况下调用它,则会收到参数过多的错误(这是预期的)。
有解决方案吗?
在 SQL Server 2008 中,执行此操作的最佳方法是首先不传入 CSV 列表。这组以逗号分隔的值从何而来?
首先,创建一个表类型:
CREATE TYPE dbo.myFoo AS TABLE(id INT PRIMARY KEY);
GO
Run Code Online (Sandbox Code Playgroud)
现在,创建一个将其作为 TVP 的函数:
CREATE FUNCTION dbo.fnTest
(
@codes dbo.myFoo READONLY
)
RETURNS TABLE
AS
RETURN
(
SELECT
T1.CODE AS [CODE],
(SELECT COUNT(*)
FROM dbo.TABLE1 AS T2 WITH (NOLOCK)
WHERE NOT EXISTS (SELECT 1 FROM @codes
WHERE id = T2.CODE)
) AS [COUNT]
FROM dbo.TABLE1 T1 WITH (NOLOCK)
);
Run Code Online (Sandbox Code Playgroud)
要在本地测试它...
DECLARE @x dbo.myFoo;
INSERT @x(id) VALUES(500),(250),(202);...
SELECT * FROM dbo.fnTest(@x);
Run Code Online (Sandbox Code Playgroud)
...但最终您将从 C# 代码或其他任何地方作为 DataTable 或其他基于集合的结构传递该组值。
对于 SQL Server 2005
您不能使用 TVP。所以下一个最好的选择是拆分功能,例如
CREATE FUNCTION dbo.SplitInts
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(32)
)
RETURNS TABLE
AS
RETURN
(
SELECT Item = CONVERT(INT, Item)
FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects) AS n(Number)
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
) AS y
);
Run Code Online (Sandbox Code Playgroud)
那么你的功能可以是:
CREATE FUNCTION dbo.fnTest
(
@codes VARCHAR(MAX)
)
RETURNS TABLE
AS
RETURN
(
SELECT
T1.CODE AS [CODE],
(SELECT COUNT(*)
FROM dbo.TABLE1 AS T2 WITH (NOLOCK)
WHERE NOT EXISTS (SELECT 1 FROM dbo.SplintInts(@codes, ',')
WHERE Item = T2.CODE)
) AS [COUNT]
FROM dbo.TABLE1 T1 WITH (NOLOCK)
);
Run Code Online (Sandbox Code Playgroud)
如果您可以在 CLR 中执行此操作,它的性能可能会好一些。请参阅以下博客系列 - 他们处理分割字符串,但在大多数情况下,观察结果也适用于分割整数字符串。
http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-follow-up http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql
归档时间: |
|
查看次数: |
235 次 |
最近记录: |