Okay, so I'm connected to an oracle database in python 2.7 and cx_Oracle 5.1 compiled against the instant client 11.2. I've got a cursor to the database and running SQL is not an issue, except this:
cursor.execute('ALTER TRIGGER :schema_trigger_name DISABLE',
schema_trigger_name='test.test_trigger')
or
cursor.prepare('ALTER TRIGGER :schema_trigger_name DISABLE')
cursor.execute(None,{'schema_trigger_name': 'test.test_trigger'})
both result in an error from oracle:
Traceback (most recent call last):
File "connect.py", line 257, in
cursor.execute('ALTER TRIGGER :schema_trigger_name DISABLE',
schema_trigger_name='test.test_trigger')
cx_Oracle.DatabaseError: ORA-01036: illegal variable name/number
While running:
cursor.execute('ALTER TRIGGER test.test_trigger DISABLE')
works perfectly. What's the issue with binding that variable?
In your example test.test_trigger is not a variable but an object. You can only bind variables (that can be replaced by a value).
The query you are trying to run would be logically equivalent to:
ALTER TRIGGER 'test.test_trigger' DISABLE
Binding in this case won't work, you will have to build the query dynamically.
You normally can't bind an object name in Oracle. For variables it'll work but not for trigger_names, table_names etc.
Related
I have a stored procedure on mysql database.When I call this procedure on phpmyadmin
CALL bakiyesifirla('Deneme');
CREATE PROCEDURE bakiyesifirla(IN cadres varchar(500))
BEGIN
set #bakiye=0;
CALL bakiyecek(cadres,#bakiye);
IF #bakiye<0 THEN
CALL bakiyeguncelle(0,cadres);
END IF;
END; –
it works fine but when I try to call it on python with
cadres='Deneme'
mycursor = mydb.cursor()
mycursor.callproc('bakiyesifirla',[cadres,])
mycursor.close()
it doesnt give any error but it wont make any difference.
use a tuples not arrays
mycursor.callproc('bakiyesifirla',(cadres,))
But i can't see how you can check, if the procedures are called or not.
Add some out paramters to check,if also the sub stored procedures are running see the link provided
I am calling a stored procedure with ibm_db like this:
SQL = "EXECUTE PROCEDURE db_x:example_procedure(8, 1234567)"
stmt = ibm_db.exec_immediate(conn, sql)
But line exec_imediate gives the error: Transaction couldn't be completed:[IBM][CLI Driver][IDS/UNIX64] Function (%s) returns too few values. SQLCODE=-685
In the IBM site we have the following:
685 Function <function-name> returns too few values.
The number of returned values from a function is less than the number
of values that the caller expects.
I dont know where exactly the error occurs and why? How can I debug this and solve it?
Ps.: I do not have access to the procedure code.
Thanks.
The ibm_db uses DRDA protocol, and it is not a best choice with Informix database. You may try the same with Informix native python driver, which is IfxPy.
Here is the Informix native python driver homepage
https://openinformix.github.io/IfxPy/
I have created a stored procedure usuarios_get , I test it in oracle console and work fine. This is the code of stored procedure
create or replace PROCEDURE USUARIOS_GET(
text_search in VARCHAR2,
usuarios_list out sys_refcursor
)
AS
--Variables
BEGIN
open usuarios_list for select * from USUARIO
END USUARIOS_GET;
The python code is this:
with connection.cursor() as cursor:
listado = cursor.var(cx_Oracle.CURSOR)
l_query = cursor.callproc('usuarios_get', ('',listado)) #in this sentence produces error
l_results = l_query[1]
The error is the following:
NotSupportedError: Variable_TypeByValue(): unhandled data type VariableWrapper
I've also tried with other stored procedure with a out parameter number type and modifying in python code listado= cursor.var(cx_Oracle.NUMBER) and I get the same error
NotSupportedError: Variable_TypeByValue(): unhandled data type VariableWrapper
I work with
python 2.7.12
Django 1.10.4
cx_Oracle 5.2.1
Oracle 12c
Can any help me with this?
Thanks
The problem is that Django's wrapper is incomplete. As such you need to make sure you have a "raw" cx_Oracle cursor instead. You can do that using the following code:
django_cursor = connection.cursor()
raw_cursor = django_cursor.connection.cursor()
out_arg = raw_cursor.var(int) # or raw_cursor.var(float)
raw_cursor.callproc("<procedure_name>", (in_arg, out_arg))
out_val = out_arg.getvalue()
Then use the "raw" cursor to create the variable and call the stored procedure.
Looking at the definition of the variable wrapper in Django it also looks like you can access the "var" property on the wrapper. You can also pass that directly to the stored procedure instead -- but I don't know if that is a better long-term option or not!
Anthony's solution works for me with Django 2.2 and Oracle 12c. Thanks! Couldn't find this solution anywhere else on the web.
dcursor = connection.cursor()
cursor = dcursor.connection.cursor()
import cx_Oracle
out_arg = cursor.var(cx_Oracle.NUMBER)
ret = cursor.callproc("<procedure_name>", (in_arg, out_arg))
I have encountered a problem after implementing the named parameters in RAW SQL Queries as per Python DB-API.
Earlier, my code was as follows (and this works fine, both on my DEV Server and my Client's test server)
cursor.execute("SELECT DISTINCT(TAG_STATUS) FROM TAG_HIST WHERE TAG_NBR = '%s' " %(TAG_NBR))
I changed it to the following
cursor.execute("SELECT DISTINCT(TAG_STATUS) FROM TAG_HIST WHERE TAG_NBR = :TAG_NBR " ,{'TAG_NBR':TAG_NBR})
This changed version (with named parameters) works fine on my Development Server
Windows XP Oracle XE
SQL*Plus: Release 11.2.0.2.0
cx_Oracle-5.1.2-11g.win32-py2.7
However, when deployed on my Client's Test Server, it does not.... execution of all queries fail.
Characteristics of my client's server are as follows
Windows Server 2003
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
cx_Oracle-5.1.2-10g.win32-py2.7
The error that I get is as follows
Traceback (most recent call last):
File "C:/Program Files/App_Logic/..\apps\views.py", line 400, in regularize_TAG
T_cursor.execute("SELECT DISTINCT(TAG_STATUS) FROM TAG_HIST WHERE TAG_NBR = :TAG_NBR " ,{'TAG_NBR':TAG_NBR})
DatabaseError: ORA-01460: unimplemented or unreasonable conversion requested
Appreciate if someone could help me through this issue.
This issue presents itself only when the cx_Oracle code is run inside the Web App (Hosted on Apache).
If i run the same code with named parameters from within the python command line then the query runs just fine.
Here is how this got solved.
I tried typecasting unicode to str and the results were positive.
This one worked for example
T_cursor.execute("SELECT DISTINCT(TAG_STATUS) FROM TAG_HIST WHERE TAG_NBR = :TAG_NBR", {'TAG_NBR': str(TAG_NBR)})
So in effect, unicode was getting mangled by getting encoded into the potentially non-unicode database character set.
To solve that, here is another option
import os
os.environ.update([('NLS_LANG', '.UTF8'),('ORA_NCHAR_LITERAL_REPLACE', 'TRUE'),])
import cx_Oracle
Above guarantees that we are really in UTF8 mode.
Second environment variable one is not an absolute necessity. And AFAIK there is no other way to set these variables (except before running app itself) due the fact that NLS_LANG is
read by OCI libs from the environment.
I'm using the following software stack on Ubuntu 10.04 Lucid LTS to
connect to a database:
python 2.6.5 (ubuntu package)
pyodbc git trunk commit eb545758079a743b2e809e2e219c8848bc6256b2
unixodbc 2.2.11 (ubuntu package)
freetds 0.82 (ubuntu package)
Windows with Microsoft SQL Server 2000 (8.0)
I get this error when trying to do native parameter binds in arguments
to a SQL SERVER function:
Traceback (most recent call last):
File "/home/nosklo/devel/testes/sqlfunc.py", line 32, in <module>
cur.execute("SELECT * FROM fn_FuncTest(?)", ('test',))
pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS][SQL
Server]SqlDumpExceptionHandler: Process 54 generated fatal exception
c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this
process.\r\n (0) (SQLPrepare)')
Here's the reproduction code:
import pyodbc
constring = 'server=myserver;uid=uid;pwd=pwd;database=db;TDS_Version=8.0;driver={FreeTDS}'
con = pyodbc.connect(constring)
print 'VERSION: ', con.getinfo(pyodbc.SQL_DBMS_VER)
cur = con.cursor()
try:
cur.execute('DROP FUNCTION fn_FuncTest')
con.commit()
print "Function dropped"
except pyodbc.Error:
pass
cur.execute('''
CREATE FUNCTION fn_FuncTest (#testparam varchar(4))
RETURNS #retTest TABLE (param varchar(4))
AS
BEGIN
INSERT #retTest
SELECT #testparam
RETURN
END''')
con.commit()
Now the function is created. If I try to call it using a value direct in the query (no native binds of values) it works fine:
cur.execute("SELECT * FROM fn_FuncTest('test')")
assert cur.fetchone()[0] == 'test'
However I get the error above when I try to do a native bind (by using a parameter placeholder and passing the value separately):
cur.execute("SELECT * FROM fn_FuncTest(?)", ('test',))
Further investigation reveals some weird stuff I'd like to relate:
Everything works fine if I change TDS Version to 4.2 (however,
version report from sql server is wrong -- using TDS version 4.2 I get
'95.08.0255' instead of the real version '08.00.0760').
Everything works fine for the other two types of functions ->
functions that return a value and functions that are just a SELECT
query (like a view) both work fine. You can even define a new function
that returns the result of a query on the other (broken) function, and
this way everything will work, even when doing native binds on the
parameters. For example: CREATE FUNCTION fn_tempFunc(#testparam
varchar(4)) RETURNS TABLE AS RETURN (SELECT * FROM
fn_FuncTest(#testparam))
Connection gets very unstable after this error, you can't recover.
The error happens when trying to bind any type of data.
How can I pursue this further? I'd like to do native binds to function parameters.
Ultimately, this probably isn't the answer you're looking for, but when I had to connect to MSSQL from Perl two or three years ago, ODBC + FreeTDS was initially involved, and I didn't get anywhere with it (though I don't recall the specific errors, I was trying to do binding, though, and it seemed the source of some of the trouble).
On the Perl project, I eventually wound up using a driver intended for Sybase (which MSSQL forked off from), so you might want to look into that.
The Python wiki has a page on Sybase and another on SQL Server that you'll probably want to peruse for alternatives:
http://wiki.python.org/moin/Sybase
http://wiki.python.org/moin/SQL%20Server