Не уверен в правильном синтаксисе хранимой процедуры - PullRequest
0 голосов
/ 02 января 2019

Я работаю над другим кодом, который только что получил на этом сайте, и я впервые работаю с хранимой процедурой, поэтому я не совсем уверен, как должен работать синтаксис.Я работаю в Teradata SQL Assistant.Основная цель заключается в создании макроса с этими переменными.

CREATE PROCEDURE member_count(
        IN state CHAR(2),
        IN state_mbr CHAR(9))

--We have to tell it here that we will be returning a result set
DYNAMIC RESULT SETS 1
BEGIN

--Declare variables we will be using at the top
--One variable for the sql string
DECLARE my_sql VARCHAR(5000);

--And another for the cursor that we will open for the result set
DECLARE my_cursor CURSOR WITH RETURN ONLY FOR my_statement;

--Now we build our dynamically generated sql statement
--we use two single quotes together to escape the quote character
--(essentially we want a single quote in the SQL statement so we must
--double it as it's already inside single quotes).
SET my_sql = 'Select
    ''' || state || ''' as state
,case when m.var1 not in ('PREM','MPP') then 'SF'
        when m.var1 in ('JG',) then 'FI'
        when m.var1 in ('STU') and (m.var2 is not null or m.var2 not in ('xxx')) then 'HIM'
              else 'Other' end as lob
    ,count(m.dw_mbr_key) as members
FROM database. || state_mbr
group by 1,2
order by 1,2;'

---Now we "prepare" the "statement" from our string
PREPARE my_statement FROM my_sql;

---and we open the cursor. We don't close it because we want it returned.
OPEN my_cursor;
END;

CALL member_count(NM, NM_MBR);

Моя проблема в том, как мне обращаться с одинарными кавычками?Например, утверждение «когда», это проблема и что-то другое должно быть сделано?

Это сложно, потому что я не получаю никаких результатов или сообщений об ошибках.Только то, что говорит «Импортировать параметры стиля, найденные в запросе».

1 Ответ

0 голосов
/ 03 января 2019

Поскольку @ Error_2646 уже написал, что возиться со строками в кавычках в Dynamic SQL сложно.Вы должны начать с рабочего запроса без параметров

SELECT
   'NM' AS state
   ,CASE WHEN m.var1 NOT IN ('PREM','MPP') THEN 'SF'
         WHEN m.var1 IN ('JG') THEN 'FI'
         WHEN m.var1 IN ('STU') AND (m.var2 IS NOT NULL OR m.var2 NOT IN ('xxx')) THEN 'HIM'
         ELSE 'Other'
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.NM_MBR AS m
GROUP BY 1,2
ORDER BY 1,2;

Затем вы будете искать и заменять все ' на ''

SELECT
   ''NM'' AS state
   ,CASE WHEN m.var1 NOT IN (''PREM'',''MPP'') THEN ''SF''
         WHEN m.var1 IN (''JG'') THEN ''FI''
         WHEN m.var1 IN (''STU'') AND (m.var2 IS NOT NULL OR m.var2 NOT IN (''xxx'')) THEN ''HIM''
         ELSE ''Other''
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.NM_MBR AS m
GROUP BY 1,2
ORDER BY 1,2;

И заключать в кавычки весь запрос

'SELECT
   ''NM'' AS state
   ,CASE WHEN m.var1 NOT IN (''PREM'',''MPP'') THEN ''SF''
         WHEN m.var1 IN (''JG'') THEN ''FI''
         WHEN m.var1 IN (''STU'') AND (m.var2 IS NOT NULL OR m.var2 NOT IN (''xxx'')) THEN ''HIM''
         ELSE ''Other''
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.NM_MBR AS m
GROUP BY 1,2
ORDER BY 1,2;'

Наконец, вы заменяете параметры на ' || myparam || ', здесь ''NM'' & NM_MBR

'SELECT
   ' || NM || ' AS state
   ,CASE WHEN m.var1 NOT IN (''PREM'',''MPP'') THEN ''SF''
         WHEN m.var1 IN (''JG'') THEN ''FI''
         WHEN m.var1 IN (''STU'') AND (m.var2 IS NOT NULL OR m.var2 NOT IN (''xxx'')) THEN ''HIM''
         ELSE ''Other''
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.' || NM_MBR || ' AS m
GROUP BY 1,2
ORDER BY 1,2;'

Теперь вы получили допустимую строку SQL для использования в динамическом SQL.

Поскольку еще много потенциальных проблем / ошибок, я обычно определяю некоторую обработку ошибок и выходное сообщение, которое возвращает информацию об успешном выполнении или сбоях:

REPLACE PROCEDURE member_count(
        IN state CHAR(2),
        IN state_mbr CHAR(9),
        OUT msg VARCHAR(1000))

--We have to tell it here that we will be returning a result set
DYNAMIC RESULT SETS 1
BEGIN   
   -- constants
   DECLARE CRLF CHAR(2) DEFAULT '0D0A'xc; -- to simplify adding linebreaks
   -- I usually got multiple constants, e.g. for debugging.

   --Declare variables we will be using at the top
   --One variable for the sql string
   DECLARE my_sql VARCHAR(5000);

   --And another for the cursor that we will open for the result set
   DECLARE my_cursor CURSOR WITH RETURN ONLY FOR my_statement;

   --Now we build our dynamically generated sql statement
   --we use two single quotes together to escape the quote character
   --(essentially we want a single quote in the SQL statement so we must
   --double it as it's already inside single quotes).
   SET my_sql =
'SELECT
   ' || state|| ' AS state
   ,CASE WHEN m.var1 NOT IN (''PREM'',''MPP'') THEN ''SF''
         WHEN m.var1 IN (''JG'') THEN ''FI''
         WHEN m.var1 IN (''STU'') AND (m.var2 IS NOT NULL OR m.var2 NOT IN (''xxx'')) THEN ''HIM''
         ELSE ''Other''
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.' || state_mbr || ' AS m
GROUP BY 1,2
ORDER BY 1,2;'
   ;

   ---Now we "prepare" the "statement" from our string
   BEGIN
      -- adding a handler to catch error information
      DECLARE EXIT HANDLER FOR SqlException
      BEGIN -- there was an error during PREPARE or OPEN
         DECLARE errortext VARCHAR(1000);
         DECLARE Errorcode CHAR(5);
         GET DIAGNOSTICS EXCEPTION 1
             errortext = Message_Text,
             Errorcode = Returned_SqlState;

         SET msg = 'Failed: ' || Errorcode || ': ' || errortext
                   || CRLF || 'SQL Statement: ' 
                   || CRLF || my_sql;
      END;

      PREPARE my_statement FROM my_sql;

      ---and we open the cursor. We don't close it because we want it returned.
      OPEN my_cursor;

      -- only execute if there was no error
      SET msg = 'Finished: ' || Trim(Activity_Count) || ' rows returned';
   END;

END;

Теперь SP компилируется, новаш оригинальный CALL потерпит неудачу с [3810] Column/Parameter 'member_count.NM' does not exist..Вы должны передать свои параметры в виде строк:

CALL member_count('NM', 'NM_MBR', msg);

Это запускает и возвращает это msg

Failed: 52004: Database 'db' does not exist.
SQL Statement: 
SELECT
   NM AS state
   ,CASE WHEN m.var1 NOT IN ('PREM','MPP') THEN 'SF'
         WHEN m.var1 IN ('JG') THEN 'FI'
         WHEN m.var1 IN ('STU') AND (m.var2 IS NOT NULL OR m.var2 NOT IN ('xxx')) THEN 'HIM'
         ELSE 'Other'
    END AS lob
   ,Count(m.dw_mbr_key) AS members
FROM db.NM_MBR    AS m
GROUP BY 1,2
ORDER BY 1,2;

Внимание, CALL не завершился ошибкой, он выполнен успешно, но обработчикперехватил ошибку, и набор результатов не был возвращен.

Если выполнение выборки выполнено успешно, возвращаются два набора результатов, первым является сообщение `'Finished: возвращены строки xxx', а вторым фактический результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...