Oracle UNISTR in SQL and PL/SQL - sql

When I execute below query in SQL and in PL/SQL (stored procedure), both gives different results. Why is that?
Query: select UNISTR('\03A6') from dual;
Sql outputs Φ where as PL/SQL outputs F
I am using sql developer to execute both.
How can I make pl/sql return Φ

Function UNISTR expects a string as input parameter. Usually you should get error
ORA-00911: invalid character
when you run UNISTR(\03A6)
Try select UNISTR('\03A6') from dual; instead.

Related

PL/SQL Developer - Creating dynamic SQL

I'm using PL/SQL Developer. I'm trying to get query results to excel via vba. Since query is so long, i decided to create table with the query results and then simply get the table results with vba. In order to create table via excel i needed to create procedure with dynamic sql. So this is what i tried so far (even this simple example doesn't work):
create or replace procedure d_x IS
str VARCHAR(81) = 'create table as select 1 as x from dual'
BEGIN
EXECUTE IMMEDIATE str;
END;
Procedure completes without error. But when i try to execute it to create table it throws an error.
Execute statement:
EXECUTE d_x;
The execute statement throws 'ORA-00900' Invalid sql statement error.
I'm kinda new to pl sql so i couldn't find a solution to this.
Any help would be appreciated, thanks.
Procedure you posted can't possibly execute without errors because it is invalid. When fixed, looks like this:
SQL> create or replace procedure d_x IS
2 str VARCHAR(81) := 'create table test as select 1 as x from dual';
3 BEGIN
4 EXECUTE IMMEDIATE str;
5 END;
6 /
Procedure created.
In tools that support execute, you can run it as:
SQL> execute d_x
PL/SQL procedure successfully completed.
SQL> select * from test;
X
----------
1
"Correct" way - which works anywhere - is to enclose it (the procedure) into begin-end block:
SQL> drop table test;
Table dropped.
SQL> begin
2 d_x;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>
I suggest you do that.
In PL/SQL Developer you can click on the procedure name and choose 'Test', which will generate a calling script as a Test window.
You can only use execute in a Command window, because it's a SQL*Plus command and not part of SQL or PL/SQL, and the Command window is a SQL*Plus emulator.
In a SQL window you could either use a complete PL/SQL block:
begin
d_x;
end
/
or use the SQL call command:
call d_x();
Note that call() requires brackets regardless of whether or not the procedure has any parameters.
The / character is useful as a separator when using PLSQL blocks in a SQL window where you have more than one statement, otherwise PL/SQ Developer won't know where one ends and the next starts.
A Test window can only have one statement and only a single PL/SQL block or SQL statement is allowed, so there is no / character at the end.

Postgresql 11 - Create Procedure to Execute COPY function

I'm currently trying to create a procedure to automatically copy data into my database when I call the procedure. However, every time I call it I get the following error:
ERROR: column "name" does not exist
LINE 1: SELECT format('COPY test(%L) FROM %s CSV HEADER', name, '/Us...
How does the column not exist? Here's everything I've written out:
CREATE PROCEDURE
test_insert() AS
$$
BEGIN
EXECUTE format('COPY test(%L) FROM %s CSV HEADER', name, '/Users/Receiving.csv');
END;
$$ LANGUAGE plpgsql;
If you use name without single quotes, it is interpreted as a column name in the (tacit) SELECT statement
SELECT format('...', name, '...')
that PL/pgSQL runs when you execute your function.
Since this SELECT statement does not have a FROM clause, you get the observed error.
The solution is to use a string literal instead, i.e. write 'name' instead of 'name'.

How to call a function in select statement which is having OUT parameter in it?

If i have a function with OUT parameters then how can we call that function in select statement.
my function is as below
CREATE OR REPLACE FUNCTION fun_1 (p_in IN VARCHAR2, p_out OUT NUMBER)
RETURN number
AS
BEGIN
SELECT SAL INTO p_out FROM emp WHERE ename=P_in;
RETURN p_out;
END;
i want to call that function through select statement as below.
select fun_1('KING', lv_var) from dual;
is it possible. ?
Is this possible?
NO
Because, with normal variable,it will give complile time error saying -
"LV_VAR": invalid identifier
Then I tried that using bind variables(:lv_var). It gave run time error(after setting the bind variable). The reason is -
PL/SQL functions referenced by SQL statements must not contain the OUT parameter.
ORA-06572: Function FUN_1 has out arguments
06572. 00000 - "Function %s has out arguments"
*Cause: A SQL statement references either a packaged, or a stand-alone,
PL/SQL function that contains an OUT parameter in its argument
list. PL/SQL functions referenced by SQL statements must not
contain the OUT parameter.
*Action: Recreate the PL/SQL function without the OUT parameter in the
argument list.
Hope this helps.

Postgres run SQL statement from string

I would like to execute a SQL statement based on a string. I have created the SQL statement through a function which returns a string. Can anybody explain how I can execute the statement that is returned? I know that you can't do it in plain SQL, so I was thinking about putting it in a function. The only issue is that the columns in the statement aren't always the same, so I don't know which data types to use for the columns. I'm using Postgres 9.1.0.
For example, suppose the SQL string returned from my function the is:
Select open, closed, discarded from abc
But, it can also be:
Select open from abc
Or
Select open, closed from abc
How can I execute any of these strings, so that the results would be returned as a table with only the columns listed in the statement?
Edit: the function is written in PL/pgSQL. And the results will be used for reporting where they don't want to see columns that have no values. So the function that I wrote returns the names of all columns that have values and then add it to the SQL statement.
Thanks for your help!
I don't think you can return the rows directly from a function, because its return type would be unknown. Even if you specified the return type as RECORD, you'd have to list the returned columns at call time. Based on Wayne Conrad's idea, you could do this:
CREATE FUNCTION my_create(cmd TEXT) RETURNS VOID AS $$
BEGIN
EXECUTE 'CREATE TEMPORARY TABLE temp_result AS ' || cmd;
END;
$$ VOLATILE LANGUAGE plpgsql;
Then use the function like this:
BEGIN;
SELECT my_create(...);
SELECT * FROM temp_result;
ROLLBACK; -- or COMMIT

How to execute stored procedures containing dynamic SQL in oracle?

I've created the following procedure
Create or replace procedure abcd
(
tab_name in USER_TABLES.table_name%type
)
is
begin
execute immediate
'select * from'||tab_name;
end abcd;
The procedure gets compiled.
I am trying to get the output using the following
select abcd('Table') from dual ;
I am new to dynamic SQL and this does not seem to work for me. I keep getting the error
[Error] Execution (44: 8): ORA-00904: "ABCD": invalid identifier
Can someone please help ?
Regards,
Kshitij
You're missing a space before your table name:
create or replace procedure abcd (tab_name in USER_TABLES.table_name%type )
is
begin
execute immediate 'select * from '||tab_name;
end abcd;
This won't work because you're trying to call it as a function, not a procedure:
select abcd('Table') from dual ;
Your second attempt should now work:
exec abcd('Table');
... but will now get a different error. In PL/SQL you have to select into something. In this case you probably want to open a cursor with the dynamic string and do something with the results. Not really sure what your end goal is though.
You should also read up about SQL injection while you learn about dynamic SQL.
you cannot perform a select on a procedure, a function will work only if single record return.
use
begin
abcd();
end;
or use
execute keyword
ALSO use a space after from in query
It will not work.
When you invoke EXECUTE IMMEDIATE the sql statement is send to SQL engine. No results are passed back to the PL/SQL.
Writing "SELECT * FROM a_table" is not that hard and much safer.