在Oracle DevGym上学习cx_Oracle的笔记

2024-02-04 12:48
文章标签 oracle 学习 笔记 cx devgym

本文主要是介绍在Oracle DevGym上学习cx_Oracle的笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文是在Oracle DevGym上学习cx_Oracle的笔记。
cx_Oracle帮助文档参见这里
更多学习资源参加Oracle在GitHub上的项目。

环境准备

使用Vagrant Box安装的Oracle Database 19c环境,操作系统为Oracle Linux 7。 详见这里

安装Python3

$ sudo yum install python3
$ python3
Python 3.6.8 (default, Aug  7 2019, 08:02:28)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39.0.1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

安装cx_Oracle

$ pip3 install cx_Oracle --user --upgrade
Collecting cx_OracleDownloading https://files.pythonhosted.org/packages/d5/15/d38862a4bd0e18d8ef2a3c98f39e743b8951ec5efd8bc63e75db04b9bc31/cx_Oracle-7.3.0-cp36-cp36m-manylinux1_x86_64.whl (737kB)100% |████████████████████████████████| 737kB 23kB/s
Installing collected packages: cx-Oracle
Successfully installed cx-Oracle-7.3.0

cx_Oracle依赖于Oracle client library连接Oracle数据库,在我们的Vagrant Box中已经包含了client library。

数据库和cx_Oracle模块就绪后,接下来安装示例Schema,参见如何使用github安装Oracle 数据库12c Sample Schema

测试cx_Oracle
从页面下载示例代码。
只需修改connection = ...那一行,填写相应的hr用户口令和服务名,命名此文件为cxdemo.py。

import cx_Oracle# Establish the database connection
connection = cx_Oracle.connect("hr", "oracle", "localhost/orclpdb1")# Obtain a cursor
cursor = connection.cursor()# Data for binding
managerId = 145
firstName = "Peter"# Execute the query
sql = """SELECT first_name, last_nameFROM employeesWHERE manager_id = :mid AND first_name = :fn"""
cursor.execute(sql, mid = managerId, fn = firstName)# Loop over the result set
for row in cursor:print(row)

运行以上程序输出如下:

('Peter', 'Hall')
('Peter', 'Tucker')

DEV GYM教程Using CX_ORACLE and Python

所有示例代码都可以从这里下载。不过其中有错误,我已在本文中指出。

在这一节的开始,作者提到了两个ORM软件,SQLAlchemy和Pony。
作者引用了Martin Fowler在文章OrmHate中的一句话:

“Mapping to a relational database involves lots of repetitive, boiler-plate code. A framework that allows me to avoid 80% of that is worthwhile even if it is only 80%.”
意思是说,ORM即使只解决了80%的问题,也是值得的。我看了整个文章,后面其实隐含的意思是ORM是做不到100%的,还有一部分需要充分了解数据库,或直接对数据库进行CRUD操作,类似于cx_Oracle这样。

准备工作

这一部分的教程参见这里。

这一部分设置了教程使用的测试表结构数据,我们仍安装在hr用户下。 注意两个表的id列定义,

CREATE TABLE cx_people (id NUMBER GENERATED BY DEFAULT AS identity,name VARCHAR2(20),age NUMBER,notes VARCHAR2(100)
)
/ALTER TABLE CX_PEOPLE
ADD CONSTRAINT PK_CX_PEOPLE PRIMARY KEY ("ID")
/CREATE TABLE CX_PETS (id NUMBER GENERATED BY DEFAULT AS IDENTITY,name VARCHAR2(20),owner NUMBER,type VARCHAR2(100)
)
/ALTER TABLE CX_PETS ADD CONSTRAINT PK_CX_PETS PRIMARY KEY ("ID")
/ALTER TABLE CX_PETS ADD CONSTRAINT FK_CX_PETS_OWNER FOREIGN KEY ("OWNER") REFERENCES "CX_PEOPLE" ("ID")
/INSERT INTO cx_people (name, age, notes)VALUES ('Bob', 35, 'I like dogs')
/INSERT INTO cx_people (name, age, notes)VALUES ('Kim', 27, 'I like birds')
/INSERT INTO cx_pets (name, owner, type)VALUES ('Duke', 1, 'dog')
/INSERT INTO cx_pets (name, owner, type)VALUES ('Pepe', 2, 'bird')
/COMMIT
/

