日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Using Python with Oracle

發(fā)布時間:2023/12/9 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Using Python with Oracle 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

Using Python with Oracle

This page discusses using Python with Oracle.

The page is based on the cx_oracle Python extension module. It was developed on a VM running Oracle Enterprise Linux 6U4 runnng Oracle 11.2.0.4 and Python 2.6.6.

Installation and Configuration

Assuming Python 2.6 has already been installed, the first job is to install the cx_oracle module. At the time of writing the current version was still 5.1.3 for which binaries are available for both Windows and Linux. For other platforms the sources can be downloaded and compiled.

I downloaded version 5.1.2 from http://sourceforge.net/projects/cx-oracle/files where the following RPM is available. This was the closest match to my environment

cx_Oracle-5.1.2-11g-py26-1.x86_64.rpm

Installation is standard. As the root user:

rpm -ivh cx_Oracle-5.1.2-11g-py26-1.x86_64.rpm

My VM already contained Oracle 11.2.0.4 Enterprise Edition with a database called "TARGET". I set the following environment variables in .bash_profile

export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1 export LD_LIBRARY_PATH=$ORACLE_HOME/lib export ORACLE_SID=TARGET

I rarely need to set $LD_LIBRARY_PATH, but in this case it was necessary to avoid raising the following error when the cx_Oracle is imported:

ImportError: libclntsh.so.11.1: cannot open shared object file: No such file or directory

Preparation

cx_oracle supports various connection methods. If possible I like to use a TNS alias with the Oracle client as the alias can be configured to use connection load balancing, failover etc. For this post my VM was called vm16, so the entry in $ORACLE_HOME/network/admin/tnsnames.ora was:

TARGET= (DESCRIPTION=(ADDRESS=(HOST=vm16)(PROTOCOL=TCP)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=TARGET)) )

Example Script

The following is a complete script that connects to the database, executes a simple SELECT aggregate statement and returns the result

#!/usr/bin/python # Example of fetchoneimport sys import cx_Oracledef printf (format,*args):sys.stdout.write (format % args)def printException (exception):error, = exception.argsprintf ("Error code = %s\n",error.code);printf ("Error message = %s\n",error.message);username = 'scott' password = 'tiger' databaseName = "TARGET"try:connection = cx_Oracle.connect (username,password,databaseName) except cx_Oracle.DatabaseError, exception:printf ('Failed to connect to %s\n',databaseName)printException (exception)exit (1)cursor = connection.cursor ()try:cursor.execute ('SELECT COUNT(*) FROM emp') except cx_Oracle.DatabaseError, exception:printf ('Failed to select from EMP\n')printException (exception)exit (1)count = cursor.fetchone ()[0] printf ('Count = %d\n',count)cursor.close ()connection.close ()exit (0)

The above code is discussed in the following sections

printf statement

Python does not include a printf statement. However the following library function provides similar functionality.

import sysdef printf (format,*args):sys.stdout.write (format % args)

This can be called using the familiar C syntax. For example:

printf ("Str %s Int %d\n",s,i)

printException function

I have also created a function to print details of any exceptions raised when accessing the database:

def printException (exception):error, = exception.argsprintf ("Error code = %s\n",error.code);printf ("Error message = %s\n",error.message);

Connection

The connection requires a username, password and TNS alias:

username = 'scott' password = 'tiger' databaseName = "TARGET"

Experience has demonstrated that it is good practice to execute cx_oracle methods that access the database within a try..except structure in order to catch and report any exceptions that they might throw. The printException function prints more detail

For the connection I have used the following code:

try:connection = cx_Oracle.connect (username,password,databaseName) except cx_Oracle.DatabaseError, exception:printf ('Failed to connect to %s\n',databaseName)printException (exception)exit (1)

The connection should be closed when no longer required using:

connection.close ()

It is a good idea to develop the exception handling code at the outset, then most can be reused for other cx_oracle method calls. Remember to rollback any uncommitted transactions, close cursors and close any connections when the exception is raised.

Alternatively consider using a finally clause in the try statement. The finally clause of a try statement is executed irrespective of any exceptions that may be raised.

Cursor Management

In the previous section we created a connection. We now need to create a cursor as follows:

cursor = connection.cursor ()

The cursor should be closed when no longer required using:

cursor.close ()

The Cursor class has a number of powerful methods that allow statements and PL/SQL blocks to be prepared and executed

Execute method

The cursor.execute method is the easiest way to execute simple statements including DDL.

The simple SELECT statement is an aggregate returning a single column in a single row:

try:cursor.execute ('SELECT COUNT(*) FROM emp') except cx_Oracle.DatabaseError, exception:printf ('Failed to select from EMP\n')printException (exception)exit (1)

We can check the result as follows:

count = cursor.fetchone ()[0] printf ('Count = %d\n',count)

In this case the fetchone method is more appropriate when we are expecting a single row.

Alternatively we could have used the Cursor.fetchall method which fetches all rows returned by the statement:

count = cursor.fetchall ()[0][0] printf ("Count = %d\n",count)

SELECT Statements

This section examines more complex examples of the SELECT statement. The next example returns multiple rows and columns:

