代码之家  ›  专栏  ›  技术社区  ›  vignesh

为什么需要表值参数

  •  -2
  • vignesh  · 技术社区  · 6 年前

    我们可以访问storedprocedures中的实际表。那么,需要通过参数传递表吗?有什么特别的优势吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Dai    6 年前

    表值参数是以“安全”的方式将表格式数据传递给存储过程或函数所必需的,尤其是从客户端代码(例如。 SqlCommand SqlParameter )。

    主要的替代技术是创建和 INSERT 变成一个 #temporaryTable 首先调用存储过程,但临时表并不完全是临时的,它们存在于 tempdb 它引入了名称空间和并发性问题。您还必须使用动态SQL,因为您无法参数化表名。对于非临时表,同样的问题也适用。

    此外,如果要将数据传递给 FUNCTION 之后要丢弃的,则不能使用临时表,因为 作用 代码是严格只读的:处理完临时表后,它不能删除临时表,而表值参数在超出范围后会神奇地消失。

    如果有 作用 出于相同的只读原因,希望将表格数据传递给另一个函数:该函数不允许创建 #temporarytable ,但它可以创建和填充表值参数。

    打个比方,这就像在堆栈上传递变量与在堆上传递变量一样——使用堆栈意味着您可以获得自动的生命周期管理和所有权语义,而不必太担心并发性——而使用堆则会带来大量问题。

    一个例子

    假设应用程序代码需要将元组列表(或主键列表)传递给存储过程,或者 作用 -或者如果现有存储过程或函数需要将数据传递给另一个函数。

    使用临时表,您的代码必须执行以下操作:

    1. 创建并打开 SqlConnection
    2. 创建并开始 TRANSACTION
    3. 新建
      • 临时表的作用域为当前数据库会话。这在大多数情况下都是可以的,但这意味着您不能在同一会话中对该临时表执行多个并发数据库操作。
    4. LOCK 如果需要,您将使用任何普通表,因为您的操作将跨越多个 SqlCommand命令 执行情况。
    5. 在客户端或原始存储过程中,执行 插入 语句来填充临时表。如果要从客户端应用程序插入数据,可能需要执行单行 插入 操作次数太多-这非常低效,尤其是在高延迟连接环境中,因为SQL Server使用的TDS协议非常健谈(讽刺的是,您可以执行单个多行 插入 操作使用 但必须使用表值参数来包含多行数据)。
    6. 调用存储过程或 作用 将使用临时表。
    7. 拆下 #临时表 如果要使会话保持活动状态,或立即结束会话以防止浪费内存。

    但如果使用表值参数,则更简单:

    1. 创建并打开 连接对象
    2. 创建并开始 交易
    3. 创建您的 SqlCommand命令 将调用存储过程或 作用 ,但您可以直接使用表值参数,并在一次传递中从客户端填充所有参数。然后,客户端软件通过一次操作将表数据流推送到服务器,这将更加高效。
    4. 然后存储过程将运行。无需拆卸或会话结束。