输出如下:

SQL> desc cx_peopleName                                      Null?    Type----------------------------------------- -------- ----------------------------ID                                        NOT NULL NUMBERNAME                                               VARCHAR2(20)AGE                                                NUMBERNOTES                                              VARCHAR2(100)SQL> desc cx_petsName                                      Null?    Type----------------------------------------- -------- ----------------------------ID                                        NOT NULL NUMBERNAME                                               VARCHAR2(20)OWNER                                              NUMBERTYPE                                               VARCHAR2(100)SQL> select * from cx_people;ID NAME            AGE NOTES
---------- -------- ---------- ------------------------1 Bob              35 I like dogs2 Kim              27 I like birdsSQL> select * from cx_pets;ID NAME          OWNER TYPE
---------- -------- ---------- ------------1 Duke              1 dog2 Pepe              2 bird

如需清理测试数据,执行以下:

drop table CX_PETS
/drop table CX_PEOPLE
/

注意上面两个表id列的定义,使用了12.1版本后支持的IDENTITY Columns特性,简称为ID列。
简单介绍见这里,记住以下几点:

  • 每个表只能有一个ID列
  • 当表中数据被清除时,ID列的值重置会初始值

参照以下的实验理解其概念:

create table test(id NUMBER GENERATED BY DEFAULT AS identity, name varchar2(20));
alter table test modify id generated BY DEFAULT as identity (START WITH 3);
insert into test(name) values('tony');
select * from test;ID NAME
---------- --------------------3 tony

连接测试:

>>> import cx_Oracle
>>> con = cx_Oracle.connect('hr/oracle@orclpdb1')
<cx_Oracle.Connection to hr@orclpdb1>

插入数据

这一部分的教程参见这里。
第一个程序reset_data.py用于重置数据,也就是删除所有数据后再插入测试数据,也就是建立测试数据的基线。