sql = """\\SELECT empno,ename,sal FROM empWHERE sal > 2000ORDER BY sal DESC"""try:cursor.execute (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to select from EMP\n')printException (exception)result = cursor.fetchall () for row in result:printf (" %s;%s;%d\n",row[0],row[1],row[2])

I have separated the SQL statement from the call to cursor.execute to improve readability. The triple quotes at the start and end of the SQL statement allow it to be written across multiple lines. This is particularly important for longer SQL statements where indentation is necessary. The backslash after the opening triple quote suppresses a newline character from being appended before the first line. A newline character will be appended to the remaining lines until the closing triple quote.

The results are returned using the Cursor.fetchall�method which returns a 2-dimensional array. All results are returned by the single call to fetchall and are stored in process memory. Obviously this works when there are only 14 employees - it would not be appropriate for larger result sets. In this case I am iterating through the results, printing them one line at a time. This works but is not particularly readable.

An alternative version of the code to handle the call to cursor.fetchall() follows:

for empno, ename, sal in cursor.fetchall ():printf (" %s;%s;%d\n",empno, ename, sal)

This version is more readable and requires less process memory

Bind Variables

So far our statements have only used literal values. These are not particularly scalable in high volume workloads so most applications use bind variables to reduce the parsing overhead.

The following example shows a statement with a couple of bind variables in the predicates

sql = """\\SELECT empno,ename,sal FROM empWHERE job = :jobAND deptno = :deptORDER BY sal DESC"""try:cursor.execute (sql,job = 'SALESMAN',dept = 30) except cx_Oracle.DatabaseError, exception:printf ('Failed to select from EMP\n')printException (exception)for empno, ename, sal in cursor.fetchall ():printf (" %s;%s;%d\n",empno, ename, sal)

In the above example the call to cursor.execute includes the sql statement and values for the bind variables 'job' and 'dept'. Note from the second bind variable that the bind variable name does not have to be the same as the column value.

Prepare Statements

Whilst bind variables reduce parsing to a limited extent, they cannot eliminate it completely. To minimize parsing it is best to assign a prepared statement to a dedicated cursor. It is not then necessary to parse the statement again until the cursor is closed.

In the following code, the bind variable example from the previous section has been modified to use a separate prepare call.

sql = """\\SELECT empno,ename,sal FROM empWHERE job = :jobAND deptno = :deptORDER BY sal DESC"""try:cursor.prepare (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to prepare cursor')printException (exception)exit (1)try:cursor.execute (None,job = 'SALESMAN',dept = 30) except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor')printException (exception)exit (1)for empno, ename, sal in cursor.fetchall ():printf (" %s;%s;%d\n",empno, ename, sal)

In the above example the statement is prepared using the cursor.prepare call and is then executed by the cursor.execute call.

Note that the first parameter of the cursor.execute call is "None". This specifies that the cursor should use the existing prepared statement instead of parsing a new SQL statement.

Alternatively the cursor.execute statement can take cursor.statement as the first parameter. For example:

try:cursor.execute (cursor.statement,job = 'SALESMAN',dept = 30) except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor')printException (exception)exit (1)

Cursor.statement returns the last statement parsed by the cursor.

INSERT Statements

This section discusses INSERT statements. The first example uses bind variables to insert a new row into the DEPT table.

sql = "INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc)"try:cursor.execute (sql,deptno=50, dname='MARKETING', loc='LONDON') except cx_Oracle.DatabaseError, exception:printf ('Failed to insert row')printException (exception)exit (1)cursor.close ()connection.commit ()

In this example the values are supplied as parameters for the cursor.execute() method.

Note the commit statement at the end of the transaction

The following example uses a dictionary instead of the parameter list:

sql = "INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc)"try:cursor.execute (sql,{ 'deptno':50, 'dname': 'MARKETING', 'loc': 'LONDON'}) except cx_Oracle.DatabaseError, exception:printf ('Failed to insert row')printException (exception)exit (1)

In the above example a dictionary is passed to the cursor.execute () method. The dictionary contains name-value pairs for the column values to be inserted into the new row.

The next example demonstrates the use of a prepared INSERT statement:

sql = "INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc)"try:cursor.prepare (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to prepare cursor')printException (exception)exit (1)try:cursor.execute (None,deptno=50, dname='MARKETING', loc='LONDON') except cx_Oracle.DatabaseError, exception:printf ('Failed to insert row')printException (exception)exit (1)

As with the SELECT statement example, the cursor.execute method can use cursor.statement() instead of None, as shown below

cursor.execute (cursor.statement,deptno=50, dname='MARKETING', loc='LONDON')

UPDATE Statement

This section discusses UPDATE statements. The first example uses bind variables.

sql = "UPDATE dept SET loc = :loc WHERE deptno = :deptno"try:cursor.execute (sql,deptno = 50,loc = 'LONDON') except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor\n')printException (exception)exit (1)

In the above example, bind variable values are specified in the arguments of the call to cursor.execute() The next example uses a prepare statement

sql = "UPDATE dept SET loc = :loc WHERE deptno = :deptno"try:cursor.prepare (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to prepare cursor\n')printException (exception)exit (1)try:cursor.execute (None,deptno = 50,loc = 'LONDON') except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor\n')printException (exception)exit (1)

As with the INSERT statement example, the Cursor.execute method can use Cursor.statement instead of None, as shown below:

cursor.execute (cursor.statement,deptno = 50,loc = 'LONDON')

DELETE Statement

This section discusses DELETE statements. The following is an example of a delete that uses a bind variable:

sql = "DELETE FROM dept WHERE deptno = :deptno"try:cursor.prepare (sql) except:printf ('Failed to prepare cursor\n')exit (1)try:cursor.execute (None,deptno = 50) except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor\n')printException (exception)exit (1)

As with previous examples, Cursor.execute can use Cursor.statement instead of None, as shown below:

cursor.execute (cursor.statement,deptno = 50)

Array Operations

So far we have concentrated on statements which only make a single visit to the database for each execution. However, if we want our application to scale, at some stage we will need to consider batch operations to reduce the number of round trips from the client to the server. In this section we will examine batching techniques for SELECT statements and also INSERT, UPDATE and DELETE statements.

SELECT statements

For SELECT statements we can control the number of statements retrieved for each fetch using Cursor.arraysize.

The following statement sets the array size to 4 and then queries the EMP table:

cursor = connection.cursor ()sql = """\\SELECT empno, ename, jobFROM empORDER BY ename"""# set array size to 4 cursor.arraysize = 4try:cursor.execute (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to select from EMP\n')printException (exception)exit (1)while True:rows = cursor.fetchmany()if rows == []:break;printf ("Fetched %d rows\n", len(rows))for empno,ename,job in rows:printf (" %s;%s;%s\n",empno,ename,job)

The above example includes the creation of the cursor using connection.cursor() as the cursor must exist before the array size can be modified.

In this example we are using the Cursor.fetchmany method to fetch the rows. Every fetch with the exception of the last one will return four rows to the application.

The output of the above script is:

Fetched 4 rows7876;ADAMS;CLERK7499;ALLEN;SALESMAN7698;BLAKE;MANAGER7782;CLARK;MANAGER Fetched 4 rows7902;FORD;ANALYST7900;JAMES;CLERK7566;JONES;MANAGER7839;KING;PRESIDENT Fetched 4 rows7654;MARTIN;SALESMAN7934;MILLER;CLERK7788;SCOTT;ANALYST7369;SMITH;CLERK Fetched 2 rows7844;TURNER;SALESMAN7521;WARD;SALESMAN

There are 14 rows in the EMP table.

The advantage of specifying an array size is that the client has more control over memory usage. Only the rows retrieved by one call to fetchmany, in this case four, will be stored in memory on the client. If we had used Cursor.fetchall instead of fetchmany, then all rows would be returned and would need to be stored in client memory.

The impact on the database server depends on the nature of the query. If the query was a set operation then all result rows would need to be stored in local memory on the database server until they had been fetched by the application or the cursor was closed. If the query was a row operation then it may only be necessary to store sufficient results to satisfy the latest fetch request.

As the above query includes an ORDER by clause, it is almost certainly executing as a set operation as there is not index on the ENAME column.

Setting the array size controls the number of network messages exchanged between the client and the server.

The DB API recommends that the default array size is 1. However, cx_oracle ignores this recommendation and sets the default to 50. We can check this using:

printf ("Array Size = %d\n",cursor.arraysize);

If cursor.arraysize is not set, then the query will fetch all rows. Output will be:

Fetched 14 rows7876;ADAMS;CLERK7499;ALLEN;SALESMAN7698;BLAKE;MANAGER7782;CLARK;MANAGER7902;FORD;ANALYST7900;JAMES;CLERK7566;JONES;MANAGER7839;KING;PRESIDENT7654;MARTIN;SALESMAN7934;MILLER;CLERK7788;SCOTT;ANALYST7369;SMITH;CLERK7844;TURNER;SALESMAN7521;WARD;SALESMAN

If cursor.arraysize is set to 1, then the query will fetch one row at a time. Output will be:

Fetched 1 rows7876;ADAMS;CLERK Fetched 1 rows7499;ALLEN;SALESMAN Fetched 1 rows7698;BLAKE;MANAGER Fetched 1 rows7782;CLARK;MANAGER Fetched 1 rows7902;FORD;ANALYST Fetched 1 rows7900;JAMES;CLERK Fetched 1 rows7566;JONES;MANAGER Fetched 1 rows7839;KING;PRESIDENT Fetched 1 rows7654;MARTIN;SALESMAN Fetched 1 rows7934;MILLER;CLERK Fetched 1 rows7788;SCOTT;ANALYST Fetched 1 rows7369;SMITH;CLERK Fetched 1 rows7844;TURNER;SALESMAN Fetched 1 rows7521;WARD;SALESMAN

Array INSERT Statement

The previous example investigated use of array size to manage fetches from SELECT statements. In the following sections we will discuss use of arrays with INSERT, UPDATE and DELETE statements. In this section we will cover array INSERT statements.

The following is an example of an array INSERT of three rows into the DEPT table:

sql = "INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc)"try:cursor.prepare (sql) except cx_Oracle.DatabaseError, exception:printf ('Failed to prepare cursor')printException (exception)exit (1)array=[] array.append ((50,'MARKETING','LONDON')) array.append ((60,'HR','PARIS')) array.append ((70,'DEVELOPMENT','MADRID'))try:cursor.executemany (None,array) except cx_Oracle.DatabaseError, exception:printf ('Failed to insert rows')printException (exception)exit (1)

Note that we are using the Cursor.executemany () method instead of Cursor.execute ()

If we enable trace for the above statement we can verify that an array insert was performed on the database server:

PARSING IN CURSOR #140238572911728 len=68 dep=0 uid=83 oct=2 lid=83 tim=1419870619434242 hv=3863288051 ad='91cf3288' sqlid='9fxqrt3m4a67m' INSERT INTO dept (deptno, dname, loc) VALUES (:deptno, :dname, :loc) END OF STMT PARSE #140238572911728:c=0,e=267,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1419870619434241 EXEC #140238572911728:c=1000,e=516,p=0,cr=1,cu=7,mis=1,r=3,dep=0,og=1,plh=0,tim=1419870619434770 STAT #140238572911728 id=1 cnt=0 pid=0 pos=1 obj=0 op='LOAD TABLE CONVENTIONAL (cr=1 pr=0 pw=0 time=258 us)' WAIT #140238572911728: nam='SQL*Net message to client' ela= 17 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419870619435236 WAIT #140238572911728: nam='SQL*Net message from client' ela= 174 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419870619435451 CLOSE #140238572911728:c=0,e=5,dep=0,type=0,tim=1419870619435486 XCTEND rlbk=0, rd_only=0, tim=1419870619435523

In the above, the EXEC line includes r=3 which indicates that three rows were inserted.

We could also call executemany using cursor.statement as the first parameter:

cursor.executemany (cursor.statement,array)

Array UPDATE Statement

We can also use arrays with UPDATE statements. In the following example, we are using a dictionary to pass the bind variable values to the cursor.executemany method:

sql = "UPDATE dept SET loc = :loc WHERE deptno = :dept"try:cursor.prepare (sql) except:printf ('Failed to prepare cursor')exit (1)array=[] array.append ({'dept':50,'loc':'SHANGHAI'}) array.append ({'dept':60,'loc':'MOSCOW'}) array.append ({'dept':70,'loc':'MUMBAI'})try:cursor.executemany(None,array) except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor')printException (exception)exit (1)

Again the trace shows that all three rows were updated using a single execution of the UPDATE statement:

PARSING IN CURSOR #140267303715936 len=47 dep=0 uid=83 oct=6 lid=83 tim=1419873983403707 hv=2665682896 ad='8bda6038' sqlid='gja8j7agf65yh' UPDATE dept SET loc = :loc WHERE deptno = :dept END OF STMT PARSE #140267303715936:c=0,e=450,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=267198286,tim=1419873983403669 EXEC #140267303715936:c=0,e=317,p=0,cr=3,cu=5,mis=0,r=3,dep=0,og=1,plh=267198286,tim=1419873983404140 STAT #140267303715936 id=1 cnt=0 pid=0 pos=1 obj=0 op='UPDATE DEPT (cr=3 pr=0 pw=0 time=212 us)' STAT #140267303715936 id=2 cnt=3 pid=1 pos=1 obj=87107 op='INDEX UNIQUE SCAN PK_DEPT (cr=3 pr=0 pw=0 time=70 us cost=1 size=21 card=1)' WAIT #140267303715936: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419873983404265 WAIT #140267303715936: nam='SQL*Net message from client' ela= 133 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419873983404418 CLOSE #140267303715936:c=0,e=4,dep=0,type=0,tim=1419873983404447 XCTEND rlbk=0, rd_only=0, tim=1419873983404492

As with the previous example, the EXEC line includes r=3 which indicates that three rows were updated.

Array DELETE Statement

Arrays can also be used with DELETE statements. As with UPDATE statements this example uses a dictionary to specify bind variables

sql = "DELETE FROM dept WHERE deptno = :dept"try:cursor.prepare (sql) except:printf ('Failed to prepare cursor')exit (1)array=[] array.append ({'dept':50}) array.append ({'dept':60}) array.append ({'dept':70})try:cursor.executemany(None,array) except cx_Oracle.DatabaseError, exception:printf ('Failed to execute cursor')printException (exception)exit (1)

In the above example, the array is used to specify the deptno for each of the three rows to be deleted

As in the previous DML examples, the EXEC line in the trace file includes r=3 indicating that three rows were deleted

PARSING IN CURSOR #140404237827184 len=37 dep=0 uid=83 oct=7 lid=83 tim=1419881960556726 hv=1258566750 ad='8be19350' sqlid='3mpppmd5h8d2y' DELETE FROM dept WHERE deptno = :dept END OF STMT PARSE #140404237827184:c=0,e=234,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=1419881960556725 EXEC #140404237827184:c=11999,e=12902,p=0,cr=49,cu=18,mis=1,r=3,dep=0,og=1,plh=2529563076,tim=1419881960569679 STAT #140404237827184 id=1 cnt=0 pid=0 pos=1 obj=0 op='DELETE DEPT (cr=49 pr=0 pw=0 time=12065 us)' STAT #140404237827184 id=2 cnt=3 pid=1 pos=1 obj=87107 op='INDEX UNIQUE SCAN PK_DEPT (cr=3 pr=0 pw=0 time=58 us cost=1 size=13 card=1)' WAIT #140404237827184: nam='SQL*Net message to client' ela= 15 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419881960570446 WAIT #140404237827184: nam='SQL*Net message from client' ela= 200 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=1419881960570681 CLOSE #140404237827184:c=0,e=22,dep=0,type=0,tim=1419881960570758 XCTEND rlbk=0, rd_only=0, tim=1419881960570869

Calling PL/SQL Subroutines

PL/SQL procedures and functions can be called using the Cursor.callproc and Cursor.callfunc methods

PL/SQL Procedures

Assume we have created the following PL/SQL procedure

CREATE OR REPLACE PROCEDURE proc1 (p_deptno NUMBER,p_dname VARCHAR2,p_loc VARCHAR2 ) IS BEGININSERT INTO dept (deptno, dname, loc) VALUES (p_deptno, p_dname, p_loc); END; /

We can call the procedure using the following code:

deptno = 50 dname = 'MARKETING' loc = 'LONDON'try:cursor.callproc('PROC1',(deptno,dname,loc)) except cx_Oracle.DatabaseError, exception:printf ('Failed to call procedure')printException (exception)exit (1)

The cursor.callproc method specifies the name of the procedure and also a list of bind variable parameters.

Note that in this example the bind variables are input parameters.

PL/SQL Functions

Assume we have created the following PL/SQL function which returns the number of employees with a specific job in a specific department:

CREATE OR REPLACE FUNCTION func1 (p_job VARCHAR2,p_deptno NUMBER ) RETURN NUMBER ISl_result NUMBER; BEGINSELECT COUNT(*) INTO l_result FROM emp WHERE job = p_job AND deptno = p_deptno;RETURN l_result; END; /

To call the function we use the cursor.callfunc method

job = 'SALESMAN' deptno = 30result = cursor.var (cx_Oracle.NUMBER)try:cursor.callfunc('FUNC1',result,(job,deptno)) except cx_Oracle.DatabaseError, exception:printf ('Failed to call function')printException (exception)exit (1)printf ("Result = %d\n",result.getvalue ())

The above code creates a result variable using the cursor.var method. It then calls the PL/SQL function FUNC1 passing the job and deptno as bind variables. The result is returned in a Variable object and is then converted to a number using the Variable.getvalue method.

Procedures with OUT parameters

If a PL/SQL subroutine only returns one value it will typically be written as a function. However if the PL/SQL subroutine needs to return more than one value it will usually return them as OUT parameters.

The following procedure returns the employee name and job for a specific employee number.

CREATE OR REPLACE PROCEDURE proc2 (p_empno NUMBER,p_ename OUT VARCHAR2,p_job OUT VARCHAR2 ) IS BEGINSELECT ename,job INTO p_ename,p_job FROM emp WHERE empno = p_empno; END; /

The procedure has one input parameter (p_empno) and two output parameters (p_ename and p_job)

The following code calls PROC2:

empno = 7839 ename = cursor.var (cx_Oracle.STRING) job = cursor.var (cx_Oracle.STRING)try:cursor.callproc('PROC2',(empno,ename,job)) except cx_Oracle.DatabaseError, exception:printf ('Failed to call procedure\n')printException (exception)exit (1)printf ("Ename = %s\n",ename.getvalue ()) printf ("Job = %s\n",job.getvalue ())

The above code creates an input parameter for empno and two output parameters to received the results for ename and job. The procedure is called using the Cursor.callproc method specifying the name of the procedure (PROC2) and a list of parameters.

The OUT parameters are returned as Variable objects. The Variable.getvalue method must be called to extract the value from the object.

Procedures with IN-OUT parameters

It is debatable whether IN-OUT parameters for simple data types are ever justified and it is therefore difficult to devise a credible example for the scott/tiger database. However, it is often necessary to call subroutines developed by others in which case they may follow different standards.

The following PL/SQL procedure adds the specified values for SAL and COMM to the existing values in the table for the specified EMPNO. The PL/SQL procedure returns the new values in the same parameters.

CREATE OR REPLACE PROCEDURE proc3 (p_empno NUMBER,p_sal IN OUT NUMBER,p_comm IN OUT NUMBER ) IS BEGINUPDATE emp SET sal = sal + p_sal, comm = comm + p_commWHERE empno = p_empnoRETURNING sal, comm INTO p_sal,p_comm; END; /

The following code calls the PROC3 procedure for EMPNO 7499

empno = 7499sal = cursor.var (cx_Oracle.NUMBER) sal.setvalue (0,400)comm = cursor.var (cx_Oracle.NUMBER) comm.setvalue (0,200)try:cursor.callproc('PROC3',(empno,sal,comm)) except cx_Oracle.DatabaseError, exception:printf ('Failed to call procedure')printException (exception)exit (1)printf ("sal = %d\n",sal.getvalue ()) printf ("comm = %d\n",comm.getvalue ())

The above code sets a value for EMPNO which is an input parameter. It then creates Variable objects for the two output parameters and sets initial values for these parameters using the Variable.setvalue method. The first parameter in the Cursor.var call will normally be 0.

The procedure then calls PROC3 using the Cursor.callproc method. When the procedure returns, the values of the SAL and COMM parameters are extracted from the Variable objects using the Variable.getvalue method

轉(zhuǎn)載于:https://my.oschina.net/zhiyonghe/blog/1585674

總結(jié)

以上是生活随笔為你收集整理的Using Python with Oracle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

91字幕 | 国产一级视屏 | 亚洲精品视频在线观看免费视频 | 91精品国产一区二区在线观看 | 久久精品国产久精国产 | 黄色视屏免费在线观看 | jizz18欧美18| 天天干天天操人体 | 亚洲精品日韩在线观看 | 999电影免费在线观看2020 | 久久视频在线看 | 亚洲精品国偷拍自产在线观看蜜桃 | 麻豆果冻剧传媒在线播放 | 免费在线观看国产精品 | 五月天激情视频 | 国产精品久久久区三区天天噜 | 日韩精品一区二区在线观看 | 九九热在线视频 | 欧美一级特黄高清视频 | 久久99国产精品久久99 | 天天精品视频 | av天天干 | 欧美一区在线看 | 中文字幕中文字幕在线一区 | 在线国产99 | 99热这里只有精品久久 | 精品国产乱码久久久久久1区二区 | 精品成人网 | 国产粉嫩在线观看 | 91成人精品一区在线播放 | 国产精品h在线观看 | 国产裸体视频bbbbb | 中文字幕av一区二区三区四区 | 亚洲欧洲av | 日韩电影中文字幕在线观看 | 免费激情在线电影 | 久久色网站| 欧产日产国产69 | 国产精品 日韩 | 欧美在线视频不卡 | 在线99 | 亚洲精品色 | 波多野结衣一区二区三区中文字幕 | 国产午夜精品久久 | 亚洲永久精品在线 | 91视频啪 | 高清视频一区二区三区 | 成人影视片 | 免费午夜在线视频 | 久久深夜福利免费观看 | 9在线观看免费高清完整版 玖玖爱免费视频 | 人人人爽| 伊人久操 | 日本精品一区二区三区在线观看 | 国产精品久久久精品 | 中文字幕在线视频免费播放 | 国产黄a三级三级 | 奇米影音四色 | 成人h动漫精品一区二 | 在线精品视频免费播放 | 9在线观看免费高清完整版在线观看明 | 久久久69 | 中文字幕欧美三区 | 国产精品久久久久四虎 | 黄色的网站在线 | 久久精品国产免费看久久精品 | 亚洲精品乱码久久久久久写真 | 99久久婷婷国产综合亚洲 | 久久久精品 一区二区三区 国产99视频在线观看 | 国产精品女人网站 | 国产亚洲精品久久久久久 | 极品嫩模被强到高潮呻吟91 | 久久理论视频 | 国产香蕉视频在线播放 | 国产精品久久久久久久久久三级 | 亚洲综合婷婷 | 日韩精品一区二区三区在线视频 | 久久午夜色播影院免费高清 | 在线观看你懂的网站 | 久久99精品久久只有精品 | 五月婷在线播放 | 色丁香婷婷 | 97av在线视频 | 97人人澡人人爽人人模亚洲 | 蜜臀久久99精品久久久无需会员 | 五月婷婷黄色网 | 黄av免费| 国产精品不卡在线观看 | 99久久这里只有精品 | 日三级在线| 日韩精品一卡 | 久久综合欧美 | 91免费黄视频 | 久久久久综合视频 | 一区二区三区在线免费 | 国产一级精品在线观看 | 日韩免费小视频 | 亚洲成av人片在线观看 | 国内99视频 | 97免费 | 菠萝菠萝在线精品视频 | 亚洲欧美日韩一级 | av电影在线观看 | 欧美一区二区三区免费观看 | 欧美特一级| 亚洲精品一区二区精华 | 亚洲japanese制服美女 | 国产精品大片免费观看 | 欧美日韩在线视频一区二区 | 国产精品丝袜久久久久久久不卡 | 91激情视频在线 | 国产精品久久艹 | 成年人视频在线免费观看 | 欧美另类巨大 | 久久亚洲在线 | 国产九色视频在线观看 | 国产精品一区二区三区免费看 | 热久久视久久精品18亚洲精品 | 免费精品国产 | 888av| 97精品国产97久久久久久粉红 | 91视频91自拍 | 国产免费资源 | 91久久精品一区二区三区 | 国产精品视频99 | 日韩在线国产精品 | 亚洲综合日韩在线 | 国产成人三级在线观看 | 久久99热国产 | 精品国产一区二区三区久久久久久 | 亚洲精品88欧美一区二区 | 久久久久一区 | 91成人精品视频 | 欧美精品xx | 欧美乱淫视频 | 天天综合网久久 | 日韩久久精品一区二区 | 国产色啪 | 在线视频福利 | 日韩午夜小视频 | 国产999视频| 欧美一级在线看 | 在线午夜av| av永久网址 | 97成人免费| 亚洲成a人片在线观看网站口工 | 丁香婷婷色月天 | 欧美一级片免费播放 | 日韩欧美在线观看 | 国产淫片 | 久久综合久久综合这里只有精品 | 天堂激情网 | 黄视频色网站 | 久久久久免费网站 | 黄色免费在线看 | av三级在线免费观看 | 中文字幕电影网 | 婷婷网址| 爱爱av网 | 国产精品久久久久av福利动漫 | 中文字幕黄色 | 一 级 黄 色 片免费看的 | 天天干夜夜夜操天 | 在线观看日韩av | 婷婷伊人综合亚洲综合网 | 超碰激情在线 | 久久精品老司机 | 18久久久 | 国产欧美高清 | 五月天色综合 | 久久精品视频99 | 免费成人看片 | 亚洲国产日韩精品 | 98涩涩国产露脸精品国产网 | 中文字幕免费高清 | 伊人五月天 | 在线视频观看91 | 国产精品www | 超碰人人在 | 成人亚洲精品久久久久 | 日本中文乱码卡一卡二新区 | 国产精品一区久久久久 | 色资源网免费观看视频 | 久草国产精品 | 成人午夜电影网 | 91在线精品观看 | 国产香蕉视频在线观看 | 国产精品美女久久久久久网站 | 日韩精品免费一区二区三区 | 日韩mv欧美mv国产精品 | 免费观看国产精品视频 | av网址在线播放 | 国产成人精品久久久久 | av资源免费在线观看 | 国产麻豆精品在线观看 | 人人玩人人添人人澡97 | 中文在线免费观看 | 国产自在线 | 蜜臀av性久久久久av蜜臀妖精 | 狠狠干成人 | 日韩,中文字幕 | 国产香蕉久久 | 久久久久成人精品免费播放动漫 | 奇米先锋| 亚洲人在线| 999国内精品永久免费视频 | 91成人在线看| 91免费观看网站 | 96亚洲精品久久久蜜桃 | 伊人影院av | 91av视频在线观看免费 | 九九免费视频 | 3d黄动漫免费看 | 天天干天天做天天操 | 国产精品久久久久婷婷二区次 | 手机成人在线 | 在线观看视频国产一区 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 欧美日韩中文国产一区发布 | 日本午夜免费福利视频 | 免费成人在线电影 | 99r在线观看| 午夜久久福利 | 国内精品久久久久 | 国产精品久久久久免费 | 欧洲精品二区 | 欧美日韩一区三区 | 91中文字幕一区 | 天操夜夜操 | 国产精品久久久久久久久费观看 | 日韩在线电影观看 | 日韩精品一区二区不卡 | 91精品国产91久久久久久三级 | 精品在线观看一区二区 | 欧美日韩99 | 久久国产美女 | 久久激情视频 久久 | 国产综合精品一区二区三区 | 激情婷婷亚洲 | 在线观看亚洲国产精品 | 成人免费在线观看av | 看全黄大色黄大片 | 人人精品久久 | 国产高清av免费在线观看 | 一本一本久久aa综合精品 | av一级在线 | 久久另类小说 | 2018好看的中文在线观看 | 五月婷婷激情综合 | 色网站在线免费 | 欧美a免费 | 深爱婷婷网 | 成人在线观看资源 | 亚州免费视频 | 久久久.com| 国产一区二区免费看 | 国产精品热 | 四虎小视频 | 色婷婷在线观看视频 | 国产精品毛片一区二区在线看 | av在线官网 | 日韩黄视频 | 国产午夜精品在线 | 一本一本久久a久久 | 亚洲日本一区二区在线 | 在线国产小视频 | 欧美成人在线网站 | 91最新网址 | 狠狠躁日日躁狂躁夜夜躁 | 欧美在线视频免费 | 欧美午夜久久 | 伊人天天色 | 国产成人一区二区三区影院在线 | 在线观看国产91 | 国产视频在线免费 | 国产一区免费在线观看 | 在线看日韩av | 成人av资源 | 亚洲国产999 | 在线视频欧美日韩 | 免费男女羞羞的视频网站中文字幕 | 欧美 激情 国产 91 在线 | 欧美精品一区二区免费 | 天堂在线一区二区 | 色视频在线观看 | 国产精品二区三区 | 成人久久精品视频 | 成人啪啪18免费游戏链接 | 一级一片免费观看 | 成人网看片 | 九九热免费在线观看 | 精品99久久 | 久久久www成人免费精品 | 日韩在线视频线视频免费网站 | 国产日韩欧美网站 | 亚洲在线视频观看 | 91视频啊啊啊| 91麻豆网站 | 中文字幕大全 | 久久高清精品 | 日韩免费成人av | 国产精品午夜免费福利视频 | 久久久久久97三级 | 亚洲精品福利视频 | 97超碰人人澡人人 | 狠狠色狠狠色综合日日92 | 97超碰免费在线观看 | 香蕉视频在线免费看 | 亚洲免费在线播放视频 | 中文字幕电影在线 | www.啪啪.com| 69精品久久久 | 国产精品久久久久久久久婷婷 | 国产成人精品一区二区三区 | 麻豆91精品91久久久 | 国产成人精品一区二区在线观看 | 国产精品一区二区三区四区在线观看 | 久久免费在线观看视频 | 亚洲精品视频网站在线观看 | 国产麻豆电影在线观看 | 中文在线8资源库 | 国产午夜一级毛片 | 91看片一区二区三区 | 久久免费国产视频 | 伊人久久精品久久亚洲一区 | 亚洲经典视频 | 亚洲一区二区三区四区精品 | 欧美色道| 久久精品伊人 | 爱色av.com | 一级特黄av | 看国产黄色片 | 成人性生交大片免费看中文网站 | 五月开心激情网 | 精品在线免费观看 | 午夜视频一区二区 | 久久免费99精品久久久久久 | 在线观看国产高清视频 | 国产精品视频免费看 | 天天激情综合网 | 久久综合中文字幕 | 91精品国自产在线观看欧美 | 欧美成人久久 | 国产一区网址 | 91av在线免费看 | av动态图片 | 在线观看视频黄色 | 九九热精 | 亚洲视频电影在线 | 四虎影视欧美 | 日韩av一卡二卡三卡 | 色久天| 在线观看av小说 | 中文av一区二区 | 国产精品久久久久久婷婷天堂 | 亚洲一级黄色大片 | 国产亚洲精品久久久久久电影 | 狠狠色丁香 | 99精品久久只有精品 | 开心激情久久 | 婷婷av在线| 91av手机在线 | 在线观看mv的中文字幕网站 | 美女视频黄色免费 | 欧美性粗大hdvideo | 久久伦理网 | 午夜视频在线观看一区二区三区 | 亚洲精品久久在线 | 黄色一级在线视频 | 久久久久久久久久久久久久免费看 | 福利av影院 | 一区av在线播放 | 婷婷激情av| 久久久国产影视 | 国产精品视频久久 | 日韩在线视频免费观看 | 尤物97国产精品久久精品国产 | 国产一级视频在线免费观看 | 一级成人免费 | 激情五月伊人 | 日韩高清观看 | 中文字幕视频一区二区 | 97在线观看免费观看高清 | 国产精品亚洲片夜色在线 | 亚洲视频电影在线 | 性日韩欧美在线视频 | 丁香花在线视频观看免费 | 免费精品视频在线观看 | 黄色在线免费观看网址 | 69视频在线播放 | 久久国产亚洲视频 | 日本三级吹潮在线 | 欧美日韩中文字幕在线视频 | 国产精品大片免费观看 | 婷婷丁香激情 | 亚洲资源片 | 亚洲欧美国产精品久久久久 | 啪嗒啪嗒免费观看完整版 | 久久社区视频 | 国产成人亚洲精品自产在线 | 97久久久免费福利网址 | 久久久电影网站 | 成人av电影在线 | 9999精品 | 97国产小视频 | 国产最顶级的黄色片在线免费观看 | 国内精品视频在线 | 丝袜网站在线观看 | 天天激情 | 视频国产精品 | 日韩免费电影网站 | 久要激情网 | 天天要夜夜操 | 97免费在线观看视频 | www.香蕉视频| 中文字幕免费观看全部电影 | 国精产品永久999 | 亚洲精品婷婷 | 亚洲黄色免费电影 | 国产久视频 | 国产欧美在线一区二区三区 | 中文字幕免费播放 | 久久精品久久综合 | 久久亚洲影院 | 免费观看福利视频 | 99精品视频在线观看 | 国产精品一区二区久久久久 | 国产精品综合av一区二区国产馆 | 青青久草在线 | 中文字幕精品一区二区三区电影 | 婷婷5月色 | 日韩精品极品视频 | 国产乱对白刺激视频在线观看女王 | 九九视频免费在线观看 | 久久久www成人免费精品 | 国产伦精品一区二区三区… | 免费av大片 | 午夜一级免费电影 | 婷婷 中文字幕 | 国产在线日本 | 在线 成人| 久久男人中文字幕资源站 | 成年人免费在线观看 | 久久久久久片 | 日韩中文字幕在线 | 在线观看mv的中文字幕网站 | 狠狠五月天 | 中文字幕日韩有码 | 日本视频高清 | 欧美一区二区精美视频 | 97超碰免费| 日日爱夜夜爱 | 亚洲美女免费精品视频在线观看 | 中文字幕在线观看完整版 | 天天干天天拍 | 麻豆久久一区 | 亚洲午夜久久久久 | 久久精品国产亚洲精品 | 日韩深夜在线观看 | www久久com | 国产精品久久婷婷六月丁香 | 国内精品视频免费 | 麻花天美星空视频 | av高清一区二区三区 | 亚洲欧美国产精品18p | 又黄又爽又色无遮挡免费 | av免费福利 | 五月天亚洲婷婷 | 成人国产精品av | 91精品一区在线观看 | 一区二区三区在线观看免费视频 | 99久久精品免费 | 国产一级视频在线 | 天天摸夜夜操 | 精品一区二区免费在线观看 | 国产小视频国产精品 | 女人高潮一级片 | 成年人免费在线观看网站 | 精品无人国产偷自产在线 | 亚洲精品毛片一级91精品 | 国内精品视频在线播放 | 日韩久久久 | 一个色综合网站 | 成人精品福利 | 色欧美综合| 国产二区视频在线观看 | 日日夜夜精品免费观看 | 亚洲涩涩色 | 国产精品久久久久久爽爽爽 | 一区二区三区 中文字幕 | 亚洲伊人婷婷 | 人人爽人人爽人人爽 | 国产拍在线| 久久电影国产免费久久电影 | 国产精品久久三 | 丁香5月婷婷 | 狠狠88综合久久久久综合网 | 欧美最爽乱淫视频播放 | 91最新网址 | 成人欧美日韩国产 | 视频在线播放国产 | 狠狠操狠狠干天天操 | 一级淫片在线观看 | 成人久久久久久久久久 | 黄色三级视频片 | 久久国产精品99久久久久久进口 | avav片 | 亚洲成人av在线电影 | 四虎永久国产精品 | 国产欧美三级 | 在线电影中文字幕 | 亚洲国产欧美在线人成大黄瓜 | 色综合婷婷 | 国产高清在线视频 | 久草在线免费在线观看 | 国产99久 | www在线观看国产 | 国产一级在线播放 | 日本午夜在线亚洲.国产 | 99免费在线视频观看 | 亚洲国产成人精品久久 | 精品视频久久 | 国产免费叼嘿网站免费 | 人人添人人澡 | 亚洲欧美成人 | 天天狠狠 | 999男人的天堂 | 亚洲另类xxxx | 最新日韩在线 | av在线电影播放 | a亚洲视频 | 国产精品网站一区二区三区 | 天天操夜操视频 | 久久只有精品 | 亚洲视频中文 | 亚洲一区免费在线 | 成年人在线视频观看 | 中文字幕在线专区 | 午夜精品婷婷 | 精品高清美女精品国产区 | 国产美女视频免费观看的网站 | 在线免费观看麻豆 | 国产麻豆视频免费观看 | 精品国产一区二区三区久久久久久 | 国产香蕉在线 | 久久久精品小视频 | 日日综合网 | 亚洲综合欧美日韩狠狠色 | 97色视频在线 | 永久免费看av | 天天舔天天射天天操 | 色妞色视频一区二区三区四区 | 91手机电视| 狠狠色丁香婷婷综合久小说久 | 国产视频不卡 | 成人app在线免费观看 | 日韩在线视| 91麻豆精品91久久久久同性 | 成人免费精品 | 色综合久久久久久中文网 | 免费成视频 | 黄色成人影院 | 国产免费xvideos视频入口 | 最近中文字幕久久 | 麻豆免费在线视频 | 国产一二区视频 | 狠狠天天 | 亚洲狠狠 | www中文在线 | 国产精品9区 | 4hu视频 | 久久久夜色 | 天天艹天天干天天 | www.夜夜草 | 美女黄频免费 | 久久免费观看视频 | 日韩sese | 国产精国产精品 | 在线观看视频国产 | 亚洲精品视频在线观看网站 | 国产成人精品一区二区三区网站观看 | 日韩大片在线播放 | 欧美电影在线观看 | 99色免费 | 高清av免费一区中文字幕 | 国产精品久久久久久久久免费看 | 欧美激情视频久久 | 久久久久久久国产精品影院 | 亚洲免费一级电影 | 91视频在线观看免费 | 国产精品系列在线观看 | 97国产精品亚洲精品 | 99视频一区二区 | 9在线观看免费高清完整 | 91精品人成在线观看 | 97精品国产91久久久久久 | 亚洲成熟女人毛片在线 | 国产精品一区二区果冻传媒 | 欧美日韩中 | 一级大片在线观看 | 亚洲一级影院 | 国产成人av电影在线 | 国产精品毛片一区二区在线看 | 99久久精品免费看国产免费软件 | 亚洲涩涩色 | 99久久综合精品五月天 | 黄色99视频| 天天射天天射天天射 | 日韩电影中文字幕在线观看 | 久久久久久久久毛片 | 亚洲永久精品国产 | 久久久久久久久久久国产精品 | 国产网红在线观看 | 五月情婷婷 | 91亚洲精品久久久蜜桃借种 | 免费v片 | 97碰视频| 免费av在线网 | 日韩手机视频 | 日本免费久久高清视频 | 久热av在线| 久久久高清视频 | 色婷婷综合五月 | 亚洲好视频 | 久久国产精品久久w女人spa | 国产精品网站一区二区三区 | 久久成年人视频 | 久久视频免费在线 | 日韩影视精品 | 国产精品美女久久久久久 | 91桃色视频 | 91污在线观看 | 国产一区二区高清不卡 | 久久久国产一区 | 99人成在线观看视频 | 9999在线观看 | 免费a网 | 国产综合91 | 欧美乱码精品一区 | 亚州日韩中文字幕 | av免费观看网址 | 日韩av成人在线观看 | 国产一级精品视频 | 亚洲最新av网站 | 97超碰成人在线 | 99综合影院在线 | 丁香免费视频 | 国内精品视频久久 | 91资源在线播放 | 日本精品一 | 精品久久一级片 | 最近日本字幕mv免费观看在线 | 人人爽人人爽人人片av | 色网站国产精品 | 日韩a级黄色片 | 亚洲一区 av | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 少妇按摩av | 成人综合婷婷国产精品久久免费 | 一区 二区电影免费在线观看 | 国产黄色大片免费看 | 国产在线美女 | 91最新在线观看 | 精品99在线视频 | 91精品在线观看入口 | 国产99久久久欧美黑人 | 久久国产精品网站 | 色网站视频 | 美女精品在线观看 | 九九热精品视频在线观看 | 激情网婷婷 | 色视频在线 | 深夜免费福利视频 | 色婷婷综合久久久 | 久久免费精品一区二区三区 | av免费在线观看网站 | 黄色91在线观看 | 手机av在线不卡 | 久久综合色天天久久综合图片 | 久久大片 | 日韩欧美综合在线视频 | 欧美日韩视频免费 | 国产永久免费 | 久久99精品国产麻豆婷婷 | av在线看网站 | 久久免费成人网 | 亚洲最大av网 | 色五月成人 | 91精品久久久久久综合五月天 | 日本激情视频中文字幕 | 日韩精品视频免费在线观看 | 日韩av电影一区 | 蜜臀aⅴ精品一区二区三区 久久视屏网 | 国产无遮挡又黄又爽馒头漫画 | 一区二区免费不卡在线 | 夜夜操狠狠干 | 婷婷亚洲五月 | 日韩av免费一区 | 日韩在线高清免费视频 | 干狠狠| 91最新网址 | 久久久国产精品一区二区三区 | 射射射综合网 | 亚洲精品色视频 | 亚洲三级黄色 | 91丨九色丨蝌蚪丨对白 | 婷婷丁香六月 | 久久久午夜精品福利内容 | 中文字幕精品久久 | 午夜精品成人一区二区三区 | 久久在线影院 | 91精品入口 | 国产美女网站在线观看 | 日韩女同一区二区三区在线观看 | 国产成人久 | 97在线观视频免费观看 | www日韩在线 | 九热在线 | 天堂av高清 | 国产免费成人av | 欧美日韩高清一区二区三区 | 77国产精品 | 国内精品久久久久久久影视简单 | 午夜黄色影院 | av在线播放一区二区三区 | 狠狠操夜夜 | 国产女人40精品一区毛片视频 | 丁香花在线观看免费完整版视频 | 奇米影视8888在线观看大全免费 | 99久久这里有精品 | 最近高清中文在线字幕在线观看 | 中文字幕在线视频免费播放 | 日本丰满少妇免费一区 | 日日夜夜天天射 | 婷婷综合激情 | 青草视频在线播放 | 亚洲一区美女视频在线观看免费 | 国产亚洲精品久久久久久久久久久久 | 激情五月婷婷丁香 | 国产精品久久久亚洲 | 天天干天天操天天拍 | 亚洲精品国产精品乱码在线观看 | 黄色大全在线观看 | 国产手机在线观看 | 色狠狠综合 | 狠狠狠干 | 国产在线观看av | 亚洲精品一区二区在线观看 | 黄污在线看 | 欧美一二三在线 | 九九免费精品视频在线观看 | 日本不卡久久 | 欧美激情精品久久久久久变态 | www.eeuss影院av撸 | 日韩色在线观看 | 久久久久色| 在线观看91精品国产网站 | 亚洲黄色片在线 | 99免费在线播放99久久免费 | 欧美精品久久久久久久久久丰满 | 成人a毛片 | 日韩av在线影视 | 天天天在线综合网 | 亚洲3级 | 午夜影院在线观看18 | 成人在线免费观看网站 | 欧美日韩三级在线观看 | 激情综合电影网 | 超碰97免费观看 | 在线婷婷 | 久久理论片 | 亚洲六月丁香色婷婷综合久久 | 91av电影网 | 国产在线观看你懂得 | 99热最新地址 | 在线观看的av网站 | 日韩有码中文字幕在线 | 97免费| 久久这里只有精品久久 | 久久久久久久久久久久电影 | 婷婷中文字幕在线观看 | 久久久久久久99精品免费观看 | 在线观看一 | 亚洲国产中文字幕在线观看 | 精品人人人 | 久久毛片高清国产 | 国产精品毛片完整版 | 亚洲理论在线 | 日韩久久久 | 欧美中文字幕第一页 | 国产精品大片在线观看 | 免费成人短视频 | 久久综合网色—综合色88 | 成人 国产 在线 | 成年人在线看片 | 久久成人福利 | 国产成人av福利 | 成人免费观看网址 | 久久久精品成人 | 国产高清在线 | 激情视频免费在线 | 国产精品video爽爽爽爽 | 国内精品视频免费 | 久久黄色网页 | 婷婷色网址 | 亚洲一区二区麻豆 | 国产日韩欧美在线一区 | 国产色一区 | 91最新网址在线观看 | 成人在线视频免费看 | 久久国产成人午夜av影院潦草 | 夜夜看av | 色网免费观看 | 日韩欧美国产激情在线播放 | 欧美三级在线播放 | 精品久久久久国产免费第一页 | 操操操日日日干干干 | 蜜臀av免费一区二区三区 | 日韩欧美在线视频一区二区 | 九九九九热精品免费视频点播观看 | 成人av电影在线播放 | 久久综合久久综合久久 | 丁香五月亚洲综合在线 | 一本到在线 | 欧美美女视频在线观看 | 欧美极品少妇xxxx | www,黄视频 | 国产三级国产精品国产专区50 | 久久久久久久久久久影院 | 国产美女在线精品免费观看 | 精品国产99国产精品 | 久久五月精品 | 五月开心激情网 | 国产精品国产自产拍高清av | 最近更新好看的中文字幕 | 啪嗒啪嗒免费观看完整版 | 日韩视频图片 | 一区二区三区动漫 | 在线免费视频 你懂得 | 精品少妇一区二区三区在线 | 午夜久久 | 久久综合亚洲鲁鲁五月久久 | 深爱五月激情五月 | 最近中文字幕在线中文高清版 | 精品三级av | 国产日韩欧美视频在线观看 | 午夜免费久久看 | 五月婷婷伊人网 | 国产在线不卡视频 | 色婷婷 亚洲 | 成人免费网站视频 | 高清不卡免费视频 | 人人爽人人香蕉 | av导航福利 | 日韩特级片 | adn—256中文在线观看 | 欧美日韩一区二区三区免费视频 | 欧美激情精品久久久久久变态 | 国产精品久久久久久久久久久久久 | 免费视频91| 国产中文字幕视频在线观看 | 人人干人人做 | 国产在线观看av | 天天干,天天干 | 国产精品一区二区三区久久久 | 成年人免费在线看 | 天天干天天拍 | 丁香婷婷综合激情五月色 | 天天干天天射天天操 | www.人人草 | 99热精品视 | 午夜国产福利在线观看 | a特级毛片 | 国产亚洲欧美在线视频 | 91在线精品视频 | 久久久久久久久久久免费视频 | 久久精品999 | 一区二区视频在线免费观看 | a一片一级 | 久久99国产精品免费 | 天天操夜夜拍 | 欧美日韩高清在线观看 | 国产成人一区在线 | av在线网站大全 | 欧美三人交 | 欧美精品午夜 | 狠狠做深爱婷婷综合一区 | 日本中文字幕在线 | 成人在线播放网站 | 亚洲在线观看av | 五月婷婷网站 | 69精品久久| 在线不卡中文字幕播放 | 国产在线不卡 | 久久久久久久久久福利 | 日韩高清在线一区 | 欧美精品国产综合久久 | 午夜精品久久一牛影视 | 欧美a级在线免费观看 | 99久高清在线观看视频99精品热在线观看视频 | 亚州精品一二三区 | www.色婷婷.com | 热久久免费国产视频 | 天天操天天干天天爱 | 中文字幕一区二区三区四区在线视频 | 99麻豆视频 | 在线观看中文字幕一区 | 中文av影院 | 国产在线传媒 | 日韩一二区在线 | 久久久久国产精品视频 | www.91国产 | 在线一区观看 | 黄色小说视频在线 | 国产福利中文字幕 | 91视视频在线直接观看在线看网页在线看 | 欧美日韩视频在线观看一区二区 | 色成人亚洲网 | 色视频成人在线观看免 | 日韩一级黄色av | 久久人人爽人人爽人人片 | 中文字幕在线播放视频 | 中字幕视频在线永久在线观看免费 | 九月婷婷人人澡人人添人人爽 | 在线观看一级 | 久久久久黄色 | 精品国产1区二区 | 亚洲成人午夜在线 | 婷婷福利影院 | 日韩成人邪恶影片 | 在线观看国产www | 91在线精品视频 | 亚洲精品777| 狠狠躁日日躁狂躁夜夜躁 | 草久久久久 | 91av99| 一级免费看 | 96亚洲精品久久 | 日韩欧美91 | 日本一区二区三区视频在线播放 | 久久99精品国产 | 五月天久久综合 | 在线观看中文字幕亚洲 | 亚洲高清91| 国产精品久久久久婷婷二区次 | 日韩精品在线免费观看 | 99热9| 国产精品久久久久久久久免费看 | 在线观看中文字幕av | 视频在线99 | 日韩伦理一区二区三区av在线 | av免费观看在线 | 九九在线播放 | 国产精品一区二区你懂的 | 欧美性大战久久久久 | 天堂网在线视频 | 中文字幕 欧美性 | 中文字幕一区二区三区久久 | 玖玖在线看 | 婷婷色网址 | 欧美日韩视频精品 | 97超碰在线免费观看 | 97久久久免费福利网址 | 精品无人国产偷自产在线 | 亚洲最新在线 | 激情网五月天 | 一区中文字幕在线观看 | 手机av在线网站 | 亚洲精品视频在线 | 亚洲一区精品人人爽人人躁 | 国产精品成久久久久三级 | 免费在线激情电影 | 欧美一级性生活片 | 亚洲欧美国内爽妇网 | 亚洲精品免费在线 | 国产一区视频在线播放 | 欧美最猛性xxxx | 国内精品久久久久国产 | 欧美成人性战久久 | 久久99九九99精品 | 激情xxxx | 香蕉视频在线免费看 | 天天色宗合 | www.夜夜夜 | 一区二区精品视频 | 午夜精品一区二区三区四区 | 日韩中文字幕在线 | 在线91精品| 制服丝袜亚洲 | 一区二区中文字幕在线 | 正在播放国产91 | 国产成人av电影在线 | 在线探花| 国产精品美女久久久网av | 国产69精品久久app免费版 | 国产精品高清一区二区三区 | 亚洲精品视频一二三 | 亚洲一区二区高潮无套美女 |