存储过程失败,违反 PRIMARY KEY 约束
Stored Procedure fails, Violation of PRIMARY KEY constraint
我真的不太了解 SP 或 TSQL 来解决这个问题,希望这里有人可以提供帮助。我们有一个存储过程,可以通过一些插入等获取一些统计信息,但由于 "Violation of PRIMARY KEY constraint" 而失败。这是SP:
SET ANSI_WARNINGS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CalculateKPIs]
AS
DECLARE @MaxRequests DECIMAL(19,2),
@RequestDateTime DATETIME,
@MaxRequestsBySecond CURSOR,
@MaxRequestsByMinute CURSOR,
@MaxRequestsByHour CURSOR,
@MaxRequestsByDay CURSOR;
-- Max requests per second
SET @MaxRequestsBySecond = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, request_datetime
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second'
GROUP BY request_datetime
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second')
ORDER BY 1 DESC;
-- Max requests per minute
SET @MaxRequestsByMinute = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(16), request_datetime, 20)
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute'
GROUP BY CONVERT(VARCHAR(16), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute')
ORDER BY 1 DESC;
-- Max requests per hour
SET @MaxRequestsByHour = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(13), request_datetime, 20) + ':00'
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour'
GROUP BY CONVERT(VARCHAR(13), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour')
ORDER BY 1 DESC;
-- Max requests per day
SET @MaxRequestsByDay = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(10), request_datetime, 20) + ' 00:00:00'
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day'
GROUP BY CONVERT(VARCHAR(10), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day')
ORDER BY 1 DESC;
-- Get the number of developers
INSERT INTO api_kpi_value
SELECT 'Usage', 'Developers', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscriber_view;
-- Get the number of all applications
INSERT INTO api_kpi_value
SELECT 'Usage', 'Applications', COUNT(1), 'All', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_application_view;
-- Get the number of active applications
INSERT INTO api_kpi_value
SELECT 'Usage', 'Applications', COUNT(DISTINCT application_name), 'Active', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_traffic_summary
WHERE request_datetime BETWEEN CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) AND CONVERT(VARCHAR(10), GETDATE(), 20);
-- Get the number of API's
INSERT INTO api_kpi_value
SELECT 'Usage', 'APIs', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_view;
-- Get subscribers by API
INSERT INTO api_kpi_value
SELECT 'Subscribers', api_name + ':' + api_version, COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscription_view
GROUP BY api_name, api_version;
-- Update max requests per second
OPEN @MaxRequestsBySecond;
FETCH NEXT FROM @MaxRequestsBySecond
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second';
CLOSE @MaxRequestsBySecond;
DEALLOCATE @MaxRequestsBySecond;
-- Update max requests per minute
OPEN @MaxRequestsByMinute;
FETCH NEXT FROM @MaxRequestsByMinute
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute';
CLOSE @MaxRequestsByMinute;
DEALLOCATE @MaxRequestsByMinute;
-- Update max requests per hour
OPEN @MaxRequestsByHour;
FETCH NEXT FROM @MaxRequestsByHour
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour';
CLOSE @MaxRequestsByHour;
DEALLOCATE @MaxRequestsByHour;
-- Update max requests per day
OPEN @MaxRequestsByDay;
FETCH NEXT FROM @MaxRequestsByDay
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day';
CLOSE @MaxRequestsByDay;
DEALLOCATE @MaxRequestsByDay;
我收到的错误是:
Violation of PRIMARY KEY constraint 'PK__API_KPI___348637B32645B050'. Cannot insert duplicate key in object 'dbo.API_KPI_VALUE'.
The duplicate key value is (Usage, Developers, Now, Nov 20 2019 12:00AM). [SQLSTATE 23000] (Error 2627) The statement has been terminated. [SQLSTATE 01000] (Error 3621).
NOTE: The step was retried the requested number of times (1) without succeeding. The step failed.
我知道错误消息准确指出了问题所在,但我不太明白为什么它一直失败。此数据库位于 SQL 2008 R2
能否分享 table 对 api_kpi_value 的定义?根据您的错误,主键重复,因此失败。
您可以分别尝试 运行 这 2 个语句并检查哪个 Insert 失败。
-- Get the number of developers
INSERT INTO api_kpi_value
SELECT 'Usage', 'Developers', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscriber_view;
-- Get the number of API's
INSERT INTO api_kpi_value
SELECT 'Usage', 'APIs', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_view;
这里的问题是我是个白痴。这项工作实际上 运行 很好,但问题是如果工作失败,它正在执行 "retry" 并且第二次尝试 运行 它显示此错误消息,因为它已经 运行 一次。第一条错误消息是 "Null value is eliminated by an aggregate or other SET operation",我刚刚添加了 ansi_warnings,所以现在工作应该 运行 没问题。感谢您帮助@dataconsumer
我真的不太了解 SP 或 TSQL 来解决这个问题,希望这里有人可以提供帮助。我们有一个存储过程,可以通过一些插入等获取一些统计信息,但由于 "Violation of PRIMARY KEY constraint" 而失败。这是SP:
SET ANSI_WARNINGS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CalculateKPIs]
AS
DECLARE @MaxRequests DECIMAL(19,2),
@RequestDateTime DATETIME,
@MaxRequestsBySecond CURSOR,
@MaxRequestsByMinute CURSOR,
@MaxRequestsByHour CURSOR,
@MaxRequestsByDay CURSOR;
-- Max requests per second
SET @MaxRequestsBySecond = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, request_datetime
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second'
GROUP BY request_datetime
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second')
ORDER BY 1 DESC;
-- Max requests per minute
SET @MaxRequestsByMinute = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(16), request_datetime, 20)
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute'
GROUP BY CONVERT(VARCHAR(16), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute')
ORDER BY 1 DESC;
-- Max requests per hour
SET @MaxRequestsByHour = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(13), request_datetime, 20) + ':00'
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour'
GROUP BY CONVERT(VARCHAR(13), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour')
ORDER BY 1 DESC;
-- Max requests per day
SET @MaxRequestsByDay = CURSOR READ_ONLY FOR
SELECT TOP 1 SUM(request_count) AS requests, CONVERT(VARCHAR(10), request_datetime, 20) + ' 00:00:00'
FROM api_traffic_summary, api_kpi_value
WHERE request_datetime > kpi_date AND kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day'
GROUP BY CONVERT(VARCHAR(10), request_datetime, 20)
HAVING SUM(request_count) > (SELECT kpi_value FROM api_kpi_value WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day')
ORDER BY 1 DESC;
-- Get the number of developers
INSERT INTO api_kpi_value
SELECT 'Usage', 'Developers', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscriber_view;
-- Get the number of all applications
INSERT INTO api_kpi_value
SELECT 'Usage', 'Applications', COUNT(1), 'All', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_application_view;
-- Get the number of active applications
INSERT INTO api_kpi_value
SELECT 'Usage', 'Applications', COUNT(DISTINCT application_name), 'Active', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_traffic_summary
WHERE request_datetime BETWEEN CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) AND CONVERT(VARCHAR(10), GETDATE(), 20);
-- Get the number of API's
INSERT INTO api_kpi_value
SELECT 'Usage', 'APIs', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_view;
-- Get subscribers by API
INSERT INTO api_kpi_value
SELECT 'Subscribers', api_name + ':' + api_version, COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscription_view
GROUP BY api_name, api_version;
-- Update max requests per second
OPEN @MaxRequestsBySecond;
FETCH NEXT FROM @MaxRequestsBySecond
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Second';
CLOSE @MaxRequestsBySecond;
DEALLOCATE @MaxRequestsBySecond;
-- Update max requests per minute
OPEN @MaxRequestsByMinute;
FETCH NEXT FROM @MaxRequestsByMinute
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Minute';
CLOSE @MaxRequestsByMinute;
DEALLOCATE @MaxRequestsByMinute;
-- Update max requests per hour
OPEN @MaxRequestsByHour;
FETCH NEXT FROM @MaxRequestsByHour
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Hour';
CLOSE @MaxRequestsByHour;
DEALLOCATE @MaxRequestsByHour;
-- Update max requests per day
OPEN @MaxRequestsByDay;
FETCH NEXT FROM @MaxRequestsByDay
INTO @MaxRequests, @RequestDateTime;
IF @@FETCH_STATUS = 0
UPDATE api_kpi_value
SET kpi_value = @MaxRequests, kpi_date = @RequestDateTime
WHERE kpi_group = 'Requests' AND kpi_name = 'Max' AND kpi_period = 'Day';
CLOSE @MaxRequestsByDay;
DEALLOCATE @MaxRequestsByDay;
我收到的错误是:
Violation of PRIMARY KEY constraint 'PK__API_KPI___348637B32645B050'. Cannot insert duplicate key in object 'dbo.API_KPI_VALUE'.
The duplicate key value is (Usage, Developers, Now, Nov 20 2019 12:00AM). [SQLSTATE 23000] (Error 2627) The statement has been terminated. [SQLSTATE 01000] (Error 3621).
NOTE: The step was retried the requested number of times (1) without succeeding. The step failed.
我知道错误消息准确指出了问题所在,但我不太明白为什么它一直失败。此数据库位于 SQL 2008 R2
能否分享 table 对 api_kpi_value 的定义?根据您的错误,主键重复,因此失败。
您可以分别尝试 运行 这 2 个语句并检查哪个 Insert 失败。
-- Get the number of developers
INSERT INTO api_kpi_value
SELECT 'Usage', 'Developers', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_subscriber_view;
-- Get the number of API's
INSERT INTO api_kpi_value
SELECT 'Usage', 'APIs', COUNT(1), 'Now', CONVERT(VARCHAR(10), DATEADD(DAY,-1, GETDATE()), 20) + ' 00:00:00'
FROM api_view;
这里的问题是我是个白痴。这项工作实际上 运行 很好,但问题是如果工作失败,它正在执行 "retry" 并且第二次尝试 运行 它显示此错误消息,因为它已经 运行 一次。第一条错误消息是 "Null value is eliminated by an aggregate or other SET operation",我刚刚添加了 ansi_warnings,所以现在工作应该 运行 没问题。感谢您帮助@dataconsumer