@@ -34,8 +34,8 @@ then the following Python code can be used to call it:
3434 cursor.callproc(' myproc' , [123 , out_val])
3535 print (out_val.getvalue()) # will print 246
3636
37- Calling :meth: `Cursor.callproc() ` actually generates an anonymous PL/SQL block
38- as shown below, which is then executed :
37+ Calling :meth: `Cursor.callproc() ` internally generates an :ref: ` anonymous PL/SQL
38+ block <anonplsql>` and executes it. This is equivalent to the application code :
3939
4040.. code-block :: python
4141
@@ -113,6 +113,8 @@ The Python code that will call this procedure looks as follows:
113113 See :ref: `bind ` for information on binding.
114114
115115
116+ .. _anonplsql :
117+
116118Anonymous PL/SQL Blocks
117119-----------------------
118120
@@ -134,34 +136,56 @@ Creating Stored Procedures and Packages
134136---------------------------------------
135137
136138To create PL/SQL stored procedures and packages, use :meth: `Cursor.execute() `
137- with a SQL CREATE command.
139+ with a CREATE command. For example:
140+
141+ .. code-block :: python
142+
143+ cursor.execute("""
144+ create or replace procedure myprocedure
145+ (p_in in number, p_out out number) as
146+ begin
147+ p_out := p_in * 2;
148+ end;""" )
149+
150+ .. _plsqlwarning :
138151
139- Creation warning messages can be found from database views like USER_ERRORS.
152+ PL/SQL Compilation Warnings
153+ +++++++++++++++++++++++++++
140154
141- For example, creating a procedure with an error could be like:
155+ When creating PL/SQL procedures and functions (or creating types) in
156+ python-oracledb, the statement might succeed without throwing an error, but
157+ there may be additional informational messages. (These messages are sometimes
158+ known in Oracle as "success with info" messages). If your application needs to
159+ show such messages, they must be explicitly looked for using
160+ :attr: `Cursor.warning `. A subsequent query from a table like ``USER_ERRORS ``
161+ will show more details. For example:
142162
143163.. code-block :: python
144164
145165 with connection.cursor() as cursor:
166+
146167 cursor.execute("""
147- create or replace procedure badproc (a in number) as
148- begin
149- WRONG WRONG WRONG
150- end;""" )
151- cursor.execute("""
152- select line, position, text
153- from user_errors
154- where name = 'BADPROC' and type = 'PROCEDURE'
155- order by name, type, line, position""" )
156- errors = cursor.fetchall()
157- if errors:
158- for info in errors:
168+ create or replace procedure badproc as
169+ begin
170+ WRONG WRONG WRONG
171+ end;""" )
172+
173+ if cursor.warning.full_code == " DPY-7000" :
174+ print (cursor.warning)
175+
176+ # Get details
177+ cursor.execute("""
178+ select line, position, text
179+ from user_errors
180+ where name = 'BADPROC' and type = 'PROCEDURE'
181+ order by name, type, line, position""" )
182+ for info in cursor:
159183 print (" Error at line {} position {} :\n {} " .format(* info))
160- else :
161- print (" Created successfully" )
162184
163185 The output would be::
164186
187+ DPY-7000: creation succeeded with compilation errors
188+ Error at line 3 position 27:
165189 PLS-00103: Encountered the symbol "WRONG" when expecting one of the following:
166190
167191 := . ( @ % ;
0 commit comments