【发布时间】:2017-12-06 11:02:05
【问题描述】:
我在另一个存储过程中执行存储过程时遇到问题。基本上,当我自己执行我的存储过程时,它工作得很好,并插入并返回正确的值。但是,当我在另一个存储过程中调用相同的存储过程时,使用与手动尝试时相同的输入,它不会插入任何内容,也不会返回正确的值。变量的处理方式有什么奇怪的吗?还是有其他问题?请参阅下面的代码。
第一道工序:
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
调用它的过程的缩写版本:
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
同样,如果我手动执行第一个过程,它会正确插入 Org Level,并返回 ID。但是,在第二个过程中调用它时,它不会插入任何新的 Org Level,而只是返回它找到的第一个 Org Level 的 ID(我手动插入的所有 Orgs 的父级)。
我已经尝试解决这个问题,通过在第二个程序执行之前打印出所有参数,它们与我手动尝试时完全相同。我还检查了是否发生错误,并且它正在进入 catch 语句,但事实并非如此。有谁能帮帮我吗?
【问题讨论】:
-
如果注释掉 createOrgLevel 并打印输出以查看它是否迭代会发生什么?
-
您可能想要使用 scope_identity 而不是 @@indentity。 @@identity 将返回最后插入的会话标识。 scope_identity 将返回最后插入的范围标识。
-
我注意到,在调用过程中,字符串值为
nvarchar,而在被调用过程中,字符串值为varchar。我不确定这是导致问题的原因,但值得快速测试一下。
标签: sql sql-server