【问题标题】:Execute function with multiple values in single parameter在单个参数中执行具有多个值的函数
【发布时间】:2016-10-31 10:23:36
【问题描述】:

我有一个 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)

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

【问题讨论】:

  • 在线研究T能够V评估P参数。
  • 请提供任何示例链接,对于这个特定的场景?
  • 所有场景都是一样的。如果您需要将值列表作为参数传递给函数或 SP,请使用 TVP。这是一般的建议。如果您搜索sql server table valued parameter,可以在网上找到很多东西。 GL!
  • 嗨!这个问题解决了吗?您需要进一步的帮助吗?请给我一个提示:如果这个问题得到了解决,您将非常好心,在(最佳)答案的投票计数器下方勾选接受检查。这将 1) 将此问题标记为已解决 2) 让追随者更容易找到最佳解决方案 3) 向回答者支付积分和 4) 向您支付积分。由于您自己已经越过了 15 点边界,因此您还被要求对贡献进行投票。这是说谢谢的方式。编码快乐!

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


【解决方案1】:

这行不通

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

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

您要传递的是一个逗号分隔的字符串,它代表一个数字列表

没有内置功能。既不是IN 子句,也不是任何类型的JOIN 本身都可以做到这一点。

你有几个选择

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

这是post with list of approaches

【讨论】:

    【解决方案2】:

    又快又脏,但应该可以工作:-) 这是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
    

    【讨论】:

    • 这可能是 但是 - 可以肯定! - 它不是快速
    【解决方案3】:

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


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

    希望这能让你明白。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 2014-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多