SQL Server: 在存储过程中使用 if 语句插入/更新数值时遇到问题。

huangapple go评论61阅读模式
英文:

SQL Server: having issues inserting/updating values with if statements in a stored procedure

问题

以下是代码部分的中文翻译:

ALTER PROCEDURE [dbo].[Truck_Offload]
	@Contract int,
	@Source int,
	@Product int,
	@Truck_Ticket int,
	@Truck_Volume bigint,
	@Flow_weighted_Dens real,
	@Avg_meter_temp real,
	@Avg_meter_press real,
	@fast_loop_dens real,
	@offload_date_year int,
	@offload_date_month int,
	@offload_date_day int,
	@offload_date_hour int,
	@offload_date_min int,
	@BSW real,
	@BSW_alarm bit,
	@BOL bigint,
	@library_ID bigint OUTPUT
AS
BEGIN
	DECLARE @offload_datetime date;
	DECLARE @temp_result int;
	DECLARE @source_to_use int;
	DECLARE @product_string nchar(10);
	DECLARE @density_min real;
	DECLARE @density_max real;
	DECLARE @density_temp real;
	DECLARE @Offload_ID bigint;
	DECLARE @request_ID bigint;
	DECLARE @library_ID_temp int;
	DECLARE @offload_total int;
	DECLARE @offload_max int;
	DECLARE @lib_ID_temp bigint;

	SET NOCOUNT ON;

	SELECT @library_ID = 0;

	SELECT @offload_datetime = DATETIMEFROMPARTS(@offload_date_year, @offload_date_month,@offload_date_day, @offload_date_hour, @offload_date_min, 0, 0);

	SELECT @temp_result = Contract 
	FROM Offload_Contracts
	WHERE Contract = @Contract;

	IF @temp_result IS NULL 
	BEGIN
		SELECT @temp_result = eOne_ID 
		FROM Src_Locations
		WHERE eOne_ID = @Source;

		IF @temp_result IS NULL
		BEGIN
			INSERT INTO Src_Locations (eOne_ID) 
            VALUES (@Source);

			SELECT @source_to_use = SCOPE_IDENTITY();
		END
    	ELSE
		BEGIN
			SELECT @source_to_use = @temp_result;
		END

		SELECT @product_string = CASE @Product
	                        			WHEN 1 THEN  'C3+'
                        				WHEN 2 THEN 'C5+'
                        				ELSE 'C5+'
                          		 END;

		INSERT INTO Offload_Contracts (Contract, Offload_ID, Product, Source_ID)
		VALUES (@Contract, 1, @product_string, @source_to_use);
	END
	
	INSERT INTO truck_tickets (Offload_Volume, UOM, Flow_weighted_Dens, meter_average_temp, truck_average_press, fast_loop_dens, offload_date, BSW, BSW_alarm, sys_ticket)
	VALUES (@Truck_Volume, 'm3', @Flow_weighted_Dens, @Avg_meter_temp, @Avg_meter_press, @fast_loop_dens, @offload_datetime, @BSW, @BSW_alarm, @Truck_Ticket);

	INSERT INTO OffLoad_Registry (Offload_Contract, BOL, truck_ticket)
    	SELECT @Contract, @BOL, SCOPE_IDENTITY();

	SELECT @Offload_ID = SCOPE_IDENTITY();

	IF @BSW_alarm = 1 AND @Product = 2
	BEGIN
		INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
        VALUES (@Offload_ID, 'Waiting');

		SELECT @library_ID = SCOPE_IDENTITY();

		UPDATE Offload_Contracts 
		SET offload_total = 1
		WHERE Contract = @Contract;
	END
	ELSE
	BEGIN
		SELECT @request_ID = Request_ID 
        FROM Retain_Requests 
        WHERE Contract = @Contract;

		IF @request_ID IS NOT NULL
		BEGIN
			INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
            VALUES (@Offload_ID, 'Waiting');

			SELECT @library_ID = SCOPE_IDENTITY();

			UPDATE Offload_Contracts 
			SET offload_total = 1
			WHERE Contract = @Contract;
		END
    	ELSE
		BEGIN
			SELECT @lib_ID_temp = P.Lib_ID
			FROM dbo.Prod_Library P
			LEFT JOIN Offload_Registry OfR ON P.Offload_ID = Ofr.Offload_ID
			LEFT JOIN Offload_Contracts OC ON Ofr.Offload_Contract = OC.Contract				
			WHERE Ofr.Offload_Contract = @Contract 
			  AND (Lab_Status = 'Waiting' Or Lab_Status = 'Approved');

			IF @lib_ID_temp IS NULL
			BEGIN
				INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
                VALUES (@Offload_ID, 'Waiting');

				SELECT @library_ID = SCOPE_IDENTITY();
			END

			SELECT @offload_total = OC.offload_total, @density_temp = TT.Flow_weighted_Dens, @density_min = Density_Min, @density_max = Density_Max, @offload_max = Truck_offloads
    			FROM Prod_Library AS PL
				INNER JOIN Offload_Registry OFR ON PL.Offload_ID = OFR.Offload_ID
				INNER JOIN truck_tickets TT ON OFR.truck_ticket = TT.Ticket
				INNER JOIN Offload_Contracts OC ON OC.Contract = OFR.Offload_Contract
				INNER JOIN Products Prod ON Prod.Product = OC.Product
				WHERE PL.Lib_ID = @lib_ID_temp;

				IF @offload_total >= @offload_max OR @Flow_weighted_Dens < @density_temp - @density_min OR @Flow_weighted_Dens > @density_temp + @density_max
				BEGIN
					INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
                    VALUES (@Offload_ID, 'Waiting');

					SELECT @library_ID = SCOPE_IDENTITY();

					UPDATE Offload_Contracts 
					SET offload_total = 1
					WHERE Contract = @Contract;
				END
				ELSE
				BEGIN
					UPDATE Offload_Contracts 
					SET offload_total += 1
					WHERE Contract = @Contract;
				END
			END
		END
	END