import cx_Oracle
import os
connectString = os.getenv('db_connect') # 从环境变量db_connect中读取连接串
con = cx_Oracle.connect(connectString)
cur = con.cursor()# Delete rows
statement = 'delete from cx_pets'
cur.execute(statement)# 设置id列,如果是自动生成(也就是当未指定此列值时),则从3开始。 因为前面已经插入两行了
statement = 'alter table cx_pets modify id generated BY DEFAULT as identity (START WITH 3)'
cur.execute(statement)# Delete rows
statement = 'delete from cx_people'
cur.execute(statement)# 设置id列,如果是自动生成(也就是当未指定此列值时),则从3开始。 因为前面已经插入两行了
statement = 'alter table cx_people modify id generated BY DEFAULT as identity (START WITH 3)'
cur.execute(statement)# Insert default rows
rows = [(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]
cur.bindarraysize = len(rows)
cur.setinputsizes(int, 20, int, 100)    # 20 和 100 表示VARCHAR2的宽度
cur.executemany("insert into cx_people(id, name, age, notes) values (:1, :2, :3, :4)", rows)
con.commit()# Insert default rows
rows = [(1, 'Duke', 1, 'dog'), (2, 'Pepe', 2, 'bird')]
cur.bindarraysize = len(rows)
cur.setinputsizes(int, 20, int, 100)    # 20 和 100 表示VARCHAR2的宽度
cur.executemany("insert into cx_pets (id, name, owner, type) values (:1, :2, :3, :4)", rows)
con.commit()cur.close()

测试此程序如下:

$ export db_connect='hr/oracle@orclpdb1'
$ python3 reset_data.py
$ sqlplus登入数据库查看表和数据均存在

接下来是一个程序模板,我们命名为template.py

import cx_Oracle
import os
connectString = os.getenv('db_connect')
con = cx_Oracle.connect(connectString)def get_all_rows(label):# Query all rowscur = con.cursor()statement = 'select id, name, age, notes from cx_people order by id'cur.execute(statement)res = cur.fetchall()print(label + ': ')print (res)print(' ')cur.close()get_all_rows('Original Data')# 插入你的代码get_all_rows('New Data')

这个模板的作用是显示操作前后表cx_people的所有数据。 之后我们只需将操作代码放置到# 插入你的代码这一行。

基本INSERT操作
在模板中嵌入以下代码并形成文件insert.py

cur = con.cursor()
statement = 'insert into cx_people(name, age, notes) values (:2, :3, :4)'
cur.execute(statement, ('Sandy', 31, 'I like horses'))
con.commit()

运行结果为:

Original Data:
[(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]New Data:
[(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds'), (3, 'Sandy', 31, 'I like horses')]

注意插入时并没有指定id的值,这一列是自动增长的,且初始值设为3。

如果需要插入多行,可以执行多个execute()语句,然后一次性用commit()提交。

利用cx_Oracle.connect()可以在一个程序里创建多个数据库连接,也就是可以模拟多个会话,例如作者创建了两个连接来验证只有在第一个会话提交数据后,第二个会话才能看到数据的变化。

利用RETURNING返回参数
重置数据,然后将以下代码插入到模板并运行, 原程序有错误,我已经做了修改,见中文注释:

cur = con.cursor()new_id = cur.var(cx_Oracle.NUMBER)statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id into :4'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id))sandy_id = new_id.getvalue()[0] # getvalue()返回List,因此我们只取其第一个元素pet_statement = 'insert into cx_pets (name, owner, type) values (:1, :2, :3)'
cur.execute(pet_statement, ('Big Red', sandy_id, 'horse'))
con.commit()print('Our new value is: ' + str(sandy_id).rstrip('.0'))sandy_pet_statement = 'select name, owner, type from cx_pets where owner = :owner'
cur.execute(sandy_pet_statement, {'owner': int(sandy_id)})  # 转换成整形以避免类型不匹配错误
res = cur.fetchall()
print('Sandy\'s pets: ')
print (res)
print(' ')

上面代码中最重要的是returning关键字,使得我们可以在SQL中输出变量。

原代码中的sandy_id = new_id.getvalue()必须修改,否则报以下错误:

cx_Oracle.DatabaseError: ORA-01484: arrays can only be bound to PL/SQL statements

下面一段代码和上一个类似,只不过多返回了一个变量,注意原代码同样存在错误:

cur = con.cursor()new_id = cur.var(cx_Oracle.NUMBER)
new_name = cur.var(cx_Oracle.STRING)statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id, name into :4, :5'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id, new_name))sandy_id = new_id.getvalue()[0]         # 原代码是错的
sandy_name = new_name.getvalue()[0]     # 原代码是错的con.commit()print('Our new id is: ' + str(sandy_id).rstrip('.0') + ' name: ' + str(sandy_name))

利用EXECUTEMANY()一次性插入多行
每次插入一行效率很低,我们可以利用bind array一次插入多行,使用的方法是executemany():

rows = [('Sandy', 31, 'I like horses'), ('Suzy', 29, 'I like rabbits')]
cur = con.cursor()
cur.bindarraysize = len(rows)
cur.setinputsizes(20, int, 100)     # 20和100是列定义VARCHAR2的长度
statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3)'
cur.executemany(statement, rows)
con.commit()

查询数据

这一部分的教程参见这里。

基本查询
以下的代码返回表cx_people中的数据:

cur = con.cursor()
statement = 'select id, name, age, notes from cx_people'
cur.execute(statement)
res = cur.fetchall()
print (res)

输出为list of tuple:

[(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]

特定查询
当我们需要查询满足特定条件的行时,使用字符串拼接是不建议的,可能带来安全风险,如SQL Injection:

-- 不建议
statement = "select id, name, age, notes from cx_people where name= '" + person_name + "'"

我们建议的方法是使用绑定变量,按位置或按名称:

-- 按位置
cur.execute('select id, name, age, notes from cx_people where name=:1 and age=:2', ('Bob', 35))
-- 按名称
cur.execute('select id, name, age, notes from cx_people where name = :name and age = :age', {'name':'Bob', 'age':35})

代码如下,当绑定变量为按名称时,带入变量使用dictionary的键值对形式:

cur = con.cursor()
person_name = 'Kim'
statement = 'select id, name, age, notes from cx_people where name = :name'
cur.execute(statement, {'name':person_name})
res = cur.fetchall()
print (res)

输出如下:

[(2, 'Kim', 27, 'I like birds')]

更新数据

这一部分的教程参见这里。

在这一节,我们使用了新的模板,变化是函数get_all_rows增加了data_type参数以返回指定表的所有数据:

import cx_Oracle
import os
connectString = os.getenv('db_connect')
con = cx_Oracle.connect(connectString)def get_all_rows(label, data_type='people'):# Query all rowscur = con.cursor()if (data_type == 'pets'):statement = 'select id, name, owner, type from cx_pets order by owner, id'else:statement = 'select id, name, age, notes from cx_people order by id'cur.execute(statement)res = cur.fetchall()print(label + ': ')print (res)print(' ')cur.close()get_all_rows('Original Data')# Your code hereget_all_rows('New Data')

相应的,reset_data.py也修改为如下,唯一的变化是cx_pets表中插入了7条而不是2条数据:

import cx_Oracle
import os
connectString = os.getenv('db_connect')
con = cx_Oracle.connect(connectString)
cur = con.cursor()# Delete rows
statement = 'delete from cx_pets'
cur.execute(statement)# Reset Identity Coulmn
statement = 'alter table cx_pets modify id generated BY DEFAULT as identity (START WITH 8)'
cur.execute(statement)# Delete rows
statement = 'delete from cx_people'
cur.execute(statement)# Reset Identity Coulmn
statement = 'alter table cx_people modify id generated BY DEFAULT as identity (START WITH 3)'
cur.execute(statement)# Insert default rows
rows = [(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]
cur.bindarraysize = 2
cur.setinputsizes(int, 20, int, 100)
cur.executemany("insert into cx_people(id, name, age, notes) values (:1, :2, :3, :4)", rows)
con.commit()# Insert default rows
rows = [(1, 'Duke', 1, 'dog'),(2, 'Pepe', 2, 'bird'),(3, 'Princess', 1, 'snake'),(4, 'Polly', 1, 'bird'),(5, 'Rollo', 1, 'horse'),(6, 'Buster', 2, 'dog'),(7, 'Fido', 1, 'cat')]
cur.bindarraysize = len(rows)   # 原代码中设置成2
cur.setinputsizes(int, 20, int, 100)
cur.executemany("insert into cx_pets (id, name, owner, type) values (:1, :2, :3, :4)", rows)
con.commit()cur.close()

此代码中cursor.bindarraysize表示每次绑定的行数,如果是1,则每次插入一行。当批量插入时,将此值设大有利于性能。

简单更新
代码片段如下:

cur = con.cursor()
statement = 'update cx_people set age = :1 where id = :2'
cur.execute(statement, (31, 1))
con.commit()

输出为

Original Data:
[(1, 'Bob', 35, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]New Data:
[(1, 'Bob', 31, 'I like dogs'), (2, 'Kim', 27, 'I like birds')]

通过rowcount()获取受影响的行数
由于需要更新cx_pets,因此需要将模板中的get_all_rows()函数修改为以下:

get_all_rows('Original Data', 'pets')# Your code hereget_all_rows('New Data', 'pets')

代码片段如下:

cur = con.cursor()
statement = 'update cx_pets set owner = :1 where id = :2'
cur.execute(statement, (1, 6))
print('Number of rows updated: ' + str(cur.rowcount))
con.commit()
print(' ')

执行结果如下,注意id为6那行,owner由2改为了1:

Original Data:
[(1, 'Duke', 1, 'dog'), (3, 'Princess', 1, 'snake'), (4, 'Polly', 1, 'bird'), (5, 'Rollo', 1, 'horse'), (7, 'Fido', 1, 'cat'), (2, 'Pepe', 2, 'bird'), (6, 'Buster', 2, 'dog')]Number of rows updated: 1New Data:
[(1, 'Duke', 1, 'dog'), (3, 'Princess', 1, 'snake'), (4, 'Polly', 1, 'bird'), (5, 'Rollo', 1, 'horse'), (6, 'Buster', 1, 'dog'), (7, 'Fido', 1, 'cat'), (2, 'Pepe', 2, 'bird')]

可以尝试,如果rowcount不满足某一条件,则回退事务。

删除数据

这一部分的教程参见这里。
在这一节,模板函数和上一节一致。
重置文件reset_data.py修改为以下,变化为cx_people和cx_pets都插入了7行。

import cx_Oracle
import os
connectString = os.getenv('db_connect')
con = cx_Oracle.connect(connectString)
cur = con.cursor()# Delete rows
statement = 'delete from cx_pets'
cur.execute(statement)# Reset Identity Coulmn
statement = 'alter table cx_pets modify id generated BY DEFAULT as identity (START WITH 8)'
cur.execute(statement)# Delete rows
statement = 'delete from cx_people'
cur.execute(statement)# Reset Identity Coulmn
statement = 'alter table cx_people modify id generated BY DEFAULT as identity (START WITH 8)'
cur.execute(statement)# Insert default rows
rows = [(1, 'Bob', 35, 'I like dogs'),(2, 'Kim', 27, 'I like birds'),(3, 'Cheryl', 23, 'I like horses'),(4, 'Bob', 27, 'I like rabbits'),(5, 'Stacey', 45, 'I like snakes'),(6, 'Pete', 23, 'I like cats'),(7, 'Pat', 36, 'I like dogs')]
cur.bindarraysize = 2
cur.setinputsizes(int, 20, int, 100)
cur.executemany("insert into cx_people(id, name, age, notes) values (:1, :2, :3, :4)", rows)
con.commit()# Insert default rows
rows = [(1, 'Duke', 1, 'dog'),(2, 'Dragon', 2, 'bird'),(3, 'Sneaky', 5, 'snake'),(4, 'Red', 2, 'bird'),(5, 'Red', 3, 'horse'),(6, 'Buster', 2, 'dog'),(7, 'Fido', 7, 'cat')]
cur.bindarraysize = 2
cur.setinputsizes(int, 20, int, 100)
cur.executemany("insert into cx_pets (id, name, owner, type) values (:1, :2, :3, :4)", rows)
con.commit()cur.close()

代码片段如下:

cur = con.cursor()
statement = 'delete from cx_pets where id = :id'
cur.execute(statement, {'id':1})
con.commit()

由于都和前面差不多,因此不再赘述。

遗留问题:如果绑定Null值?

cx_Oracle Connection Object

参见文档
连接数据库成功后会返回cx_Oracle.Connection对象。
Connection对象的方法和属性包括:

>>> connection.
connection.DataError(            connection.cancel(               connection.encoding              connection.outputtypehandler
connection.DatabaseError(        connection.changepassword(       connection.enq(                  connection.ping(
connection.Error(                connection.client_identifier     connection.enqoptions(           connection.prepare(
connection.IntegrityError(       connection.clientinfo            connection.external_name         connection.queue(
connection.InterfaceError(       connection.close(                connection.getSodaDatabase(      connection.rollback(
connection.InternalError(        connection.commit(               connection.gettype(              connection.shutdown(
connection.NotSupportedError(    connection.createlob(            connection.handle                connection.startup(
connection.OperationalError(     connection.current_schema        connection.inputtypehandler      connection.stmtcachesize
connection.ProgrammingError(     connection.cursor(               connection.internal_name         connection.subscribe(
connection.Warning(              connection.dbop                  connection.ltxid                 connection.tag
connection.action                connection.deq(                  connection.maxBytesPerCharacter  connection.tnsentry
connection.autocommit            connection.deqoptions(           connection.module                connection.unsubscribe(
connection.begin(                connection.dsn                   connection.msgproperties(        connection.username
connection.callTimeout           connection.edition               connection.nencoding             connection.version

除了建立和关闭连接,此对象还可切换schema,关闭和启动数据库。
以下是连接成功后其它一些属性:

>>> connection.dsn
'localhost/orclpdb1'
>>> connection.autocommit
0
>>> connection.encoding
'ASCII'
>>> connection.version
'19.3.0.0.0'
>>> connection.username
'hr'
>>> connection.tnsentry
'localhost/orclpdb1'
>>> connection.nencoding
'ASCII'
>>> connection.current_schema
>>> connection.maxBytesPerCharacter
1

Connect to the database using cx_Oracle

https://devgym.oracle.com/pls/apex/f?p=10001:5:112176356535023::NO:5:P5_COMP_EVENT_ID,P5_QUIZ_ID,P5_CLASS_ID,P5_WORKOUT_ID,P5_RETURN_TO_PAGE,P5_QUESTION_ID,P5_PREVIEW_ONLY,P5_USER_WORKOUT_ID,P5_COMPEV_ANSWER_ID:2015492,3012272,4702,123001,329,N,545944,&cs=1ulwhvsWu95YVZeTClXQNf9g7iu_a5pvJQnnrVTTyxQzOoIOIpZwUXfeHonWMQTwuUiGArC7qBHYoMu1d_KB4IQ

cx_Oracle Cursor Object

Cursor对象是操作数据库最重要的对象。详见这里
Cursor对象的方法和属性如下:

>>> cursor.
cursor.arraysize              cursor.close(                 cursor.fetchmany(             cursor.inputtypehandler       cursor.scroll(
cursor.arrayvar(              cursor.connection             cursor.fetchone(              cursor.lastrowid              cursor.scrollable
cursor.bindarraysize          cursor.description            cursor.fetchraw(              cursor.outputtypehandler      cursor.setinputsizes(
cursor.bindnames(             cursor.execute(               cursor.fetchvars              cursor.parse(                 cursor.setoutputsize(
cursor.bindvars               cursor.executemany(           cursor.getarraydmlrowcounts(  cursor.prepare(               cursor.statement
cursor.callfunc(              cursor.executemanyprepared(   cursor.getbatcherrors(        cursor.rowcount               cursor.var(
cursor.callproc(              cursor.fetchall(              cursor.getimplicitresults(    cursor.rowfactory

以下为运行cx_demo.py时输出的部分属性:

>>> cursor.arraysize
100
>>> cursor.bindarraysize
1
>>> cursor.bindvars
{'mid': <cx_Oracle.NUMBER with value 145>, 'fn': <cx_Oracle.STRING with value 'Peter'>}
>>> cursor.connection
<cx_Oracle.Connection to hr@localhost/orclpdb1>
>>> cursor.description
[('FIRST_NAME', <class 'cx_Oracle.STRING'>, 20, 20, None, None, 1), ('LAST_NAME', <class 'cx_Oracle.STRING'>, 25, 25, None, None, 0)]
>>> cursor.lastrowid
>>> cursor.rowcount
0
>>> cursor.rowfactory
>>> cursor.scrollable
False
>>> cursor.statement
'SELECT first_name, last_name\n         FROM employees\n         WHERE manager_id = :mid AND first_name = :fn'

cx_Oracle cursor functionality

https://devgym.oracle.com/pls/apex/f?p=10001:5:112176356535023::NO:5:P5_COMP_EVENT_ID,P5_QUIZ_ID,P5_CLASS_ID,P5_WORKOUT_ID,P5_RETURN_TO_PAGE,P5_QUESTION_ID,P5_PREVIEW_ONLY,P5_USER_WORKOUT_ID,P5_COMPEV_ANSWER_ID:2015492,3012274,4702,123001,329,N,545944,&cs=1Jszzdg_Drxs1fhIP-KKyL0-PdoesilD8yCC2xMU25NdmsrcNoTm1uEwlRJBXPH_jVgJh5jazTIhLjPjdUw_k4w

这篇关于在Oracle DevGym上学习cx_Oracle的笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/677559

相关文章

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss