我想知道此过程中的错误
set serveroutput on
create or replace procedure insert_table(column_name in varchar2, dat in varchar2)
as
table_name varchar2(100):= column_name || '_' || dat;
sql_create varchar2(100) := 'create table '||table_name||'(FIRSTNAME varchar2(100))';
sql_str varchar2(100);
CURSOR c_emp is
select FIRSTNAME
from employees
where column_name = dat;
begin
execute immediate sql_create;
for r_reg in c_emp
loop
sql_str:='INSERT INTO '||table_name||'('''||r_reg.firstname||''')';
execute immediate sql_str;
end loop;
end;
/
execute insert_table('CITY','London');
编辑: 好的,我在语法错误中添加了下面提到的更正,但是我该怎么做,以便可以在游标处获取列名的参数,因为目前它的类型为varchar,'CITY'应该是行名。
答案 0 :(得分:1)
您将需要如下使用光标中的dynamic query
。另外,您错过了我添加的VALUES
语句中的INSERT
关键字(请参阅代码中的内联注释)
Oracle示例数据创建:
SQL> CREATE TABLE "EMPLOYEES" (
2 "ID" NUMBER,
3 "FIRSTNAME" VARCHAR2(100 BYTE),
4 "CITY" VARCHAR2(100 BYTE),
5 PRIMARY KEY ( "ID" ) USING INDEX ENABLE
6 );
Table created.
SQL>
现在,让我们创建您的过程
SQL> CREATE OR REPLACE PROCEDURE INSERT_TABLE (
2 COLUMN_NAME IN VARCHAR2,
3 DAT IN VARCHAR2
4 ) AS
5
6 TABLE_NAME VARCHAR2(100) := COLUMN_NAME || '_' || DAT;
7 SQL_CREATE VARCHAR2(100) := 'create table ' || TABLE_NAME || '(FIRSTNAME varchar2(100))';
8 C_EMP SYS_REFCURSOR; -- declaration of cursor
9 LV_FNAME EMPLOYEES.FIRSTNAME%TYPE; -- to store the each value from cursor
10 BEGIN
11 EXECUTE IMMEDIATE SQL_CREATE;
12 OPEN C_EMP FOR 'SELECT FIRSTNAME
13 FROM EMPLOYEES
14 WHERE ' || COLUMN_NAME || ' = ''' || DAT || '''';
15 -- above statement used dynamic query in cursor
16 LOOP
17 FETCH C_EMP INTO LV_FNAME;
18 EXIT WHEN C_EMP%NOTFOUND;
19 EXECUTE IMMEDIATE 'INSERT INTO ' || TABLE_NAME || ' VALUES (''' || LV_FNAME || ''')'; -- added VALUES keyword in INSERT statement.
20 END LOOP;
21
22 COMMIT;
23 END INSERT_TABLE;
24 /
让我们执行它并立即查看结果。
SQL>
SQL> EXECUTE INSERT_TABLE('CITY', 'London');
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> SELECT * FROM CITY_LONDON;
FIRSTNAME
--------------------------------------------------------------------------------
TEJASH
SQL>
哦,是的,它创建了所需的表,并且正确填充了数据。
干杯!
答案 1 :(得分:0)
您缺少引号。这个
sql_str:='INSERT INTO '||table_name||'('||r_reg.firstname||');';
应该是
sql_str:='INSERT INTO '||table_name||'('''||r_reg.firstname||''');';
这会将INSERT INTO CITY_London (Peter);
变成INSERT INTO CITY_London ('Peter');
。
根据文档(例如https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/dynamic.htm):
在动态字符串中构造单个SQL语句时,请不要在引号内的末尾包括分号(;)。
因此EXECUTE IMMEDIATE
的两个SQL字符串应为:
sql_create varchar2(100) := 'create table ' || table_name || '(FIRSTNAME varchar2(100))';
和
sql_str := 'INSERT INTO ' || table_name || '(''' || r_reg.firstname || ''')';
答案 2 :(得分:0)
这是您最后一个问题的答案。您可以像下面那样将参数传递给光标:
declare
CURSOR c_emp(p_param varchar2) is
select p_param val
from dual;
begin
for r_reg in c_emp('b')
loop
dbms_output.put_line(r_reg.val);
end loop;
end;