如何在 Teradata 中编写动态 SQL 代码?

How to write a dynamic SQL code in Teradata?

我正在尝试转换此代码(它接受列名作为输入,对输入列进行计算并将数据插入 table)。现在我知道我们不能通过存储过程或宏传递 table/column 名称,我开始知道我们可以通过动态 SQL 来传递它。我不确定语法应该如何,因为我找不到一个清晰简单的例子。下面是我需要转换的代码:

INSERT INTO PROD_CE_WORK_SPACE.NPVAZ_CVM_CHECK_TEST_CASE_5

                    SELECT 
                                'DURATION_CELL_CURR' AS COLMN,
                                PW_END_DATE,
                                'ACPT' AS TAB,
                                MIN(DURATION_CELL_CURR) AS PER_MIN,
                                MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN DURATION_CELL_CURR END) AS PER_25,
                                MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN DURATION_CELL_CURR END) AS PER_50,
                                MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN DURATION_CELL_CURR END) AS PER_75,
                                MAX(DURATION_CELL_CURR) AS PER_MAX
                    FROM (
                                SELECT PC.*,
                                 ROW_NUMBER() OVER (ORDER BY DURATION_CELL_CURR) AS SEQNUM,
                                 COUNT(*) OVER () AS CNT
                                  FROM PROD_EXP_DL_CVM.ACPT_PROD_CVM PC
                                  WHERE PC.PW_END_DATE =  '2017-01-17'
                                )A
                                GROUP BY 1,2,3

UNION ALL

                    SELECT 
                                'DURATION_CELL_CURR' AS COLMN,
                                PW_END_DATE,
                                'PROD' AS TAB,
                                MIN(DURATION_CELL_CURR) AS PER_MIN,
                                MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN DURATION_CELL_CURR END) AS PER_25,
                                MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN DURATION_CELL_CURR END) AS PER_50,
                                MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN DURATION_CELL_CURR END) AS PER_75,
                                MAX(DURATION_CELL_CURR) AS PER_MAX
                    FROM (
                                SELECT PC.*,
                                 ROW_NUMBER() OVER (ORDER BY DURATION_CELL_CURR) AS SEQNUM,
                                 COUNT(*) OVER () AS CNT
                                  FROM PROD_EXP_DL_CVM.PROD_CVM PC
                                  WHERE PC.PW_END_DATE =  '2017-01-17'
                                )B
                                GROUP BY 1,2,3

下面是我对其动态转换的理解SQL:

REPLACE PROCEDURE PROD_CE_WORK_SPACE.NPVAZ_CVM_CHECK_TEST_CASE (IN COL CHAR(50))
(
BEGIN REQUEST
CALL DBC.SYSEXECSQL
('
INSERT INTO PROD_CE_WORK_SPACE.NPVAZ_CVM_CHECK_TEST_CASE_5
                            SELECT
                            '||COL||' AS COLMN,
                            PW_END_DATE,
                            ''ACPT'' AS TAB,
                            MIN( '||COL||') AS PER_MIN,
                            MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN  '||COL||' END) AS PER_25,
                            MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN  '||COL||' END) AS PER_50,
                            MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN  '||COL||' END) AS PER_75,
                            MAX( '||COL||') AS PER_MAX
                            FROM (
                                        SELECT PC.*,
                                         ROW_NUMBER() OVER (ORDER BY  '||COL||') AS SEQNUM,
                                         COUNT(*) OVER () AS CNT
                                          FROM PROD_EXP_DL_CVM.ACPT_PROD_CVM PC
                                          WHERE PC.PW_END_DATE =  '2017-01-17'
                                         )A
                            GROUP BY 1,2,3

            UNION ALL

                            SELECT 
                            '||COL||' AS COLMN,
                            PW_END_DATE,
                            ''PROD'' AS TAB,
                            MIN( '||COL||') AS PER_MIN,
                            MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN  '||COL||' END) AS PER_25,
                            MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN  '||COL||' END) AS PER_50,
                            MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN  '||COL||' END) AS PER_75,
                            MAX( '||COL||') AS PER_MAX
                            FROM (
                                SELECT PC.*,
                                 ROW_NUMBER() OVER (ORDER BY  '||COL||') AS SEQNUM,
                                 COUNT(*) OVER () AS CNT
                                  FROM PROD_EXP_DL_CVM.PROD_CVM PC
                                  WHERE PC.PW_END_DATE =  '2017-01-17'
                                )B
                          GROUP BY 1,2,3
')

END REQUEST;
);

我知道在 运行-ready 之前我必须解决许多错误。所以我遇到的第一个错误如下:

谁能帮我解决这个问题。我必须计算 60 多个这样的列的分位数分布,手动操作是疯狂的。 非常感激。 皮尤什

应该删除 BEGIN 之前的一对括号,并且包括日期在内的所有字符串周围的单引号都必须加倍:

REPLACE PROCEDURE NPVAZ_CVM_CHECK_TEST_CASE (IN COL CHAR(50))
BEGIN
CALL DBC.SYSEXECSQL
('
INSERT INTO PROD_CE_WORK_SPACE.NPVAZ_CVM_CHECK_TEST_CASE_5
                            SELECT
                            '||COL||' AS COLMN,
                            PW_END_DATE,
                            ''ACPT'' AS TAB,
                            MIN( '||COL||') AS PER_MIN,
                            MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN  '||COL||' END) AS PER_25,
                            MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN  '||COL||' END) AS PER_50,
                            MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN  '||COL||' END) AS PER_75,
                            MAX( '||COL||') AS PER_MAX
                            FROM (
                                        SELECT PC.*,
                                         ROW_NUMBER() OVER (ORDER BY  '||COL||') AS SEQNUM,
                                         COUNT(*) OVER () AS CNT
                                          FROM PROD_EXP_DL_CVM.ACPT_PROD_CVM PC
                                          WHERE PC.PW_END_DATE = DATE ''2017-01-17''
                                         )A
                            GROUP BY 1,2,3

            UNION ALL

                            SELECT 
                            '||COL||' AS COLMN,
                            PW_END_DATE,
                            ''PROD'' AS TAB,
                            MIN( '||COL||') AS PER_MIN,
                            MIN(CASE WHEN SEQNUM / 0.25 >= CNT THEN  '||COL||' END) AS PER_25,
                            MIN(CASE WHEN SEQNUM / 0.50 >= CNT THEN  '||COL||' END) AS PER_50,
                            MIN(CASE WHEN SEQNUM / 0.75 >= CNT THEN  '||COL||' END) AS PER_75,
                            MAX( '||COL||') AS PER_MAX
                            FROM (
                                SELECT PC.*,
                                 ROW_NUMBER() OVER (ORDER BY  '||COL||') AS SEQNUM,
                                 COUNT(*) OVER () AS CNT
                                  FROM PROD_EXP_DL_CVM.PROD_CVM PC
                                  WHERE PC.PW_END_DATE =  DATE ''2017-01-17''
                                )B
                          GROUP BY 1,2,3
');

END;