[英]Stored procedure not returning correct value when called by another stored procedure
I'm having issues executing a stored procedure within another stored procedure. 我在另一个存储过程中执行存储过程时遇到问题。 Basically, when I execute my stored procedure by itself, it works just fine, and inserts and returns the correct values.
基本上,当我自己执行存储过程时,它可以正常工作,并插入并返回正确的值。 However, when I call the same stored procedure within another stored procedure, with the same input as when I tried it manually, it doesn't insert anything, and doesn't return the correct value.
但是,当我在另一个存储过程中调用相同的存储过程时,使用与手动尝试时相同的输入,它不会插入任何内容,也不会返回正确的值。 Is there something weird going on with how the variables are handled?
处理变量的方式是否有些奇怪? Or is something else going wrong?
还是出了什么问题? See my code below.
请参阅下面的代码。
The first procedure: 第一个过程:
ALTER PROCEDURE [dbo].[createOrgLevel]
@name varchar(255),
@level int,
@parentid bigint,
@newid bigint OUTPUT
AS
SET NOCOUNT ON;
-- Check to see if it exists
SELECT @newid = [id] from dbo.[Org 3]
WHERE
[Name] = @name and
[Parent ID] = @parentid
IF @newid IS NULL
-- If it doesn't exist, insert
BEGIN
INSERT INTO [dbo].[Org 3]
([Parent ID]
,[Name]
,[Level])
VALUES
(@parentid
,@name
,@level)
SET @newid = @@identity
END
END
An abbreviated version of the procedure calling it: 该过程的缩写形式:
ALTER PROCEDURE [dbo].[createOrg]
@level1 nvarchar(255),
@level2 nvarchar(255),
@level3 nvarchar(255),
@level4 nvarchar(255),
@level5 nvarchar(255),
@level6 nvarchar(255),
@level7 nvarchar(255),
@level8 nvarchar(255),
@orgid bigint OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@parid bigint,
@curname nvarchar(255)
DECLARE
@levels table (num int, name nvarchar(255))
INSERT @levels(num, name) values (1,@level1),(2,@level2),(3,dbo.@level3),
(4,@level4),(5,@level5),(6,@level6),(7,@level7),
(8,@level8)
BEGIN
BEGIN TRY
SET @curname = @level1
EXEC dbo.createOrgLevel @name = @curname, @level = 1, @parentid = 0, @newid = @orgid OUTPUT
SET @parid = @orgid
END TRY
BEGIN CATCH
SET @orgid = NULL
RETURN -1
END CATCH
DECLARE @cnt INT = 2;
WHILE @cnt < 9
BEGIN
BEGIN TRY
SELECT @curname = name FROM @levels WHERE num = @cnt
-----------------------------------
-- This is where it is executed, and not inserting/returning the correct value. It keeps
-- returning the value from the previous 'loop', and not inserting anything. It's not
-- entering the Catch, though.
EXEC dbo.createOrgLevel @name = @curname, @level = @cnt, @parentid = @parid, @newid = @orgid OUTPUT
-----------------------------------
SET @parid = @orgid
END TRY
BEGIN CATCH
RETURN 1
END CATCH
SET @cnt = @cnt + 1
END
END
END
Again, if I manually execute the first procedure, it correctly inserts the Org Level, and returns the ID. 同样,如果我手动执行第一个过程,它将正确插入组织级别,并返回ID。 However, when it is called in the second procedure, it doesn't insert any new Org Levels, and just returns the ID of the first Org Level it finds (the parent level for all Orgs, that I manually inserted).
但是,在第二个过程中调用它时,它不会插入任何新的组织级别,而只是返回找到的第一个组织级别的ID(我手动插入的所有组织的父级别)。
I have tried troubleshooting this issue, by printing out all the parameters before the procedure is executed within the second, and they are exactly the same as when I try it manually. 我已尝试解决此问题,方法是在第二步执行该过程之前先打印出所有参数,这些参数与我手动尝试时的参数完全相同。 I also checked to see if errors where occurring, and it was entering the catch statement, but it wasn't.
我还检查了是否发生了错误,是否正在输入catch语句,但是没有。 Can anyone help me out here?
有人可以帮我从这里出去吗?
Yes, this is because you refactor @newid
variable in each iteration and it's value from last run is still stored in it on each consecutive run. 是的,这是因为您在每次迭代中都重构了
@newid
变量,并且上一次运行的值仍在每次连续运行时存储在其中。
Your problem is here actually: 您的问题实际上在这里:
SELECT @newid = [id] from dbo.[Org 3]
WHERE
[Name] = @name and
[Parent ID] = @parentid
@newid
already has a value, and since the query does not return anything, value is not overrided with NULL
but remains from last time. @newid
已经有一个值,并且由于查询不返回任何内容,因此该值不会被NULL
覆盖,而是从上次开始保留。
What you should do is either: 您应该做的是:
@newid
to NULL at the start of your inner stored procedure or @newid
设置为NULL或 You can rewrite SELECT
to SET
which would overwrite value with NULL if nothing is returned 您可以将
SELECT
重写为SET
,如果什么都没有返回,它将用NULL覆盖值
SET @newid = (SELECT id FROM dbo.[Org 3]..)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.