我正在尝试根据以下信息动态创建表..如果你在下面的输出中看到我没能正常工作我最终无法摆脱额外的','甚至没有关闭括号..请指教。
drop table t1;
/
create table t1 (table_name varchar2(10),COLUMN_NAME varchar2(10),DATATYPE varchar2(10),COLUMN_WIDTH NUMBER,is_null varchar2(1));
/
insert into t1 values ('TEST','FNAME','VARCHAR2',10,'Y');
insert into t1 values ('TEST','LNAME','VARCHAR2',10,'N');
commit;
代码
create or replace PROCEDURE P1(
P_TABLE_NM IN VARCHAR2 )
IS
LSQL VARCHAR2(1000);
LSQL2 VARCHAR2(100);
CURSOR C1
IS
SELECT * FROM T1 WHERE TABLE_NAME = P_TABLE_NM ;
RC1 C1%ROWTYPE;
BEGIN
lsql := 'create table '||P_TABLE_NM||'(';
OPEN C1;
LOOP
FETCH C1 INTO RC1;
EXIT WHEN C1%NOTFOUND;
LSQL := lsql||RC1.COLUMN_NAME||' '||RC1.DATATYPE||'('||RC1.COLUMN_WIDTH||') ';
BEGIN
IF (RC1.IS_NULL='Y') THEN
BEGIN
lsql := lsql || 'NOT NULL';
END;
END IF;
lsql := lsql || ',' || CHR(10);
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE(LSQL);
CLOSE C1;
END;
输出
create table TEST(FNAME VARCHAR2(10) NOT NULL,LNAME VARCHAR2(10) ,
答案 0 :(得分:0)
最简单的解决方法是在最后删除尾随逗号:
dbms_output.put_line(rtrim(lsql,',') || ' )');
似乎程序可以简化为:
create or replace procedure p1(p_table_nm in varchar2)
is
l_sql long := 'create table ' || p_table_nm || chr(10);
l_colsep varchar2(2) := '( '; -- changes to comma after first item
begin
for rc1 in (
select * from t1
where table_name = p_table_nm
)
loop
l_sql := l_sql || l_colsep || rc1.column_name || ' ' || rc1.datatype ||
case
when rc1.column_width is not null then '(' || rc1.column_width || ')'
end;
if rc1.is_null = 'N' then -- Changed from 'Y' - check requirement
l_sql := l_sql || ' NOT NULL';
end if;
l_sql := l_sql || chr(10);
l_colsep := ', ';
end loop;
dbms_output.put_line(rtrim(l_sql,chr(10)) || ' )');
end;
这样输出如下:
create table TEST
( FNAME VARCHAR2(10)
, LNAME VARCHAR2(10) NOT NULL
, STARTDATE DATE NOT NULL )
您是否计划处理默认值,生成的标识符,虚拟列或任何指定的列排序?
您还确定rc1.is_null = 'Y'
表示该列是强制性的吗?看起来恰恰相反。
答案 1 :(得分:0)
要修复您的代码,您可以将lsql := lsql || ',' || CHR(10)
更改为lsql := lsql || ','
并在RTRIM
之后添加END LOOP
,以删除其他逗号并包括右括号
lsql := RTRIM(lsql, ',' )|| ' )';
更好的选择是使用LISTAGG
这样的单个SQL语句。
SELECT 'CREATE TABLE '
|| TABLE_NAME
|| '('
|| CHR (10)
|| LISTAGG (
COLUMN_NAME
|| ' '
|| DATATYPE
|| CASE
WHEN COLUMN_WIDTH IS NOT NULL
THEN
'(' || COLUMN_WIDTH || ')'
END
|| CASE WHEN IS_NULL = 'Y' THEN ' NOT NULL' END,
',' || CHR (10))
WITHIN GROUP (ORDER BY COLUMN_NAME)
|| CHR (10)
|| ')'
AS create_table
FROM t1
WHERE table_name = 'TEST'
GROUP BY TABLE_NAME;