sql - 调用存储过程插入多个值

标签 sql sql-server t-sql

在我们的应用程序中,我们有一个包含许多记录的多行网格。为了插入或更新,我们调用存储过程。

根据当前的实现,存储过程正在调用网格中的每一行。对于每一行,它都会检查表中是否存在。如果数据已经存在,它将更新表,否则将新数据插入表中。

我们没有为每一行调用该过程,而是创建一个表值参数并同时传递所有网格值。

我的问题是:

  1. 这是一个好方法吗?

  2. 如果我将值作为表值参数传递,如何处理存在检查(用于插入或更新)?我需要循环遍历表格并检查它吗?

  3. 插入更新使用单独的存储过程是否更好?

请提出您的建议。提前致谢。

最佳答案

1) TVP 是一个好方法。而且单个存储过程调用的效率更高,对数据库的调用更少。

2) 您还没有明确网格中的每一行是否都有某种 ID 列来确定数据是否存在于表中,但是假设存在,请确保对其进行索引,然后使用 INSERT INTO 和像这样的更新语句:

要添加新行:

INSERT INTO [grid_table] 
SELECT * FROM [table_valued_parameter]
WHERE [id_column] NOT IN (SELECT [id_column] FROM [grid_table])

更新现有行:

UPDATE gt
SET gt.col_A = tvp.col_A,
    gt.col_B = tvp.col_B,
    gt.col_C = tvp.col_C,
    ...
    gt.col_Z = tvp.col_Z
FROM [grid_table] gt 
INNER JOIN [table_valued_parameter] tvp ON gt.id_column = tvp.id_column

注意:

  • 无需执行 IF EXISTS() 或 WHERE 和 JOIN 等任何操作 子句将运行相同的检查,因此无需进行“预检查” 在运行每个语句之前。
  • 这假设 TVP 数据与表中的结构相同 数据库。
  • 您必须确保 id_column 已编入索引。
  • 我使用“INNER JOIN”而不仅仅是“JOIN”来表明它是一个内部联接

3)使用上面的方法你只需新建一个存储过程,简单而有效

关于sql - 调用存储过程插入多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32494676/

相关文章:

c# - LINQ to SQL - 调用内置聚合函数(即 STDEV)

c# - 如何从 SqlDataReader uniqueidentifier 获取 Guid

Sql查询需要对多个日期列一起排序

sql - 搜索时CONVERT()对INDEX有什么影响?

t-sql - Azure Synapse 无服务器 - Azure Synapse 无服务器池中的流加载 Parquet 意外结束

sql - 从表中选择 @variable in(表列)

mysql - SQL : Select all field without duplicate data

mysql - 如何根据另一个表过滤结果。 (我猜是反向连接?)

mysql - WHERE条件是否扫描整个表?

sql - 按记录分组,然后从每组中获取最后一个升序排序记录?