【发布时间】:2019-12-24 00:17:05
【问题描述】:
我必须一次向表中插入一条记录,然后通过传递输出变量来执行存储过程。
插入部分实际上是这样做的,我在目标表中看到了两条不同的记录。但是存储过程似乎使用了与插入目标表的第一条记录相同的输出参数。所以基本上,当一个存储过程被循环调用时,对于插入到目标表中的每个不同的 ID,一次又一次地循环使用相同的输出参数。
在我下面的伪代码中,它打印 3 次以下 5, 10, 15 。这是正确的,因为它需要dbo.Table_Test 中的每个新 ID。但在我的实际代码中,实际上它只需要第一个 ID 重复循环相同 ID 三次。
-------- CREATING STORED PROCEDURE --------
USE MyDB;
GO
DROP PROCEDURE IF EXISTS dbo.sp_Testing
USE MyDB;
GO
CREATE PROCEDURE dbo.sp_Testing
@QueueId INT,
-- response
@MainId INT OUT, -- this allows null
@MessageTx VARCHAR(500) OUT,
@SuccessIn BIT OUT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT * FROM MyDB.sys.tables WHERE name = 'Table_Test') --print 1
CREATE TABLE dbo.Table_Test
(
ID INT NOT NULL PRIMARY KEY IDENTITY(5,5),
name VARCHAR(10) NULL,
Phone INT NULL,
category VARCHAR(10) NULL
)
INSERT INTO dbo.Table_Test (name)
VALUES ('Andrew')
SET @MainId = SCOPE_IDENTITY()
PRINT @MainId
END
-------- END OR STORED PROCEDURE --------
GO
-------- INSERT STATEMENTS ---------
USE MyDB;
IF OBJECT_ID('tempdb..#MainTable') IS NOT NULL
DROP TABLE #MainTable
IF OBJECT_ID('tempdb..#Queue') IS NOT NULL
DROP TABLE #Queue
DECLARE @MessageTx VARCHAR(30)
DECLARE @SuccessIn BIT
DECLARE @QueueId INT
DECLARE @MainId INT
DECLARE @ParentId INT
SET @MainId = NULL
SET @SuccessIn = 1
CREATE TABLE #MainTable
(
ID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
name VARCHAR(10) NULL,
Phone INT NOT NULL,
category VARCHAR(10) NULL
)
INSERT INTO #MainTable (name, Phone, category)
VALUES ('Adam', 123433, 'new'),
('John', 222222, 'new'),
('Samuel', 123123313, 'new')
-- SELECT * FROM #MainTable
-- SELECT * FROM #Queue
-- SELECT * FROM #Test
DECLARE Cursor_test CURSOR LOCAL FOR
SELECT id
FROM #MainTable
-- get relationships for next level
OPEN Cursor_test
FETCH NEXT FROM Cursor_test INTO @ParentId
WHILE @@FETCH_STATUS = 0
BEGIN
IF OBJECT_ID('tempdb..#Queue') IS NOT NULL
DROP TABLE #Queue
CREATE TABLE #Queue
(
PK INT NOT NULL PRIMARY KEY identity (3,2),
ID INT NOT NULL
)
INSERT INTO #Queue (id)
SELECT id
FROM #MainTable
SET @QueueId = SCOPE_IDENTITY()
-- real-time creation
EXEC dbo.sp_Testing @QueueId, @MainId, @MessageTx OUT, @SuccessIn OUT
FETCH NEXT FROM Cursor_test INTO @ParentId
END
CLOSE Cursor_test
DEALLOCATE Cursor_test
【问题讨论】:
-
有什么可以帮助您的吗?
-
显然,执行此操作的代码存在某种问题。你知道的,你更愿意留给自己的那个。
-
嗨@Squirrel,请参考我的评论和我回答中的代码
-
旁注:您应该不为您的存储过程使用
sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本不使用前缀! -
嗨@RogerWolf,在我上面的伪代码中,它打印了以下 5, 10, 15 的 3 次。这是正确的,因为它需要 dbo.Table_Test 中的每个新 ID。但在我的实际代码中,实际上它只需要第一个 ID 重复循环相同 ID 三次。
标签: sql-server loops stored-procedures cursor output-parameter