2017-01-26 1 views
0

J'essaye de convertir ce code (qui accepte un nom de colonne en entrée, fait des calculs sur la colonne d'entrée et insère des données dans une table). Maintenant que je sais que nous ne pouvons pas passer les noms de table/colonne à travers un proc ou une macro stockée, j'ai appris que nous pouvons le faire grâce à un SQL dynamique. Je ne suis pas sûr de savoir comment la syntaxe devrait être car je ne pouvais pas trouver un exemple clair et facile. Voici mon code qui doit être converti:Comment écrire un code SQL dynamique dans Teradata?

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 

ci-dessous est ma compréhension de sa conversion dans SQL dynamique:

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; 
); 

Je comprends que je dois résoudre beaucoup d'erreurs avant que ce code est exécuté prêt . Ainsi, l'une des premières erreurs que je reçois est ci-dessous:

enter image description here

Quelqu'un peut-il me s'il vous plaît aider. Je dois calculer la distribution quantile de plus de 60 colonnes qui font manuellement est fou. Très apprécié. Piyush

Répondre

2

La paire de parens commençant avant la BEGIN doivent être enlevés et tous les guillemets simples autour des chaînes, y compris les dates doivent être doublés:

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; 
+0

Salut @dnoeth. Je pourrais exécuter votre version avec succès, mais je pense que je n'ai pas géré correctement le nom de la colonne ici 'SELECT '|| COL ||' AS COLMN, 'et en raison de cela, je reçois les résultats suivants: http://stackoverflow.com/questions/41875937/how-to-delete-records-from-a-column-which-belong-to-a-different- type de données Solution de contournement pour obtenir le nom de la colonne au lieu de ses valeurs dans ** COLMN ** –

+0

J'utilise ''' | COL || '' AS COLMN' pour voir si cela modifie les résultats. –

+0

@PiyushVerma: Citant le paramètre devrait le réparer. – dnoeth