我正试图编写一个过程,在行数未知的情况下连接表中的所有行。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