You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sp_executesql获取的product_id在二次插入时为NULL的问题

解决SQL Server动态插入中product_id传递为NULL的问题

问题根源

你的第一个动态插入语句中,OUTPUT INSERTED.producto_id仅返回结果集,未将值赋值给@producto_id输出参数,导致@producto_id实际未被正确赋值,最终第二个插入时传入NULL。

修正方案

情况1:#TempProducto仅插入一行数据

修改第一个动态插入语句,将OUTPUT结果直接绑定到输出参数:

DECLARE @producto_id BIGINT -- 提前声明变量
DECLARE @InsertQuery NVARCHAR(MAX)

SET @InsertQuery = '
    INSERT INTO ' + QUOTENAME(@bdEmpresa) + '.dbo.Producto (
        producto_codigo,
        producto_codigoanterior,
        producto_status
    )
    OUTPUT INSERTED.producto_id INTO @producto_id
    SELECT 
        producto_codigo,
        producto_codigoanterior,
        producto_status
    FROM #TempProducto'

-- 执行插入并捕获product_id
EXEC sp_executesql @InsertQuery, N'@producto_id BIGINT OUTPUT', @producto_id OUTPUT

-- 执行第二个插入(此时@producto_id已正确赋值)
DECLARE @InsertQuery2 NVARCHAR(MAX)
SET @InsertQuery2 = '
    INSERT INTO ' + QUOTENAME(@bdEmpresa) + '.dbo.ProductoProveedor (
        producto_id,
        proveedor_ruc,
        proveedor_dscto
    )
    SELECT 
        @producto_id,
        proveedor_ruc,
        proveedor_dscto
    FROM #TempProveedores'

EXEC sp_executesql @InsertQuery2, N'@producto_id BIGINT', @producto_id

情况2:#TempProducto插入多行数据

若临时表有多行数据,单个变量无法存储所有生成的ID,需用临时表捕获所有插入的product_id,再关联插入:

-- 创建临时表存储所有插入的product_id
CREATE TABLE #InsertedProductos (producto_id BIGINT)

DECLARE @InsertQuery NVARCHAR(MAX)
SET @InsertQuery = '
    INSERT INTO ' + QUOTENAME(@bdEmpresa) + '.dbo.Producto (
        producto_codigo,
        producto_codigoanterior,
        producto_status
    )
    OUTPUT INSERTED.producto_id INTO #InsertedProductos
    SELECT 
        producto_codigo,
        producto_codigoanterior,
        producto_status
    FROM #TempProducto'

-- 执行插入,所有product_id存入临时表
EXEC sp_executesql @InsertQuery

-- 关联临时表插入ProductoProveedor
DECLARE @InsertQuery2 NVARCHAR(MAX)
SET @InsertQuery2 = '
    INSERT INTO ' + QUOTENAME(@bdEmpresa) + '.dbo.ProductoProveedor (
        producto_id,
        proveedor_ruc,
        proveedor_dscto
    )
    SELECT 
        ip.producto_id,
        tp.proveedor_ruc,
        tp.proveedor_dscto
    FROM #TempProveedores tp
    -- 若产品与供应商有对应关系,替换为实际关联条件,否则用CROSS JOIN
    CROSS JOIN #InsertedProductos ip'

EXEC sp_executesql @InsertQuery2

-- 清理临时表
DROP TABLE #InsertedProductos

关键注意点

  • 确保@producto_id变量在使用前已声明。
  • 多行插入时必须用集合类型(如临时表)存储所有生成的ID,避免数据丢失。
  • 保留QUOTENAME(@bdEmpresa)写法,防止SQL注入风险。

内容的提问来源于stack exchange,提问作者Jorge Mantilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:43:30