在单个参数中执行具有多个值的函数

时间:2016-10-31 10:23:37

标签: sql-server sql-server-2008 tsql table-valued-parameters

我有SQL函数,其参数为BIGINT,如下所示:

FUNCTION [dbo].[fn_doc]
(
     @DocID         bigint           
)

我想传递多个文档ID并希望获得结果。我正是这样做的:

declare @DocID   bigint
SET @DocID = (2949146,2949148,2949149,14016926,14025278,14016928,14016928,14025280,14025280)
select * from [fn_doc] (@DocID)

我的问题是,在这种情况下如何执行具有多个值的函数到单个参数?

3 个答案:

答案 0 :(得分:0)

这不起作用

declare @DocID   bigint
SET @DocID = (2949146,2949148,2949149,14016926,14025278,14016928,14016928,14025280,14025280)

声明为BIGINT的变量只能携带一个大数字......

您要传递的内容是逗号分隔字符串,表示数字列表

此功能没有内置功能。 Neiter IN - 条款,也不是JOIN任何类型的EXEC本身都会这样做。

你有几个选择

  • 动态SQL将select语句创建为字符串并使用WHERE docid IN(100,200,300)获取结果(类似IN
  • 创建一个表格(变量,临时或经典),将其填入您的值并在您的函数中使用JOINTYPE(这将导致并行操作出现问题!)
  • 创建{{1}}以像表格一样提交列表
  • 使用某种拆分操作来获取派生表。对于此选项,您可以阅读this answer (section "dynamic IN")

这是post with list of approaches

答案 1 :(得分:0)

快速又脏,但应该工作:-) 这是Shnugo最后一个建议的一个例子

CREATE FUNCTION [dbo].[fn_doc] (@DocID as bigint)
RETURNS bigint
AS
BEGIN
    RETURN @DocID
END

/* your function parameter is a comma seperated list */
DECLARE @Parameter VARCHAR(200)
SET @Parameter = '2949146,2949148,2949149,14016926,14025278,14016928,14016928,14025280,14025280'

/* start and end current parameter */
DECLARE @start int, @end int
SET @start = 0
SET @end = 1

/* current parameter */
DECLARE @p NVARCHAR(200)

WHILE @end > 0
BEGIN
    SET @end = CHARINDEX(',', @Parameter, @start)
    IF @start < @end
       IF ISNUMERIC(SUBSTRING(@Parameter, @start, @end-@start)) = 1 
          SET @p = SUBSTRING(@Parameter, @start, @end-@start)
          PRINT [dbo].[fn_doc] (@p)
    SET @start = @end +1
END

答案 2 :(得分:0)

显然你还没有走出困境。所以我给你留个例子。

创建TABLE类型:

CREATE TYPE dbo.document_ids AS TABLE (
    document_id BIGINT
);
GO

如果您可以保证只将不同的document_id值作为参数传递,您可以从document_id字段上定义主键中受益:

CREATE TYPE dbo.document_ids AS TABLE (
    document_id BIGINT PRIMARY KEY
);
GO

创建依赖于TABLE类型的函数,一个标量值和一个表值:

CREATE FUNCTION dbo.fn_doc_sv (
    @doc_ids dbo.document_ids READONLY
)
RETURNS BIGINT
AS
BEGIN
    RETURN (SELECT SUM(document_id) FROM @doc_ids); 
END
GO

CREATE FUNCTION dbo.fn_doc_tv (
    @doc_ids dbo.document_ids READONLY
)
RETURNS TABLE
AS
    RETURN (SELECT document_id FROM @doc_ids);
GO

两种功能的用法:

DECLARE @doc_ids dbo.document_ids;
INSERT INTO @doc_ids(document_id)VALUES(2949146),(2949148),(2949149),(14016926),(14025278),(14016928),(14016928),(14025280),(14025280);

SELECT dbo.fn_doc_sv(@doc_ids);

SELECT * FROM dbo.fn_doc_tv(@doc_ids);

希望能让你清楚。