Files
FTC25009/sql/20260714_project_no_traceability.sql

461 lines
15 KiB
Transact-SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 项目号全链路追溯:入库主/子单 -> 作业子表 -> 库存主/子表。
* 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