0

The stored proc is set up so the user can call it using any dates. I want to be able to restrict the date passed to two months.

Right now when the user calls the report without any dates selected, the report server crashes because there is too much data. I want to be able to either limit the rows if dates passed is more than 2 months.

    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 ;

The following should be allowed

CALL rpt_missing_payroll_files_report_test('2017-06-01','2017-07-01')

The following should not be allowed or limited to a certain amount of rows

CALL rpt_missing_payroll_files_report_test('2016-01-01','2017-07-01')

4

1 回答 1

0

将参数设置为正确的类型(即,使用 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

请注意,不等式将选择所有具有匹配 id 且日期晚于 (pc.check_date - INTERVAL 10 DAY ) 的行。这可能很多,也可能不多,具体取决于您的架构。您应该在没有 GROUP BY 和 ORDER BY 的情况下测试查询,并检查它返回的确切内容。如果您发现很多重复项,那么您可以通过使用更好的 JOIN 条件来加快查询速度。

现在,关于您的主要问题,答案很简单:将其添加到您的 proc

IF END_DATE > (BEGIN_DATE + INTERVAL 2 MONTH) THEN
    raise an error
ELSE
    your huge SELECT
END IF

这很简单。以下是如何在 mysql 存储过程中引发错误(执行方式取决于您的版本)。

您也可以简单地执行“SELECT 'your message here'”,然后消息字符串将返回给客户端(然后可能会崩溃,因为它需要一组特定的列,因此最好引发错误)。

于 2017-07-14T16:14:38.700 回答