I want to create a table inside of a procedure. I tried to put the create query in a string then execute immediate the string. For example:
create or replace procedure hr.temp is
var1 varchar2(4000);
begin
var1:='create table hr.temp(
id number)';
execute immediate var1;
end temp;
But when I execute this procedure I get the error:
ORA-00911: invalid character
ORA-06512: at "SYS.TEMP", line 6
.
.
.
Is there any way I can do this?
Try this. It should work...
create or replace procedure hr.temp is
var1 varchar2(4000);
BEGIN
var1:='create table hr.temp2(
id number)';
EXECUTE IMMEDIATE var1;
end temp;
the answer of m.r 'a_horse_with_no_name' is right. The first point is I should not create a table in sys schema.
The second point is in a dynamic sql I should not use ; character in dynamic sql.
Related
I have a table like having one column containing this data
Dummy Column
Alter PACKAGE ABC COMPILE;
Alter PACKAGE CDE COMPILE;
Alter PROCEDURE ABC COMPILE;
Alter TRIGGER ABC COMPILE;
I want to make a script such that when i run that it will execute the alter statements line by line and perform the DDL operations.
Something like this should work, obviously assuming you have real DDL statements stored in that dummy column.
for loop over the column when the value is not null
replace the ; by nothing in order to use execute immediate
Example
declare
vsql table.dummy_column%type;
begin
for h in ( select dummy_column from table where dummy_column is not null )
loop
vsql := replace(h.dummy_column,';','');
execute immediate vsql;
end loop;
end;
/
Since my school does not allow me to post the code, hence i had to come back home and put up an example to show the issue i am facing. My school asked me to do a homework on dynamic sql to create a table and later insert one dummy record to it. But while doing it I am facing the below issue. Please find the code below for your reference. Thank you.
Procedure:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Plsql Block to call the procedure:
set serveroutput on;
declare
a varchar2(10);
b varchar2(10);
c varchar2(10);
begin
a:='Example';
b:='id';
c:='nm';
table_creation(a,b,c);
dbms_output.put_line('Yes');
end;
/
The procedure is getting created perfectly and while running the above block i am getting the below error .
declare
*
ERROR at line 1:
ORA-00904: "NM": invalid identifier
ORA-06512: at "SYS.TABLE_CREATION", line 9
ORA-06512: at line 9
But when I checked the created table. The table exists with 0 records. The structure of the table is as follows.
Name Null? Type
----------------------------------------- -------- ---------------
ID VARCHAR2(10)
NM VARCHAR2(10)
Any help from your end is much appreciated.
Nick,
Please note that the above procedure will create the column with a double qoutes ("ID","NM") hence the error occurred. Please find the updated code and check if the issue has resolved.
According to oracle=>
Oracle is case sensitive in column and table names. It just converts everything to upper case by default. But if you use names in double quotes, you tell Oracle to create the column in the exact spelling you provided (lower case in the CREATE statement).
Code:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Note: I have not touched any other logic of the code. Please try and let us know the result.
Only change is
From :
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
to :
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';
I'm trying to create a procedure that will update a column in my table with an ORDSYS.ORD Image. The code I have is bellow and it keeps telling me errors when I'm trying to use it. Can some please help? Thank you
Procedure code:
create or replace
PROCEDURE Inserting_Images (REST_ID NUMBER, RESTImage ORDSYS.ORDImage) AS
ctx RAW(64):=NULL;
BEGIN
UPDATE restaurant_table
Set RESTImage = RESTImage
WHERE REST_id = REST_ID;
COMMIT;
EXCEPTION
WHEN others THEN
BEGIN
ROLLBACK;
dbms_output.put_line(sqlerrm);
END;
--Error Handling.
END;
--Ends the procedure.
Using Procedure:
BEGIN
inserting_images(52, 'YUSKIN.jpeg');
END;
The function Inserting_Images accepts an argument of ORDSYS.ORDImage, whereas what you are actually sending it is a VARCHAR, to get the behaviour you want, you need to initialize the ORDImage object first like so:
CREATE OR REPLACE DIRECTORY FILE_DIR as '/mydir/work';
GRANT READ ON DIRECTORY FILE_DIR TO 'user';
inserting_images(52, ORDSYS.ORDImage.init('FILE', 'FILE_DIR','speaker.jpg'));
(Quoted from docs.oracle.com)
I want to alter a table within a For loop in Netteza SQL. I know that Netteza does not allow alter table in a stored procedure. As quoted:
"These SQL commands are also prohibited within the body of a Netezza stored procedure."
Are there any alternatives for doing so? I am a beginner in Netteza. I also don't know if my loop format is correct?
CREATE OR REPLACE PROCEDURE "SP_Automate_Table"()
RETURNS INTEGER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
vSQL1 varchar(30000) ;
BEGIN
FOR i in 2011..2014
LOOP
For j in 1..12
Loop
call "SP_Count"(i, j);
vSQL1:='alter table X add columnX INT';
....
...
..
EXECUTE immediate vSQL1;
END LOOP;
END LOOP;
END;
END_PROC;
Starting with v7.1 you can declare an AUTOCOMMIT ON block in a stored procedure, and in this block you can call statements that would otherwise be prohibited within a stored procedure.
CREATE OR REPLACE PROCEDURE ADMIN.SP_ALTER_LOOP(INTEGER, INTEGER)
RETURNS INTEGER
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
pStartVal ALIAS FOR $1;
pCount ALIAS FOR $2;
vSQL varchar(30000);
BEGIN
BEGIN AUTOCOMMIT ON
for i in 1 .. pCount LOOP
vSQL := 'ALTER TABLE CLAIM_' || pStartVal + i-1 || ' ADD COLUMN (COL2 BIGINT);';
EXECUTE IMMEDIATE vSQL;
END LOOP;
END;
END;
END_PROC;
Prior to v7.1, I don't know of a way you can alter a table structure from with a stored procedure.
Note that in the general case of ALTER TABLE (whether scripted like this or manual), be sure to perform a groom of each altered table after the ALTER operation.
GROOM TABLE tablename VERSIONS;
Your loop statement is syntactically correct, but there is no way to issue alter statements from within nzplsql.
I would suggest doing a bash script as an alternative, repeatedly calling nzsql.
for i in $(seq 2011 2014); do
for j in $(seq 1 12); do
nzsql -c "call \"SP_Count\"($i, $j);"
nzsql -c "alter table X add columnX INT;"
done
done
I can't really imagine a use case where you'd want to dynamically add columns by calling a stored procedure from within a database that couldn't also be covered by doing it outside the database.
I am trying to build an Oracle stored procedure which will accept a table name as a parameter. The procedure will then rebuild all indexes on the table.
My problem is I get an error while using the ALTER command from a stored procedure, as if PLSQL does not allow that command.
Use the execute immediate statement to execute DDL inside PL/SQL.
create procedure RebuildIndex(index_name varchar2) as
begin
execute immediate 'alter index ' || index_name || ' rebuild';
end;
I tested this code; it works.
Documentation.
Passing Schema Object Names As Parameters
Suppose you need a procedure that
accepts the name of any database
table, then drops that table from your
schema. You must build a string with a
statement that includes the object
names, then use EXECUTE IMMEDIATE to
execute the statement:
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
END;
/
Use concatenation to build the string,
rather than trying to pass the table
name as a bind variable through the
USING clause.
In addition, if you need to call a
procedure whose name is unknown until
runtime, you can pass a parameter
identifying the procedure. For
example, the following procedure can
call another procedure (drop_table) by
specifying the procedure name when
executed.
CREATE PROCEDURE run_proc (proc_name IN VARCHAR2, table_name IN VARCHAR2) ASBEGIN
EXECUTE IMMEDIATE 'CALL "' || proc_name || '" ( :proc_name )' using table_name;
END;
/
If you want to drop a table with the
drop_table procedure, you can run the
procedure as follows. Note that the
procedure name is capitalized.
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
BEGIN
run_proc('DROP_TABLE', 'employees_temp');
END;
/
Here are a couple of possibilities. First, you would have to treat the SQL as dynamic SQL. Second, Oracle DDL statements cannot be run in a transaction (or, they terminate the current transaction and cannot themselves be rolled back). This may affect whether you can use them in stored procedures, or where you can use stored procedures that contain them.
If none of the above apply at all - there could easily be something else astray - I suggest posting some code.