I have created some variables. I want to use the variable name as an input of another query.
Is there any method to get a local variable name as a string value in Oracle.
Example Scenario
declare
FASTFUNDS VARCHAR(100);
begin
FASTFUNDS := 'TEST001';
SELECT v_variable, v_value FROM v_Table WHERE v_variable = FASTFUNDS.toString()
Results
v_variable v_value
FASTFUNDS TEST001
This isn't a Java code, so there isn't any String type, but VARCHAR (as you defined)
Just remove .toString() and it'll be a valid statement:
SELECT v_variable, v_value FROM v_Table WHERE v_variable = FASTFUNDS;
declare
FASTFUNDS VARCHAR(100);
stmt varchar2(50);
begin
FASTFUNDS := 'TEST001';
stmt := 'SELECT v_variable, v_value FROM v_Table WHERE v_variable = '|| FASTFUNDS;
EXECUTE IMMEDIATE stmt;
end;
i dont know your objective, but id do something like this.
Related
I have a multi-line PL/SQL procedure, which I have to create.
The SQL procedure is similar to the one below,
CREATE OR REPLACE PROCEDURE HELLO AS
TYPE cur_cur is REF CURSOR;
v_cur_cur cur_cur;
age NUMBER;
day VARCHAR2(10);
date DATE;
BEGIN
<Some Execute Immediate stmts>
<Some insert stmts>
commit;
END;
Currently what I am doing is,
host= "localhost"
port= 1521
sid= "abcbcadacsw.com"
user= "groups"
password= "hello!bye1209"
dsn_tns = oracledb.makedsn(host, port, service_name=sid)
print(dsn_tns)
db_conn = oracledb.connect(user=user, password=password, dsn=dsn_tns)
curs= db_conn.cursor()
curs.execute("""
CREATE OR REPLACE PROCEDURE HELLO AS
TYPE cur_cur is REF CURSOR;
v_cur_cur cur_cur;
age NUMBER;
day VARCHAR2(10);
date DATE;
BEGIN
<Some Execute Immediate stmts>
<Some insert stmts>
commit;
END;
""")
The thing is the code runs without any issues, there are not runtime errors or anything ... but when i log into the DB to check for the created procedure, its not present. When i try to execute the procedure, it says 'identifier must be declared ... '.
I have tried converting it into a single line
curs.execute("""CREATE OR REPLACE PROCEDURE HELLO AS TYPE cur_cur is REF CURSOR; v_cur_cur cur_cur; age NUMBER; day VARCHAR2(10); date DATE; BEGIN <Some Execute Immediate stmts> <Some insert stmts> commit; END;""")
This also does not work.
Please assist, ignore the correctness of the above shown procedure, i cannot put the original here, and i dont know much of SQL, i just need to know how to successfully create it in Python.
The driver doesn't (yet) return Oracle DB's 'success with info' errors so if there is a problem with the PL/SQL code you won't find out about it unless you explicitly query the error view.
In SQL*Plus:
create or replace procedure fred as
begin
f();
end;
/
would give:
Warning: Procedure created with compilation errors.
and a subsequent show errors will give
Errors for PROCEDURE FRED:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PL/SQL: Statement ignored
3/3 PLS-00201: identifier 'F' must be declared
With cx_Oracle (and its new version python-oracledb) you don't get the initial indication there was a problem so you always should do the equivalent of the show errors command to check the error view. Try something like:
with connection.cursor() as cursor:
sql = """create or replace procedure fred as
begin
f();
end;"""
cursor.execute(sql)
sql = """select name, type, line, position, text
from user_errors
order by name, type, line, position"""
for r in cursor.execute(sql):
print(r)
which will show output like:
('FRED', 'PROCEDURE', 3, 20, 'PL/SQL: Statement ignored')
('FRED', 'PROCEDURE', 3, 20, "PLS-00201: identifier 'F' must be declared")
This is shown in the documentation Creating Stored Procedures and Packages.
This may be very basic. I am very beginner of PL/SQL, but I am stuck with this issue. If somebody know the solution, please let me know.
This code
DECLARE
v_objectID VARCHAR2(100);
v_account VARCHAR2(100);
BEGIN
v_objectID :='21,22';
DBMS_OUTPUT.PUT_LINE(v_objectID);
END;
/
Output is
21,22
Then,
This code
DECLARE
v_objectID VARCHAR2(100);
v_account VARCHAR2(100);
BEGIN
SELECT LISTAGG(x.ACCOUNT, ',') WITHIN GROUP (ORDER BY NULL) AS ACCOUNT
INTO v_account
FROM acctx x
where x.OBJECT_ID IN (21,22);
DBMS_OUTPUT.PUT_LINE(v_account);
END;
/
OUTPUT is
1001,2002
Then I try to do like this
DECLARE
v_objectID VARCHAR2(100);
v_account VARCHAR2(100);
BEGIN
v_objectID :='21,22';
SELECT LISTAGG(x.ACCOUNT, ',') WITHIN GROUP (ORDER BY NULL) AS ACCOUNT
INTO v_account
FROM acctx x
where x.OBJECT_ID IN (v_objectID);
DBMS_OUTPUT.PUT_LINE(v_account);
END;
/
I added v_objectID :='21,22';; This is causing the problem
The error is
ORA_07122: Invalid number
ORA-06512: at line 9
How should I assign variable appropriately to output 1001,2002?
Thanks
The error is obvious, In your table object_id would have been of Number Datatype. Now you are trying to compare a number with a varchar, so you faced the issue. Try below:
DECLARE
v_objectID VARCHAR2(100);
v_account VARCHAR2(100);
BEGIN
v_objectID :='21,22';
SELECT LISTAGG(x.A, ',') WITHIN GROUP (ORDER BY NULL) AS ACCOUNT
INTO v_account
FROM test x
where to_char(x.A) IN (v_objectID);
DBMS_OUTPUT.PUT_LINE(v_account);
END;
/
I know I can use CASE statement inside VALUES part of an insert statement but I am a bit confused.
I have a statement like,
You can try also a procedure:
create or replace procedure insert_XYZ (P_ED_MSISDN IN VARCHAR2,
P_ED_OTHER_PARTY IN VARCHAR2) is
begin
INSERT INTO TABLE_XYZ ( ED_MSISDN,
ED_OTHER_PARTY,
ED_DURATION)
VALUES (P_ED_MSISDN ,
P_ED_OTHER_PARTY ,
CASE
WHEN P_ED_OTHER_PARTY = '6598898745' THEN
'9999999'
ELSE
'88888'
END);
END;
Here's a query structure that you can use (using JohnnyBeGoody's suggestion of using a SELECT statement to select the values).
INSERT INTO TABLE_XYZ (ED_MSISDN, ED_OTHER_PARTY, ED_DURATION)
SELECT
'2054896545' ED_MSISDN,
'6598898745' ED_OTHER_PARTY,
CASE
WHEN ED_OTHER_PARTY = '6598898745' THEN '9999999'
ELSE '88888'
END ED_DURATION
FROM DUAL;
You cannot self-reference a column in an insert statement - that would cause an "ORA-00984: column not allowed here" error.
You could, however, use a before insert trigger to achieve the same functionality:
CREATE OR REPLACE TRIGGER table_xyz_tr
BEFORE INSERT ON table_xyz
FOR EACH ROW
NEW.ed_duration = CASE NEW.ed_other_party
WHEN '6598898745' THEN '9999999'
ELSE '88888' END;
END;
I use Delphi/NexusDB and I build SQL (about 800 char long) at run time then I pass it to the nexusdb query.sql.text property to execute it but I found error of invalid token on execution.
I pass SQL like this
Query.SQL.Text := VarStrSQL; // <<---- string variable holding the SQL
when I traced I found SQL string in the Query.SQL.Text is trimmed to 326 character !!
While the string variable that hold the SQL is complete and fine but when I assign that variable to query.sql.text only 326 character passed and of course this result in an error for invalid SQL syntax
Please advise why the SQL string trimmed like that ?
Update:
*I tried memo1.lines.text := VarStrSQL and the memo component also display the string trimmed !! is it possible a character in my string cause that !! a bug in Delphi 2010 that cause TStrings to trim my string ?*
Thanks
Sounds like a bug in DB provider itself. There is no such limitation in TQuery.
My advice shall be to use small SQL, but bound parameters to set the data.
Instead of
Query.SQL.Text := 'INSERT INTO Store_Information (store_name, Sales, Date)
VALUES ('Los Angeles ... ... ...', 900, '10-Jan-1999')';
code
Query.FieldByName('store').AsString := 'Los Angeles ... ... ...'; // here you should have no limitation
Query.FieldByName('sales').AsInteger := 900;
Query.FIeldByName('Date').AsDAteTime := Now;
Query.SQL.Text := 'INSERT INTO Store_Information (store_name, Sales, Date)
VALUES (:store,:sales,:date)';
And your request will be faster, since the statement could be preparated by the engine, then reused.
I found the problem:
It is nxtChar Fields when they are null they have the value #0 and that cause string trimming
however although I check for null like this varisnull() the char fields was able to skip this trap function !!! which makes me go around myself for hours finally I now check them like this
If <nxtChar field> = #0 then <nxtChar field> = '' (or <nxtChar field> = null)
I'd like to make a query insert:
INSERT INTO A_TABLE (BLOB_FIELD) VALUES(MY_BLOB_VAL)
but I have only string values in delphi for ex:
procedure INSERT_BLOB_QUERY
var
query:String;
my_blob_val:String;
begin
my_blob_val := 'a blob string to be inserted';
query := 'INSERT INTO A_TABLE (BLOB_FIELD) VALUES(' + my_blob_val + ')';
// to execute a query....
end;
The problem that occours is string to blob conversion.
So how to I insert a string in a interbase blob field???
Like this:
procedure INSERT_BLOB_QUERY;
begin
query.SQL.Text := 'INSERT INTO A_TABLE (BLOB_FIELD) VALUES (:VAL)';
query.ParamByName('VAL').AsString := 'a blob string to be inserted';
end;
Your code doesn't work because you're not passing the string as a parameter, you're passing it as part of the query. If you do that, you obviously need to QUOTE it: the way you're doing it Interbase will try to interpret it as SQL commands, not as a literal string to be inserted in a db column.
None the less, don't go for quoting. It's always better to use parameters, it's safer!