Alter Table 在 PL SQL 循环中添加列
Alter Table Add Column in PL SQL loop
我正在尝试使用遍历游标的 for 循环在 table 中插入列。代码是:
declare
cursor Months_ET is
SELECT distinct to_char(FEE_CD_ACT_SUM_ACCTG_DA, 'MON-YY') as "Month_U"
FROM EXPORT_TABLE
WHERE EXPORT_TABLE.FEE_CD_ACT_SUM_ACCTG_DA >= to_date('10/01/2013','mm/dd/yyyy')
AND EXPORT_TABLE.FEE_CD_ACT_SUM_ACCTG_DA < to_date('10/01/2014', 'mm/dd/yyyy');
n integer := 1;
begin
for mon in Months_ET loop
dbms_output.put_line(mon."Month_U");
execute immediate 'Alter table "Fee_CT" add('|| mon."Month_U" ||' varchar(20))';
n := n +1;
end loop;
end;
开头的光标 jsut 得到一个唯一的月份名称列表,dbms_output.put_line 打印为:
SEP-14
AUG-14
JUL-14
所以我知道变量不为空。
因此,我想使用这些结果为每个月-年添加三列。但是我得到一个无效的数据类型错误。我也尝试过更改 for 循环以在引号之外连接 table 名称,如下所示:
for mon in Months_ET loop
--Month_List(n) := mon."Month_U";
dbms_output.put_line(mon."Month_U");
execute immediate 'Alter table' ||"Fee_CT" || 'add('|| mon."Month_U" ||' varchar(20))';
n := n +1;
但我收到一条消息 "Table,View Or Sequence reference 'Fee_CT' not allowed in this context." 不确定我做错了什么。实际数据要大得多,涵盖的时间范围更广,因此使用多个 alter table 语句是不现实的。再加上底层数据会发生变化,所以我需要能够使用底层数据更改列名。
始终使用 DBMS_OUTPUT.PUT_LINE
来测试您的 execute immediate
语句。
- 在keywords/variables之间给出space。
- 使用单引号
现在检查这个例子:
create table Table_A(id integer);
-- Table created.
Declare
sql_stmnt varchar2(400) ;
table_name varchar2(20) := 'Table_A';
column_name varchar2(20) := 'New_col1';
data_type varchar2(20) := 'varchar2(20)' ;
Begin
sql_stmnt := ' alter table ' || table_name || ' add( ' || Column_name || ' ' || data_type || ' ) ' ;
execute immediate sql_stmnt ;
dbms_output.put_line(sql_stmnt );
End;
-- alter table Table_A add( New_col1 varchar2(20) )
-- Table altered.
Desc Table_A;
Column Data Type Length Precision Scale
ID NUMBER 22 - 0 - - -
NEW_COL1 VARCHAR2 20 - - - - -
不确定为什么要创建列dynamically.But但有可能:
Errors :
1.Column names can only have '_'(underscore),no other special character. ie.,AUG-15 --> AUG_15
When using Alias names for further processing use SUBQUERY
(Month_U )
Quotes should be properly used.
- space between keywords/variable in execute statement.
create table Table_A
(id integer,
date1 date
);
-- Table created.
begin
insert into table_A values (1,trunc(sysdate) );
insert into table_A values (2,trunc(sysdate+100) );
end;
select to_char(date1, 'MON-YY') as "Month_U" from table_A;
--AUG-15
--DEC-15
Declare
cursor months_ET is select month_u from
( select to_char(date1, 'MON_YY') AS Month_U from table_A) DUAL;
sql_stmnt varchar2(400) ;
table_name varchar2(20) := 'Table_A';
column_name varchar2(20) := 'New_col1';
data_type varchar2(20) := 'date' ; -- you can change to varchar2
Begin
FOR MON in months_ET
LOOP
sql_stmnt := ' alter table ' || table_name || ' add( ' || MON.MONTH_U
|| ' ' || data_type || ' ) ' ;
dbms_output.put_line(sql_stmnt );
Execute immediate sql_stmnt ;
END LOOP;
End;
输出:
alter table Table_A add( AUG_15 date )
alter table Table_A add( DEC_15 date )
Table altered.
您的 table 名称和列名称使用了非标准字符 - 小写字母、破折号。这是一个非常糟糕的主意,因为这意味着 to wrap every reference in double-quotes。每个必须使用你的模式的人都会在他们必须修复 PLS-00357
、ORA-00903
或 ORA-00904
异常时诅咒你,因为他们忘记了双引号标识符。看,它甚至把你抓出来了:)
但如果你真的想坚持,你需要的声明是:
execute immediate 'Alter table "Fee_CT" add("'|| mon."Month_U" ||"' varchar(20))';
table 名称是样板文本的一部分,而不是变量。您需要将非标准列名称用双引号引起来。确保样板文件中的关键字周围有空格。
最重要的是,请记住动态 SQL 中的语法错误会引发运行时错误,而不是编译错误。使用日志记录或 DBMS_OUTPUT 查看汇编语句。
我正在尝试使用遍历游标的 for 循环在 table 中插入列。代码是:
declare
cursor Months_ET is
SELECT distinct to_char(FEE_CD_ACT_SUM_ACCTG_DA, 'MON-YY') as "Month_U"
FROM EXPORT_TABLE
WHERE EXPORT_TABLE.FEE_CD_ACT_SUM_ACCTG_DA >= to_date('10/01/2013','mm/dd/yyyy')
AND EXPORT_TABLE.FEE_CD_ACT_SUM_ACCTG_DA < to_date('10/01/2014', 'mm/dd/yyyy');
n integer := 1;
begin
for mon in Months_ET loop
dbms_output.put_line(mon."Month_U");
execute immediate 'Alter table "Fee_CT" add('|| mon."Month_U" ||' varchar(20))';
n := n +1;
end loop;
end;
开头的光标 jsut 得到一个唯一的月份名称列表,dbms_output.put_line 打印为:
SEP-14
AUG-14
JUL-14
所以我知道变量不为空。
因此,我想使用这些结果为每个月-年添加三列。但是我得到一个无效的数据类型错误。我也尝试过更改 for 循环以在引号之外连接 table 名称,如下所示:
for mon in Months_ET loop
--Month_List(n) := mon."Month_U";
dbms_output.put_line(mon."Month_U");
execute immediate 'Alter table' ||"Fee_CT" || 'add('|| mon."Month_U" ||' varchar(20))';
n := n +1;
但我收到一条消息 "Table,View Or Sequence reference 'Fee_CT' not allowed in this context." 不确定我做错了什么。实际数据要大得多,涵盖的时间范围更广,因此使用多个 alter table 语句是不现实的。再加上底层数据会发生变化,所以我需要能够使用底层数据更改列名。
始终使用 DBMS_OUTPUT.PUT_LINE
来测试您的 execute immediate
语句。
- 在keywords/variables之间给出space。
- 使用单引号
现在检查这个例子:
create table Table_A(id integer);
-- Table created.
Declare
sql_stmnt varchar2(400) ;
table_name varchar2(20) := 'Table_A';
column_name varchar2(20) := 'New_col1';
data_type varchar2(20) := 'varchar2(20)' ;
Begin
sql_stmnt := ' alter table ' || table_name || ' add( ' || Column_name || ' ' || data_type || ' ) ' ;
execute immediate sql_stmnt ;
dbms_output.put_line(sql_stmnt );
End;
-- alter table Table_A add( New_col1 varchar2(20) )
-- Table altered.
Desc Table_A;
Column Data Type Length Precision Scale
ID NUMBER 22 - 0 - - -
NEW_COL1 VARCHAR2 20 - - - - -
不确定为什么要创建列dynamically.But但有可能:
Errors :
1.Column names can only have '_'(underscore),no other special character. ie.,
AUG-15 --> AUG_15
When using Alias names for further processing use
SUBQUERY
(Month_U )Quotes should be properly used.
- space between keywords/variable in execute statement.
create table Table_A
(id integer,
date1 date
);
-- Table created.
begin
insert into table_A values (1,trunc(sysdate) );
insert into table_A values (2,trunc(sysdate+100) );
end;
select to_char(date1, 'MON-YY') as "Month_U" from table_A;
--AUG-15
--DEC-15
Declare
cursor months_ET is select month_u from
( select to_char(date1, 'MON_YY') AS Month_U from table_A) DUAL;
sql_stmnt varchar2(400) ;
table_name varchar2(20) := 'Table_A';
column_name varchar2(20) := 'New_col1';
data_type varchar2(20) := 'date' ; -- you can change to varchar2
Begin
FOR MON in months_ET
LOOP
sql_stmnt := ' alter table ' || table_name || ' add( ' || MON.MONTH_U
|| ' ' || data_type || ' ) ' ;
dbms_output.put_line(sql_stmnt );
Execute immediate sql_stmnt ;
END LOOP;
End;
输出:
alter table Table_A add( AUG_15 date )
alter table Table_A add( DEC_15 date )
Table altered.
您的 table 名称和列名称使用了非标准字符 - 小写字母、破折号。这是一个非常糟糕的主意,因为这意味着 to wrap every reference in double-quotes。每个必须使用你的模式的人都会在他们必须修复 PLS-00357
、ORA-00903
或 ORA-00904
异常时诅咒你,因为他们忘记了双引号标识符。看,它甚至把你抓出来了:)
但如果你真的想坚持,你需要的声明是:
execute immediate 'Alter table "Fee_CT" add("'|| mon."Month_U" ||"' varchar(20))';
table 名称是样板文本的一部分,而不是变量。您需要将非标准列名称用双引号引起来。确保样板文件中的关键字周围有空格。
最重要的是,请记住动态 SQL 中的语法错误会引发运行时错误,而不是编译错误。使用日志记录或 DBMS_OUTPUT 查看汇编语句。