END	

你提供的代码中,主要是一个 SQL 存储过程,用于处理卡车卸货的信息。这个存储过程接受一系列输入参数,然后根据这些参数执行一系列数据库操作,包括插入数据和更新数据。根据不同的条件,它还会执行不同的逻辑。你还提供了一个执行该存储过程的代码示例,以及返回输出参数 @library_ID 的值。

请注意,我已经对代码进行了一些翻译,但没有提供对整个代码的详尽分析。如果你需要进一步的解释或具体的问题,请随时提出。

英文:

Everything before the first check BSW alarm executes correctly. Anything being evaluated by the else/if statements doesn't seem to run the insert statements on the prod library table and I'm not sure why.

I have to pass a lot of variables this way because I'm sourcing the data not from a database. I have tested the queries separately to the stored procedure (insert statements) and they work fine, so it's not a null restriction issue or anything like that.

This is the code:

ALTER PROCEDURE [dbo].[Truck_Offload]
@Contract int,
@Source int,
@Product int,
@Truck_Ticket int,
@Truck_Volume bigint,
@Flow_weighted_Dens real,
@Avg_meter_temp real,
@Avg_meter_press real,
@fast_loop_dens real,
@offload_date_year int,
@offload_date_month int,
@offload_date_day int,
@offload_date_hour int,
@offload_date_min int,
@BSW real,
@BSW_alarm bit,
@BOL bigint,
@library_ID bigint OUTPUT
AS
BEGIN
DECLARE @offload_datetime date;
DECLARE @temp_result int;
--DECLARE @contract_to_use int;
DECLARE @source_to_use int;
DECLARE @product_string nchar(10);
DECLARE @density_min real;
DECLARE @density_max real;
DECLARE @density_temp real;
DECLARE @Offload_ID bigint;
DECLARE @request_ID bigint;
DECLARE @library_ID_temp int;
DECLARE @offload_total int;
DECLARE @offload_max int;
DECLARE @lib_ID_temp bigint;
SET NOCOUNT ON;
--If sample is to be purged, library_ID will be 0
SELECT @library_ID = 0;
-- Insert statements for procedure here
SELECT @offload_datetime = DATETIMEFROMPARTS(@offload_date_year, @offload_date_month,@offload_date_day, @offload_date_hour, @offload_date_min, 0, 0);
---find if contract exists
SELECT @temp_result = Contract 
FROM Offload_Contracts
WHERE Contract = @Contract;
--if it doesn&#39;t exist, add contract
IF @temp_result = NULL 
BEGIN
SELECT @temp_result = eOne_ID 
FROM Src_Locations
WHERE eOne_ID = @Source;
IF @temp_result = NULL
BEGIN
INSERT INTO Src_Locations (eOne_ID) 
VALUES (@Source);
SELECT @source_to_use = SCOPE_IDENTITY();
--The name of a new Source Location will be unknown and need to be modified in a GUI.
END
ELSE
BEGIN
SELECT @source_to_use = @temp_result;
END
--SELECT PRODUCT TO USE FOR NEW CONTRACT
SELECT @product_string = CASE @Product
WHEN 1 THEN  &#39;C3+&#39;
WHEN 2 THEN &#39;C5+&#39;
ELSE &#39;C5+&#39;
END;
--CREATE NEW CONTRACT
INSERT INTO Offload_Contracts (Contract, Offload_ID, Product, Source_ID)
VALUES (@Contract, 1, @product_string, @source_to_use);
END
-- Use Contract, establish new Offload_Registry Entry. First Insert Truck_Ticket.
INSERT INTO truck_tickets (Offload_Volume, UOM, Flow_weighted_Dens, meter_average_temp, truck_average_press, fast_loop_dens, offload_date, BSW, BSW_alarm, sys_ticket)
VALUES (@Truck_Volume, &#39;m3&#39;, @Flow_weighted_Dens, @Avg_meter_temp, @Avg_meter_press, @fast_loop_dens, @offload_datetime, @BSW, 
, @Truck_Ticket);
--Now that Truck Ticket has been created, create offload Registry
INSERT INTO OffLoad_Registry (Offload_Contract, BOL, truck_ticket)
SELECT @Contract, @BOL, SCOPE_IDENTITY(); --SCOPE_IDENTITY returns the truck_ticket_number
-- Have the Offload ID handy for later
SELECT @Offload_ID = SCOPE_IDENTITY();
--NOW we need to do logic to determine whether to keep or purge the sample
--First Check if there was a BSW alarm
IF @BSW_alarm = 1 AND @Product = 2
BEGIN
--create new library record
INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
VALUES (@Offload_ID, &#39;Waiting&#39;);
SELECT @library_ID = SCOPE_IDENTITY();
UPDATE Offload_Contracts 
SET offload_total = 1
WHERE Contract = @Contract;
END
ELSE
BEGIN
--check if there&#39;s been any retain requests made against the contract fed to the stored procedure
SELECT @request_ID = Request_ID 
FROM Retain_Requests 
WHERE Contract = @Contract;
--if there&#39;s a retain request, automatically create a library record
IF @request_ID &lt;&gt; NULL
BEGIN
INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
VALUES (@Offload_ID, &#39;Waiting&#39;);
SELECT @library_ID = SCOPE_IDENTITY();
--update contract
UPDATE Offload_Contracts 
SET offload_total = 1
WHERE Contract = @Contract;
END
ELSE
BEGIN
--check if there&#39;s a density + origin + contract against the library
SELECT @lib_ID_temp = P.Lib_ID
FROM dbo.Prod_Library P
LEFT JOIN Offload_Registry OfR ON P.Offload_ID = Ofr.Offload_ID
LEFT JOIN Offload_Contracts OC ON Ofr.Offload_Contract = OC.Contract				
WHERE Ofr.Offload_Contract = @Contract 
AND (Lab_Status = &#39;Waiting&#39; Or Lab_Status = &#39;Approved&#39;);
IF @lib_ID_temp = NULL
BEGIN
INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
VALUES (@Offload_ID, &#39;Waiting&#39;);
SELECT @library_ID = SCOPE_IDENTITY();
END
--contract will be updated for offload total if the operator follows the recommendation
ELSE
--check retention criteria
BEGIN
--get retention criteria
SELECT @offload_total = OC.offload_total, @density_temp = TT.Flow_weighted_Dens, @density_min = Density_Min, @density_max = Density_Max, @offload_max = Truck_offloads
FROM Prod_Library AS PL
INNER JOIN Offload_Registry OFR ON PL.Offload_ID = OFR.Offload_ID
INNER JOIN truck_tickets TT ON OFR.truck_ticket = TT.Ticket
INNER JOIN Offload_Contracts OC ON OC.Contract = OFR.Offload_Contract
INNER JOIN Products Prod ON Prod.Product = OC.Product
WHERE PL.Lib_ID = @lib_ID_temp;
IF @offload_total &gt;= @offload_max OR @Flow_weighted_Dens &lt; @density_temp - @density_min OR @Flow_weighted_Dens &gt; @density_temp + @density_max
-- Retain sample if this is true
BEGIN
INSERT INTO Prod_Library (Offload_ID, Lab_Status) 
VALUES (@Offload_ID, &#39;Waiting&#39;);
SELECT @library_ID = SCOPE_IDENTITY();
UPDATE Offload_Contracts 
SET offload_total = 1
WHERE Contract = @Contract;
END
ELSE
BEGIN
-- update contracts offload total, sample will be purged
UPDATE Offload_Contracts 
SET offload_total += 1
WHERE Contract = @Contract;
END
END
END
END
END	

Calling code was like this, and the return value was always 0.

EXECUTE [dbo].[Truck_Offload] 
@Contract = @Contract
,@Source = @Source
,@Product = @Product
,@Truck_Ticket = @Truck_Ticket
,@Truck_Volume = @Truck_Volume
,@Flow_weighted_Dens = @Flow_weighted_Dens
,@Avg_meter_temp = @Avg_meter_temp
,@Avg_meter_press = @Avg_meter_press
,@fast_loop_dens = @fast_loop_dens
,@offload_date_year = @offload_date_year
,@offload_date_month = @offload_date_month
,@offload_date_day = @offload_date_day
,@offload_date_hour = @offload_date_hour
,@offload_date_min = @offload_date_min
,@BSW = @BSW
,@BSW_alarm = @BSW_alarm
,@BOL = @BOL
,@library_ID = @library_ID OUTPUT
SELECT @library_ID;

--This Question has been solved, see comments about NULL statements. Thank you Sean.

答案1

得分: 0

问题在于任何内容都不等于NULL。它将始终评估为false。解决方法是使用IS NULL或IS NOT NULL。

代码中有几个位置,您需要更改它们以使其按您想要的方式工作。

因此,IF @temp_result = NULL 需要重写为:

IF @temp_result IS NULL

而 IF @request_ID <> NULL 则变为:

IF @request_ID IS NOT NULL

还有其他几个地方匹配相同的模式,相同的解决方法也将纠正那些地方。

英文:

The issue is that nothing ever equals NULL. It will always evaluate to false. The solution is to use IS NULL or IS NOT NULL.

You have a couple locations in the code you posted where you would need to change this to work the way you want it to.

So IF @temp_result = NULL would need to be rewritten as:

IF @temp_result IS NULL

and IF @request_ID <> NULL would become:

IF @request_ID IS NOT NULL

You have a couple other places that match the same pattern and the same solution will correct those as well.

huangapple
  • 本文由 发表于 2023年3月7日 08:20:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定