I have procedure below which create procedure in different projects
CREATE OR REPLACE PROCEDURE `sp_get_data`(arg_ProjectID STRING, arg_DatasetID STRING)
OPTIONS(strict_mode=FALSE)
BEGIN
EXECUTE IMMEDIATE
"CREATE OR REPLACE PROCEDURE `"|| arg_ProjectID || "." || arg_DatasetID || ".sp_get_data_details`() \r\n"||
"BEGIN
-- lengthy code
"END"
;
END;
The code insde procedure is very very lengthy.
When I run this create procedure with OPTIONS(strict_mode=FALSE), it is working..., but it doesn't not save in procedure script..
how to make it persist in procedure script
without it throws error
Query error: Out of stack space due to deeply nested query expression
during query resolutio
But how can I add this dynamically when calling like
call sp_get_data(projectid,datasetid)
Any help,
Highly appreciated
I want to convert all tables from a specific user to JSON (or XML) Format. I've read about a "trick" mentioned by SQL Developer.
In other words, I already started to create a Procedure with two parameters:
p_format: The format (in my case it will be "json")
p_user: The username
As IDE I use Oracle SQL Developer and my database is an Oracle XE Database.
At first the procedure loops though all tables of the given user and in the loop, it should execute the following:
SELECT /*p_format*/ * FROM p_user || '.' || table
Unfortunately, I cannot use this SELECT Statement as mentioned above. I need to use the command EXECUTE IMMEDIATE <Statement>.
The next problem I faced was the following: I wanted to output the result of the EXECUTE IMMEDIATE command. Therefore I used the command EXECUTE IMMEDIATE <Statement> INTO <Variable>. After compiling the procedure and executing it, I stumpled across the following Error:
"inconsistent datatypes: expected %s got %s"
This is my code of the procedure:
CREATE OR REPLACE PROCEDURE EXPORT_TABLE_TO_FORMAT_FROM(p_format VARCHAR2, p_user VARCHAR2) IS
/***************************************************************************
Author:
Class:
School:
Date:
Function - EXPORT_TABLE_TO_JSON_FROM(p_user):
Displays the data of every table from a given User as JSON
Parameter: p_user ... User
***************************************************************************/
v_tableData VARCHAR2(32767);
v_sqlStatement VARCHAR2(200);
BEGIN
FOR tablerec IN (SELECT *
FROM ALL_TABLES
WHERE OWNER = p_user)
LOOP
v_sqlStatement := 'SELECT /*' || p_format || '*/ * FROM ' || p_user || '.' || tablerec.TABLE_NAME;
EXECUTE IMMEDIATE v_sqlStatement INTO v_tableData;
DBMS_OUTPUT.PUT_LINE (v_sqlStatement);
END LOOP;
END;
You can see that I loop though all tables of a given user and created a sql statement with p_format and p_user and with tablerec.TABLE_NAME.
The desired result should look exactly like that:
{"results":[{"columns":[{"name":"COUNTRY_ID","type":"CHAR"},
{"name":"COUNTRY_NAME","type":"VARCHAR2"},{"name":"REGION_ID","type":"NUMBER"}],"items":
[
{"country_id":"AR","country_name":"Argentina","region_id":2},
{"country_id":"AU","country_name":"Australia","region_id":3},
{"country_id":"BE","country_name":"Belgium","region_id":1},
{"country_id":"BR","country_name":"Brazil","region_id":2},
{"country_id":"CA","country_name":"Canada","region_id":2},
{"country_id":"CH","country_name":"Switzerland","region_id":1},
{"country_id":"CN","country_name":"China","region_id":3},
{"country_id":"DE","country_name":"Germany","region_id":1},
{"country_id":"DK","country_name":"Denmark","region_id":1},
{"country_id":"EG","country_name":"Egypt","region_id":4},
{"country_id":"FR","country_name":"France","region_id":1},
{"country_id":"IL","country_name":"Israel","region_id":4},
{"country_id":"IN","country_name":"India","region_id":3},
{"country_id":"IT","country_name":"Italy","region_id":1},
{"country_id":"JP","country_name":"Japan","region_id":3},
{"country_id":"KW","country_name":"Kuwait","region_id":4},
{"country_id":"ML","country_name":"Malaysia","region_id":3},
{"country_id":"MX","country_name":"Mexico","region_id":2},
{"country_id":"NG","country_name":"Nigeria","region_id":4},
{"country_id":"NL","country_name":"Netherlands","region_id":1},
{"country_id":"SG","country_name":"Singapore","region_id":3},
{"country_id":"UK","country_name":"United Kingdom","region_id":1},
{"country_id":"US","country_name":"United States of America","region_id":2},
{"country_id":"ZM","country_name":"Zambia","region_id":4},
{"country_id":"ZW","country_name":"Zimbabwe","region_id":4}]}]}
The JSON hint is specific to SQL Developer and SQLcl, not the database directly. So you need to run the entire thing within these tools.
Easiest way to do that is to have your script write a script that you can then run, eg
spool /tmp/get_all_json.sql
select 'select /*json*/ * from '||table_name||';'
from user_tables;
spool off
#/tmp/get_all_json.sql
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've created the following package with 3 procedures:
CREATE OR REPLACE PACKAGE PQ_PaqueteIntegrantes
AS
PROCEDURE INTEG_INSERCIONES(paIdIntegrante IN CreadorTablas.INTEGRANTES.ID_INTEGRANTE%TYPE
,paNombre IN CreadorTablas.INTEGRANTES.NOMBRE%TYPE
,paApellidoPaterno IN CreadorTablas.INTEGRANTES.APELLIDO_PATERNO%TYPE);
PROCEDURE INTEG_MODIFICACIONES(paIdIntegrante IN OUT CreadorTablas.INTEGRANTES.ID_INTEGRANTE%TYPE
,paNombre IN OUT CreadorTablas.INTEGRANTES.NOMBRE%TYPE
,paApellidoPaterno IN OUT CreadorTablas.INTEGRANTES.APELLIDO_PATERNO%TYPE);
PROCEDURE INTEG_ELIMINCACIONES(
paIdIntegrante IN OE.EJEMPLO_TRANSAC_CLASE.CUSTOMER_ID%TYPE
,paMjeDescError OUT VARCHAR2
,paCodeError OUT NUMBER);
END PQ_PaqueteIntegrantes;
I created those procedures with a user called Admin_proyectos. The first procedures makes "Inserts", the second one "Updates", and the last one "Deletes", all of them working on a table called Integrantes, that table comes from another user called CreadorTablas.
My intention is to create another user called Admin, who will have the responsibility to do those things, using the procedures from this package, of course. I've tried doing an PL/SQL block, but it didn't work, neither with an EXEC.
GRANT EXECUTE ON ADMIN_PROYECTOS.PQ_PaqueteIntegrantes TO Admin
Then, you can call the procedures in this package with Admin user as
BEGIN
ADMIN_PROYECTOS.PQ_PaqueteIntegrantes.INTEG_INSERCIONES(paIdIntegrante, paNombre, paNombre);
END;
You can use execute immediate statement:
l_sql_stmt := 'alter table ' || p_table_name || ' drop partition ' || i.PARTITION_NAME || ';';
dbms_output.put_line( l_sql_stmt );
execute immediate l_sql_stmt;
CREATE PROCEDURE A(tab IN <table - what should I write here?>) AS
BEGIN
INSERT INTO tab VALUES(123);
END A;
How can I specify that the parameter tab is a table name?
You can't. Instead you need to pass it in as a VARCHAR2 string and then use Dynamic SQL:
CREATE PROCEDURE A(tab IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO ' || tab || 'VALUES(123)';
END A;
Read up about Dynamic SQL and be aware of the issues it can bring if used unwisely, such as poorer performance, scalability and security.