/* * 项目号全链路追溯:入库主/子单 -> 作业子表 -> 库存主/子表。 * SQL Server,可重复执行。 */ IF OBJECT_ID(N'dbo.in_stockin', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.in_stockin', N'project_no') IS NULL ALTER TABLE dbo.in_stockin ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.in_stockin_detail', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.in_stockin_detail', N'project_no') IS NULL ALTER TABLE dbo.in_stockin_detail ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.in_stockin_finish', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.in_stockin_finish', N'project_no') IS NULL ALTER TABLE dbo.in_stockin_finish ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.in_stockin_detail_finish', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.in_stockin_detail_finish', N'project_no') IS NULL ALTER TABLE dbo.in_stockin_detail_finish ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.mydo_job_detail', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.mydo_job_detail', N'project_no') IS NULL ALTER TABLE dbo.mydo_job_detail ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.mydo_job_detail_finish', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.mydo_job_detail_finish', N'project_no') IS NULL ALTER TABLE dbo.mydo_job_detail_finish ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.bas_stock', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.bas_stock', N'project_no') IS NULL ALTER TABLE dbo.bas_stock ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.bas_stock_detail', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.bas_stock_detail', N'project_no') IS NULL ALTER TABLE dbo.bas_stock_detail ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.bas_stock_finish', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.bas_stock_finish', N'project_no') IS NULL ALTER TABLE dbo.bas_stock_finish ADD project_no nvarchar(80) NULL; GO IF OBJECT_ID(N'dbo.bas_stock_detail_finish', N'U') IS NOT NULL AND COL_LENGTH(N'dbo.bas_stock_detail_finish', N'project_no') IS NULL ALTER TABLE dbo.bas_stock_detail_finish ADD project_no nvarchar(80) NULL; GO /* 已有数据只按明确的主子关系回填,不把旧的“项目号/项目名称”混合字段强行当作项目号。 */ UPDATE d SET d.project_no = h.project_no FROM dbo.in_stockin_detail d INNER JOIN dbo.in_stockin h ON h.stockin_id = d.stockin_id WHERE d.project_no IS NULL AND h.project_no IS NOT NULL; GO UPDATE d SET d.project_no = h.project_no FROM dbo.in_stockin_detail_finish d INNER JOIN dbo.in_stockin_finish h ON h.stockin_id = d.stockin_id WHERE d.project_no IS NULL AND h.project_no IS NOT NULL; GO UPDATE jd SET jd.project_no = COALESCE(d.project_no, df.project_no) FROM dbo.mydo_job_detail jd LEFT JOIN dbo.in_stockin_detail d ON d.stockin_detail_id = jd.stockin_detail_id LEFT JOIN dbo.in_stockin_detail_finish df ON df.stockin_detail_id = jd.stockin_detail_id WHERE jd.project_no IS NULL AND COALESCE(d.project_no, df.project_no) IS NOT NULL; GO UPDATE jd SET jd.project_no = COALESCE(d.project_no, df.project_no) FROM dbo.mydo_job_detail_finish jd LEFT JOIN dbo.in_stockin_detail d ON d.stockin_detail_id = jd.stockin_detail_id LEFT JOIN dbo.in_stockin_detail_finish df ON df.stockin_detail_id = jd.stockin_detail_id WHERE jd.project_no IS NULL AND COALESCE(d.project_no, df.project_no) IS NOT NULL; GO UPDATE bsd SET bsd.project_no = COALESCE(jd.project_no, jdf.project_no, d.project_no, df.project_no) FROM dbo.bas_stock_detail bsd LEFT JOIN dbo.mydo_job_detail jd ON jd.job_detail_id = bsd.job_detail_id LEFT JOIN dbo.mydo_job_detail_finish jdf ON jdf.job_detail_id = bsd.job_detail_id LEFT JOIN dbo.in_stockin_detail d ON d.stockin_detail_id = bsd.stockin_detail_id LEFT JOIN dbo.in_stockin_detail_finish df ON df.stockin_detail_id = bsd.stockin_detail_id WHERE bsd.project_no IS NULL AND COALESCE(jd.project_no, jdf.project_no, d.project_no, df.project_no) IS NOT NULL; GO UPDATE bs SET bs.project_no = x.project_no FROM dbo.bas_stock bs CROSS APPLY ( SELECT TOP (1) bsd.project_no FROM dbo.bas_stock_detail bsd WHERE bsd.stock_id = bs.stock_id AND bsd.project_no IS NOT NULL ORDER BY bsd.detail_id ) x WHERE bs.project_no IS NULL; GO UPDATE bsd SET bsd.project_no = COALESCE(d.project_no, df.project_no) FROM dbo.bas_stock_detail_finish bsd LEFT JOIN dbo.in_stockin_detail d ON d.stockin_detail_id = bsd.stockin_detail_id LEFT JOIN dbo.in_stockin_detail_finish df ON df.stockin_detail_id = bsd.stockin_detail_id WHERE bsd.project_no IS NULL AND COALESCE(d.project_no, df.project_no) IS NOT NULL; GO UPDATE bs SET bs.project_no = x.project_no FROM dbo.bas_stock_finish bs CROSS APPLY ( SELECT TOP (1) bsd.project_no FROM dbo.bas_stock_detail_finish bsd WHERE bsd.stock_id = bs.stock_id AND bsd.project_no IS NOT NULL ORDER BY bsd.detail_id ) x WHERE bs.project_no IS NULL; GO IF OBJECT_ID(N'dbo.proc_add_in_job', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_add_in_job; GO CREATE PROCEDURE [dbo].[proc_add_in_job] @tray_code NVARCHAR(255), @warehouse_id NVARCHAR(255), @user_id INT, @dept_id INT, @v_result INT OUTPUT, @v_resultmsg VARCHAR(80) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @task_no varchar(255), @job_id varchar(255), @now DATETIME = GETDATE(); DECLARE @row_idx INT = 1, @job_detail_id NVARCHAR(80), @product_id NVARCHAR(255), @product_name NVARCHAR(255), @lot_no NVARCHAR(80), @quantity DECIMAL(18), @stockin_id NVARCHAR(80), @stockin_detail_id NVARCHAR(255), @project_no NVARCHAR(80); IF NOT EXISTS (SELECT 1 FROM dbo.in_tray_msg WHERE tray_code = @tray_code AND warehouse_id = @warehouse_id) BEGIN SET @v_result = 0; SET @v_resultmsg = '错误:托盘无绑定数据'; RETURN; END IF EXISTS (SELECT 1 FROM dbo.mydo_job WHERE tray_code = @tray_code AND warehouse_id = @warehouse_id) BEGIN SET @v_result = 0; SET @v_resultmsg = '错误:该托盘已生成作业'; RETURN; END BEGIN TRY DECLARE cur_tray CURSOR LOCAL FAST_FORWARD FOR SELECT tm.product_id, ISNULL(d.product_name, ''), ISNULL(d.lot_no, ''), tm.quantity, ISNULL(d.stockin_id, ''), tm.stockin_detail_id, d.project_no FROM dbo.in_tray_msg tm LEFT JOIN dbo.in_stockin_detail d ON tm.stockin_detail_id = d.stockin_detail_id WHERE tm.tray_code = @tray_code AND tm.warehouse_id = @warehouse_id; BEGIN TRANSACTION; EXEC dbo.util_serial_job 'RK', @job_id OUTPUT; EXEC dbo.util_serial_task '1', @task_no OUTPUT; INSERT INTO dbo.mydo_job ( job_id, status, task_no, in_or_out, execution_phase, tray_code, warehouse_id, create_time, user_id, dept_id, priority, height, weight ) VALUES ( @job_id, '1', @task_no, 1, '0', @tray_code, @warehouse_id, @now, @user_id, @dept_id, 10, 0.00, 0.00 ); OPEN cur_tray; FETCH NEXT FROM cur_tray INTO @product_id, @product_name, @lot_no, @quantity, @stockin_id, @stockin_detail_id, @project_no; WHILE @@FETCH_STATUS = 0 BEGIN SET @job_detail_id = @job_id + '-' + CAST(@row_idx AS VARCHAR); INSERT INTO dbo.mydo_job_detail ( job_detail_id, job_id, product_id, product_name, lot_no, in_quantity, in_or_out_id, in_or_out_d_id, stockin_id, stockin_detail_id, project_no ) VALUES ( @job_detail_id, @job_id, @product_id, @product_name, @lot_no, @quantity, @stockin_id, @stockin_detail_id, @stockin_id, @stockin_detail_id, @project_no ); SET @row_idx += 1; FETCH NEXT FROM cur_tray INTO @product_id, @product_name, @lot_no, @quantity, @stockin_id, @stockin_detail_id, @project_no; END CLOSE cur_tray; DEALLOCATE cur_tray; DELETE FROM dbo.in_tray_msg WHERE tray_code = @tray_code AND warehouse_id = @warehouse_id; COMMIT TRANSACTION; SET @v_result = 1; SET @v_resultmsg = '成功:入库作业生成完成'; END TRY BEGIN CATCH IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; IF CURSOR_STATUS('local','cur_tray') >= 0 BEGIN CLOSE cur_tray; DEALLOCATE cur_tray; END SET @v_result = 0; SET @v_resultmsg = LEFT(ERROR_MESSAGE(), 80); END CATCH END GO IF OBJECT_ID(N'dbo.proc_complete_in_job', N'P') IS NOT NULL DROP PROCEDURE dbo.proc_complete_in_job; GO CREATE PROCEDURE [dbo].[proc_complete_in_job] @job_id NVARCHAR(80), @user_id INT, @dept_id INT, @v_result INT OUTPUT, @v_resultmsg VARCHAR(80) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @now DATETIME2(3) = SYSDATETIME(), @tray_code NVARCHAR(255), @warehouse_id NVARCHAR(80), @warehouse_name NVARCHAR(255), @cargo_space_id NVARCHAR(80), @stock_id NVARCHAR(32), @detail_id NVARCHAR(80), @detail_index INT = 0, @in_type NVARCHAR(5); DECLARE @job_detail_id NVARCHAR(80), @product_id NVARCHAR(80), @product_name NVARCHAR(80), @lot_no NVARCHAR(80), @in_quantity DECIMAL(18, 0), @stockin_id NVARCHAR(80), @stockin_detail_id NVARCHAR(255), @project_no NVARCHAR(80); IF NOT EXISTS (SELECT 1 FROM mydo_job WHERE job_id = @job_id) BEGIN SET @v_result = 0; SET @v_resultmsg = '错误:作业不存在'; RETURN; END; IF NOT EXISTS (SELECT 1 FROM mydo_job_detail WHERE job_id = @job_id) BEGIN SET @v_result = 0; SET @v_resultmsg = '错误:作业无明细'; RETURN; END; SELECT @cargo_space_id = cargo_space_id, @tray_code = tray_code, @warehouse_id = warehouse_id, @warehouse_name = ISNULL(NULLIF(warehouse_name, ''), ( SELECT TOP 1 bw.warehouse_name FROM bas_warehouse bw WHERE bw.warehouse_id = mydo_job.warehouse_id )) FROM mydo_job WHERE job_id = @job_id; IF NOT EXISTS (SELECT 1 FROM bas_cargo_space WHERE cargo_space_id = @cargo_space_id) BEGIN SET @v_result = 0; SET @v_resultmsg = '错误:货位不存在'; RETURN; END; BEGIN TRY DECLARE cur_finish_job_detail CURSOR LOCAL FAST_FORWARD READ_ONLY FOR SELECT job_detail_id, product_id, product_name, lot_no, in_quantity, stockin_id, stockin_detail_id, project_no FROM mydo_job_detail WHERE job_id = @job_id; BEGIN TRANSACTION; OPEN cur_finish_job_detail; FETCH NEXT FROM cur_finish_job_detail INTO @job_detail_id, @product_id, @product_name, @lot_no, @in_quantity, @stockin_id, @stockin_detail_id, @project_no; WHILE @@FETCH_STATUS = 0 BEGIN UPDATE in_stockin_detail SET assign_num = ISNULL(assign_num, 0) + @in_quantity WHERE stockin_detail_id = @stockin_detail_id; IF @stock_id IS NULL BEGIN SELECT TOP 1 @in_type = source.in_type FROM ( SELECT 1 AS source_order, current_bill.in_type FROM dbo.in_stockin current_bill WHERE current_bill.stockin_id = @stockin_id UNION ALL SELECT 2 AS source_order, history_bill.in_type FROM dbo.in_stockin_finish history_bill WHERE history_bill.stockin_id = @stockin_id UNION ALL SELECT 3 AS source_order, archived_stock.in_type FROM dbo.bas_stock_detail_finish archived_detail INNER JOIN dbo.bas_stock_finish archived_stock ON archived_stock.stock_id = archived_detail.stock_id WHERE archived_detail.detail_id = @stockin_detail_id ) source WHERE NULLIF(LTRIM(RTRIM(source.in_type)), '') IS NOT NULL ORDER BY source.source_order; SET @stock_id = 'KC' + FORMAT(@now, 'yyyyMMddHHmmssfff'); INSERT INTO bas_stock ( stock_id, cargo_space_id, stock_status, in_date, quantity, job_id, tray_code, out_quantity, stockin_id, project_no, in_type, warehouse_id, warehouse_name ) VALUES ( @stock_id, @cargo_space_id, '1', @now, 0, @job_id, @tray_code, 0, @stockin_id, @project_no, @in_type, @warehouse_id, @warehouse_name ); END; SET @detail_index = @detail_index + 1; SET @detail_id = @stock_id + N'-' + CONVERT(NVARCHAR(10), @detail_index); INSERT INTO bas_stock_detail ( detail_id, stock_id, product_status, lot_no, product_id, product_name, quantity, out_quantity, job_detail_id, stockin_detail_id, project_no, create_time ) VALUES ( @detail_id, @stock_id, '1', @lot_no, @product_id, @product_name, @in_quantity, 0, @job_detail_id, @stockin_detail_id, @project_no, @now ); FETCH NEXT FROM cur_finish_job_detail INTO @job_detail_id, @product_id, @product_name, @lot_no, @in_quantity, @stockin_id, @stockin_detail_id, @project_no; END; CLOSE cur_finish_job_detail; DEALLOCATE cur_finish_job_detail; UPDATE bas_cargo_space SET status = '2', tray_code = @tray_code WHERE cargo_space_id = @cargo_space_id; UPDATE bs SET bs.product_status = NULL, bs.lot_no = NULL, bs.product_id = NULL, bs.product_name = NULL, bs.quantity = ISNULL(bsa.quantity, 0), bs.job_detail_id = NULL, bs.out_quantity = ISNULL(bsa.out_quantity, 0), bs.stockin_detail_id = NULL FROM bas_stock bs LEFT JOIN ( SELECT stock_id, SUM(ISNULL(quantity, 0)) AS quantity, SUM(ISNULL(out_quantity, 0)) AS out_quantity FROM bas_stock_detail WHERE stock_id = @stock_id GROUP BY stock_id ) bsa ON bsa.stock_id = bs.stock_id WHERE bs.stock_id = @stock_id; UPDATE mydo_job SET status = '4', finish_time = GETDATE() WHERE job_id = @job_id; INSERT INTO mydo_job_finish SELECT * FROM mydo_job WHERE job_id = @job_id; INSERT INTO mydo_job_detail_finish SELECT * FROM mydo_job_detail WHERE job_id = @job_id; DELETE FROM mydo_job_detail WHERE job_id = @job_id; DELETE FROM mydo_job WHERE job_id = @job_id; COMMIT TRANSACTION; SET @v_result = 1; SET @v_resultmsg = '入库作业完成,库存主子表+货位已更新'; END TRY BEGIN CATCH IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; IF CURSOR_STATUS('local','cur_finish_job_detail') >= 0 BEGIN CLOSE cur_finish_job_detail; DEALLOCATE cur_finish_job_detail; END; SET @v_result = 0; SET @v_resultmsg = LEFT(ERROR_MESSAGE(), 80); END CATCH; END GO