Я использую курсоры для извлечения строк из таблицы, которая содержит 34 миллиона данных, и передачи ее в хранимую процедуру, я имею в виду передачу каждой строки данных, в результате чего вызывается 34 миллиона раз sp, Как избежать курсоров или любых решений
Я знаю, что это длинный код, так как многие просили поставить sp, и я дал sp также
ALTER PROCEDURE [dbo].[UpdateConData]
(
@UId BIGINT
)
AS
BEGIN
DECLARE @sTime DATETIME
DECLARE @eTime DATETIME
DECLARE @res NVARCHAR(30)
DECLARE @uId INT
DECLARE @Email NVARCHAR(256)
DECLARE @rCount TINYINT
DECLARE @sCount TINYINT
DECLARE conCursor CURSOR FAST_FORWARD LOCAL FOR
SELECT STime,ETime,res,uId,Email,
c.RCount,c.SCount FROM PCon c
OPEN conCursor
FETCH NEXT FROM conCursor INTO
@sTime, @eTime, @res, @uId, @Email,
@rCount, @sCount
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC InsertOrUpdateSCon @sTime, @eTime, @res, @uId, @Email,
@rCount, @sCount
UPDATE records
SET
ETime = @eTime
WHERE PId = @pId AND Type='Sync' and Integer1 = @uId
FETCH NEXT FROM conversationCursor INTO
@sTime, @eTime, @res, @uId, @Email,
@rCount, @sCount
END
CLOSE conCursor
DEALLOCATE conCursor
END
CREATE PROCEDURE [dbo].[InsertOrUpdateSCon]
(
@sTime DATETIME,
@eTime DATETIME,
@res NVARCHAR(30),
@uId BIGINT,
@EmailNVARCHAR(256),
@rCount TINYINT,
@sCount TINYINT
)
AS
BEGIN
DECLARE @conId INT
DECLARE @dId INT
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION SCon
EXEC InsertOrUpdateSDP @sTime, @uId, @Email, @dId OUTPUT
MERGE Con WITH (HOLDLOCK) a USING
(SELECT 'Email' AS Type, @res AS Dson, @Email AS MeData,
@uId AS UId, @sTime AS STime) AS b
ON a.Type=b.Type AND a.Dson=b.Dson AND a.MeData=b.MeData AND a.UId=b.UId AND a.STime=b.STime
WHEN MATCHED THEN
UPDATE SET RCount=RCount + @rCount,
SCount=SCount + @sCount
WHEN NOT MATCHED THEN
INSERT(DId, [Type], Dson, MeData, UId,
STime, ETime, SCount, RCount)
VALUES(@dId, b.Type, @res, @Email, @uId,
@sTime, @eTime, @sCount, @rCount);
COMMIT TRANSACTION SCon
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
END
CREATE PROCEDURE [dbo].[InsertOrUpdateSDP ]
(
@sTime DATETIME,
@uId BIGINT,
@Email NVARCHAR(256),
@dId INT OUTPUT
)
AS
BEGIN
SELECT TOP 1 @dId = DP.PId FROM DP
INNER JOIN Email E ON E.PId=DP.PId AND E.Email=@Email
WHERE PId = 1 /* Email */ AND UId = @dId
IF @dId IS NULL
BEGIN
DECLARE @now DATETIME = GETUTCDATE()
INSERT INTO tableA ([Type], CTime, LTime, IsActive, IsNotactive)
VALUES(1, @now, @now, 0, 1)
SET @dId = SCOPE_IDENTITY()
INSERT INTO tableB(PId, STime, SSTime, DId, UId, SP)
VALUES(@dId, @sTime, @stTime, 1, @Id, 1)
INSERT INTO tableC(PId, Email, DOr, DNS)
VALUES(@dID, @Email, 0, RIGHT(@Email,
LEN(@Email) - CHARINDEX('@', @Email)))
END
ELSE
BEGIN
UPDATE DP SET
SMTime = @sTime,
SP = 1
WHERE PId = @dId AND SMTime < @sTime
END
END