我正試圖編寫一個過程,在行數未知的情況下連接表中的所有行。WHILE循環在Teradata程序
我有這個代碼,但它不工作。
CREATE PROCEDURE Test (OUT r VARCHAR(3000))
BEGIN
DECLARE RowCnt INT;
DECLARE CurrRow INT ;
SET CurrRow = 1,
r = 'SELECT ',
RowCnt = (SELECT COUNT(*)
FROM tableWithSQLStmnts
)
WHILE CurrRow <= RowCnt DO
BEGIN
SET r = r +
CASE WHEN CurrRow = 1
THEN 'MAX(CASE Seq WHEN ' + CAST(CurrRow AS VARCHAR) + '
THEN SqlStmnt
ELSE SPACE(0) END) + ' + CHAR(13)
WHEN i = RowCnt
THEN 'MAX(CASE Seq WHEN ' + CAST(CurrRow AS VARCHAR) + '
THEN '' '' + SqlStmnt
ELSE SPACE(0) END) ' + CHAR(13)
ELSE 'MAX(CASE Seq WHEN ' + CAST(CurrRow AS VARCHAR) + '
THEN '' '' + SqlStmnt
ELSE SPACE(0) END) + ' + CHAR(13)
END
SET CurrRow = CurrRow + 1 ;
END ;
SET r = r + '
FROM (SELECT SqlStmnt,
ROW_NUMBER() OVER (PARTITION BY TabName ORDER BY SQlStmnt)
FROM tableWithSQLStmnts t) D (SqlStmnt, Seq)
GROUP BY TabName;'
END WHILE;
END
;
,我發現了以下錯誤:
- 語法錯誤,期望像 ';'在一個整數和','。'之間。
- 意外的文字'SET'。
dnoeth建議的新代碼。
REPLACE PROCEDURE Test3 (IN TbName VARCHAR(256)) --, OUT r2 VARCHAR(3000))
BEGIN
DECLARE RowCnt INT;
DECLARE i INT;
DECLARE CurrRow INT;
DECLARE r VARCHAR(3000);
DECLARE r2 VARCHAR(3000);
SET CurrRow = 1;
SET r = 'SELECT ';
SET RowCnt = (SELECT COUNT(*)
FROM tableWithSQLStmnts
WHERE tabname = :TbName
);
WHILE CurrRow <= RowCnt DO
BEGIN
SET r = r ||
'MAX(CASE Seq WHEN ' || CAST(CurrRow AS VARCHAR(10)) || '
THEN '' , '' || SqlStmnt
ELSE '''' END)
'
|| CASE WHEN CurrRow = RowCnt
THEN ''
ELSE ' || '
END;
SET CurrRow = CurrRow + 1 ;
END;
END WHILE;
SET r = r || '
FROM (SELECT SqlStmnt,
ROW_NUMBER() OVER (PARTITION BY TbName ORDER BY SQlStmnt)
FROM tableWithSQLStmnts t) D (SqlStmnt)
GROUP BY TbName
;';
SET r2 = r;
CALL dbc.sysexecsql(:r);
END;
現在我得到這個錯誤:
[3706] Syntax error: Column name list shorter than select list.
編輯2:
我現在已經改寫這樣的:
REPLACE PROCEDURE Test3 (IN TabName VARCHAR(256))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE RowCnt INT;
DECLARE Seq INT;
DECLARE QRY VARCHAR(3000);
DECLARE CurrRow INT;
SET QRY= 'INSERT INTO vt21 SELECT ';
SET CurrRow = 1;
CREATE VOLATILE TABLE vt21(QRY VARCHAR(3000)) ON COMMIT PRESERVE ROWS;
SET RowCnt = (SELECT COUNT(*)
FROM TestTable
WHERE tabname = :TabName
);
FOR CurrentRefRow AS SourceCursor CURSOR FOR
SELECT SqlStmnt
FROM TestTable
DO
WHILE CurrRow <= RowCnt
DO
BEGIN
SET QRY = QRY ||
CASE WHEN CurrRow=1
THEN 'MAX(CASE Seq WHEN ' || CAST(CurrRow AS VARCHAR(10)) || '
THEN '' , '' || SqlStmnt
ELSE '''' END) '
WHEN CurrRow < RowCnt
THEN ', MAX(CASE Seq WHEN ' || CAST(CurrRow AS VARCHAR(10)) || '
THEN '' , '' || SqlStmnt
ELSE '''' END) '
WHEN CurrRow=RowCnt
THEN ', MAX(CASE Seq WHEN ' || CAST(CurrRow AS VARCHAR(10)) || '
THEN '' , '' || SqlStmnt
ELSE '''' END) '
ELSE ' || '
END;
SET CurrRow = CurrRow + 1 ;
END;
END WHILE;
SET QRY = QRY || '
FROM (SELECT SqlStmnt, Tabname,
ROW_NUMBER() OVER (PARTITION BY TabName ORDER BY SQlStmnt)
FROM TestTable t) D (Seq, Tabname, SqlStmnt)
GROUP BY TabName
;';
EXECUTE IMMEDIATE QRY;
END FOR;
BEGIN -- return the result set
DECLARE resultset CURSOR WITH RETURN ONLY FOR S1;
SET QRY = 'SELECT * FROM vt21;';
PREPARE S1 FROM QRY;
OPEN resultset;
END;
DROP TABLE vt21;
END;
但我發現了以下錯誤:
CALL失敗。位置分配列表具有太多的值。
我試着修改它,但是當我刪除一個值比它說列名稱列表更長,然後選擇列表。
看起來像MS SQL Server的SP,沒有'在Teradata的,沒有'SPACE/CHAR'的'OUT'參數的用法+'到Concat的字符串是錯誤的,很多分號丟失。 – dnoeth
@dnoeth,謝謝你的幫助。你能否澄清爲什麼OUT參數的使用是錯誤的,以及我在哪裏丟失分號?我是程序新手,我很難找到文檔。 – Barbara
根據標準SQL,只能設置OUT參數,但不能讀取(您需要聲明一個最終分配給out變量的中間變量)。 – dnoeth