如何限制 mysql 存储过程中传递的日期数据
how to limit data from dates passed in mysql stored procedure
已设置存储过程,因此用户可以使用任何日期调用它。我希望能够将传递的日期限制为两个月。
现在,当用户在没有选择任何日期的情况下调用报表时,报表服务器会因为数据过多而崩溃。如果传递的日期超过 2 个月,我希望能够限制行。
DELIMITER ;;
DROP PROCEDURE IF EXISTS rpt_missing_payroll_files_report_test;;
CREATE PROCEDURE `rpt_missing_payroll_files_report_test`(
IN BEGIN_DATE VARCHAR(255),
IN END_DATE VARCHAR(255)
)
BEGIN
SELECT c.id,
c.name,
ip.name AS icp_name,
s.name AS country_name,
sc.name AS pm_name,
pc.frequency,
pc.check_date AS check_date,
pc.transmit_date,
IFNULL(ps.updated_at, ph.updated_at) AS submit_date,
cpp.created_at AS date_received,
ifnull(cpp.import_filename,'N/A') AS import_filename,
CASE WHEN cpp.created_at IS NOT NULL THEN 1 END AS date_received_sum,
CASE WHEN cpp.success = 1 THEN 1 END AS file_successsum,
DATEDIFF(pc.check_date,cpp.created_at) AS date_diff,
DATE_FORMAT(BEGIN_DATE,'%m/%d/%Y') AS BeginDate,
DATE_FORMAT(END_DATE,'%m/%d/%Y') AS EndDate
FROM co_payroll_calendars pc
inner join co_infos c on pc.co_info_id = c.id
inner join icp_countries icp on c.icp_country_id = icp.id
INNER JOIN sys_countries s ON icp.sys_country_id = s.id
INNER JOIN icp_infos ip ON ip.id = icp.icp_info_id
LEFT OUTER JOIN co_payroll_entry_setups ps ON pc.id = ps.co_payroll_calendar_id
LEFT OUTER JOIN co_payroll_entry_setup_histories ph ON pc.id = ph.co_payroll_calendar_id
LEFT OUTER JOIN co_payroll_processes cpp ON cpp.check_date >= (pc.check_date - INTERVAL 10 DAY ) AND cpp.co_info_id = c.id
LEFT OUTER JOIN sys_csrs sc ON c.sys_csr_id = sc.id
-- below is the part i probably need to change
WHERE (ifnull(BEGIN_DATE,'') = ''
OR pc.check_date >= BEGIN_DATE)
AND (ifnull(END_DATE,'') = ''
OR pc.check_date <= END_DATE)
GROUP BY id,
check_date
ORDER BY country_name, check_date DESC, c.id;
END;;
DELIMITER ;
应允许以下内容
呼叫 rpt_missing_payroll_files_report_test('2017-06-01','2017-07-01')
以下不应被允许或限制在一定数量的行中
调用rpt_missing_payroll_files_report_test('2016-01-01','2017-07-01')
将参数设置为正确的类型(即使用 DATE,而不是 VARCHAR)。
你还应该检查这个:
LEFT OUTER JOIN co_payroll_processes cpp
ON cpp.check_date >= (pc.check_date - INTERVAL 10 DAY )
AND cpp.co_info_id = c.id
请注意,不等式将 select 具有匹配 ID 且日期晚于 (pc.check_date - INTERVAL 10 DAY) 的所有行。这可能很多,也可能不是,具体取决于您的架构。您应该在没有 GROUP BY 和 ORDER BY 的情况下测试查询,并检查它 returns 到底是什么。如果您发现很多重复项,那么您可以通过使用更好的 JOIN 条件来加快查询速度。
现在,关于您的主要问题,答案很简单:将其添加到您的程序中
IF END_DATE > (BEGIN_DATE + INTERVAL 2 MONTH) THEN
raise an error
ELSE
your huge SELECT
END IF
很简单。以下是在 mysql 存储过程中 raise an error 的方法(具体方法取决于您的版本)。
您也可以简单地执行 "SELECT 'your message here'" 并且消息字符串将返回给客户端(然后可能会崩溃,因为它需要一组特定的列,所以最好引发错误) .
已设置存储过程,因此用户可以使用任何日期调用它。我希望能够将传递的日期限制为两个月。
现在,当用户在没有选择任何日期的情况下调用报表时,报表服务器会因为数据过多而崩溃。如果传递的日期超过 2 个月,我希望能够限制行。
DELIMITER ;;
DROP PROCEDURE IF EXISTS rpt_missing_payroll_files_report_test;;
CREATE PROCEDURE `rpt_missing_payroll_files_report_test`(
IN BEGIN_DATE VARCHAR(255),
IN END_DATE VARCHAR(255)
)
BEGIN
SELECT c.id,
c.name,
ip.name AS icp_name,
s.name AS country_name,
sc.name AS pm_name,
pc.frequency,
pc.check_date AS check_date,
pc.transmit_date,
IFNULL(ps.updated_at, ph.updated_at) AS submit_date,
cpp.created_at AS date_received,
ifnull(cpp.import_filename,'N/A') AS import_filename,
CASE WHEN cpp.created_at IS NOT NULL THEN 1 END AS date_received_sum,
CASE WHEN cpp.success = 1 THEN 1 END AS file_successsum,
DATEDIFF(pc.check_date,cpp.created_at) AS date_diff,
DATE_FORMAT(BEGIN_DATE,'%m/%d/%Y') AS BeginDate,
DATE_FORMAT(END_DATE,'%m/%d/%Y') AS EndDate
FROM co_payroll_calendars pc
inner join co_infos c on pc.co_info_id = c.id
inner join icp_countries icp on c.icp_country_id = icp.id
INNER JOIN sys_countries s ON icp.sys_country_id = s.id
INNER JOIN icp_infos ip ON ip.id = icp.icp_info_id
LEFT OUTER JOIN co_payroll_entry_setups ps ON pc.id = ps.co_payroll_calendar_id
LEFT OUTER JOIN co_payroll_entry_setup_histories ph ON pc.id = ph.co_payroll_calendar_id
LEFT OUTER JOIN co_payroll_processes cpp ON cpp.check_date >= (pc.check_date - INTERVAL 10 DAY ) AND cpp.co_info_id = c.id
LEFT OUTER JOIN sys_csrs sc ON c.sys_csr_id = sc.id
-- below is the part i probably need to change
WHERE (ifnull(BEGIN_DATE,'') = ''
OR pc.check_date >= BEGIN_DATE)
AND (ifnull(END_DATE,'') = ''
OR pc.check_date <= END_DATE)
GROUP BY id,
check_date
ORDER BY country_name, check_date DESC, c.id;
END;;
DELIMITER ;
应允许以下内容
呼叫 rpt_missing_payroll_files_report_test('2017-06-01','2017-07-01')
以下不应被允许或限制在一定数量的行中
调用rpt_missing_payroll_files_report_test('2016-01-01','2017-07-01')
将参数设置为正确的类型(即使用 DATE,而不是 VARCHAR)。
你还应该检查这个:
LEFT OUTER JOIN co_payroll_processes cpp
ON cpp.check_date >= (pc.check_date - INTERVAL 10 DAY )
AND cpp.co_info_id = c.id
请注意,不等式将 select 具有匹配 ID 且日期晚于 (pc.check_date - INTERVAL 10 DAY) 的所有行。这可能很多,也可能不是,具体取决于您的架构。您应该在没有 GROUP BY 和 ORDER BY 的情况下测试查询,并检查它 returns 到底是什么。如果您发现很多重复项,那么您可以通过使用更好的 JOIN 条件来加快查询速度。
现在,关于您的主要问题,答案很简单:将其添加到您的程序中
IF END_DATE > (BEGIN_DATE + INTERVAL 2 MONTH) THEN
raise an error
ELSE
your huge SELECT
END IF
很简单。以下是在 mysql 存储过程中 raise an error 的方法(具体方法取决于您的版本)。
您也可以简单地执行 "SELECT 'your message here'" 并且消息字符串将返回给客户端(然后可能会崩溃,因为它需要一组特定的列,所以最好引发错误) .