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
相关产品推荐
相关产品推荐

