python查询最高分_精通 Oracle+Python,第 1 部分:查询最佳应践

作者:Przemyslaw Piotrowski

首先,熟悉 Oracle-Python

连接性的基本概念

2007 年 9 月发布

参见系列目录

在 Python 做事方式的核心原则中,有一个规定是要求具有到 API 的高级接口。数据库 API(在此例中为 Oracle

API)就是一个例子。使用 Computronix 的 cx_Oracle Python 模块,您可以在维持与 Python 数据库

API 规范 v2.0 的兼容性的同时,控制 Oracle 的查询模型。

对于所有遵循该规范的客户端库而言,使用 DB API 2.0 查询数据库的模型都是一致的。在此基础上,cx_Oracle

的主要开发人员 Anthony Tuininga 添加了一组丰富的属性和方法,以向开发人员揭示 Oracle

独有的特性。仅用标准的方法而忘掉“额外的”方法是绝对可能的,但在本文中您不会这么做。通用数据库包装这一概念可能在某些情况下起作用,但与此同时,您会失去

RDBMS 提供的所有优化。

DB API 2.0 和 cx_Oracle 介绍

Python 数据库 API 规范 v2.0

是集体努力的成果,用于统一不同数据库系统的访问模型。拥有一组相对较少的方法和属性,在更换数据库供应商时就易于学习并保持一致。它不以任何方式将数据库对象映射到

Python 结构中。用户仍然需要手工编写 SQL。在更换到另一数据库后,此 SQL

可能需要重新编写。尽管如此,它还是出色妥善地解决了 Python 数据库的连接性问题。

该规范定义了 API 的各个部分,如模块接口、连接对象、游标对象、类型对象和构造器、DB API

的可选扩展以及可选的错误处理机制。

数据库和 Python 语言之间的网关是连接对象。它包含制作数据库驱动的应用程序所需的全部组件,不仅符合 DB API

2.0,而且是规范方法和属性的一个超集。在多线程的程序中,模块和连接可以在不同线程间共享,但是不支持游标共享。这一限制通常是可接受的,因为共享游标可能带来死锁风险。

Python 大量使用了异常模型,DB API

定义了若干标准异常,它们在调试应用程序中的问题时会非常有用。下面是一些标准异常,同时提供了原因类型的简要说明:

Warning — 数据在执行插入操作时被截断,等等

Error — 这里提到的除 Warning 外的所有异常的基类。

InterfaceError — 数据库接口而非数据库本身故障(本例为 cx_Oracle

问题)

DatabaseError — 严格意义上的数据库问题

DataError — 包含如下结果数据的问题除数为 0,值超出范围等

OperationalError —

与编程人员无关的数据库错误:连接丢失、内存分配错误、事务处理错误等

IntegrityError — 数据库的关系完整性受到了影响,例如,外键约束失败

InternalError — 数据库遇到内部错误,例如,游标无效、事务不同步

ProgrammingError — 未找到表、SQL

语句中的语法错误、指定参数的数量错误等

NotSupportedError — 调用的 API 部件并不存在

连接过程首先从连接对象开始,这是创建游标对象的基础。除游标操作外,连接对象还使用 commit() 和 rollback()

方法对事务进行管理。执行 SQL 查询、发出 DML/DCL 语句和获取结果这些过程均受游标控制。

在游标和连接类的实现中,cx_Oracle 对标准的 DB API 2.0

规范进行了最大程度的扩展。如果需要,所有这些扩展都将在文本中清楚地标记。

入门

在使用查询和游标之前,首先需要建立数据库连接。提供凭证和数据源名称的方法有多种,其结果都是相似的。在从下面的 Python

交互式会话提取的内容中,连接对象 db、db1 和 db2 都是等同的。makedsn() 函数根据给定的参数值创建一个 TNS

条目。此处将它赋值给变量 dsn_tns。如果环境设置得当,您可以使用更短的形式

cx_Oracle.connect('hr/hrpwd'),从而省略用于 db 和 db1 的简单连接字符串。

>>>

import cx_Oracle

>>> db =

cx_Oracle.connect('hr', 'hrpwd', 'localhost:1521/XE')

>>> db1 =

cx_Oracle.connect('hr/hrpwd@localhost:1521/XE')

>>> dsn_tns =

cx_Oracle.makedsn('localhost', 1521, 'XE')

>>> print

dsn_tns

(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SID=XE)))

>>> db2 =

cx_Oracle.connect('hr', 'hrpwd', dsn_tns)

在连接对象的作用域内(如分配给上面的 db 变量的连接对象),您可以通过查询版本属性获得数据库版本(这是 DB API 2.0

的一个扩展)。这可以用于使 Python 程序依赖于具体版本的 Oracle 产品。同样地,您可以通过查询 dsn

属性获得连接的连接字符串。

>>>

print db.version

10.2.0.1.0

>>> versioning =

db.version.split('.')

>>> print

versioning

['10', '2', '0', '1', '0']

>>> if

versioning[0]=='10':

... print "Running 10g"

... elif versioning[0]=='9':

... print "Running 9i"

...

Running 10g

>>> print

db.dsn

localhost:1521/XE

游标对象

您可以使用连接对象的 cursor()

方法定义任意数量的游标。简单的程序使用一个游标就可以了,该游标可以一再地重复使用。但较大的项目可能要求几个不同的游标。

>>>

cursor = db.cursor()

应用程序逻辑通常需要明确区分针对数据库发出的语句的各个处理阶段。这有助于更好地理解性能瓶颈并编写更快且经过优化的代码。语句处理分三个阶段:

分析(可选)

cx_Oracle.Cursor.parse([statement])

实际上并不需要调用,因为在执行阶段会自动分析 SQL 语句。该方法可以用于在执行语句前对其进行验证。当这类语句中检测出错误时,会引发

DatabaseError 异常,相应的错误消息通常可能是“ORA-00900:invalid SQL statement,

ORA-01031:insufficient privileges or ORA-00921:unexpected end of

SQL command.”

执行

cx_Oracle.Cursor.execute(statement, [parameters],

**keyword_parameters)此方法可以接受单个参数 — 一条 SQL 语句 —

直接针对数据库来运行。通过 parameters 或 keyword_parameters

参数赋值的绑定变量可以指定为字典、序列或一组关键字参数。如果已经提供了字典或关键字参数,那么这些值将与名称绑定。如果给出的是序列,将根据这些值的位置对它们进行解析。如果是查询操作,此方法返回一个变量对象列表;如果不是,则返回

None。

cx_Oracle.Cursor.executemany(statement,

parameters)对于批量插入尤其有用,因为它可以将所需的 Oracle

执行操作的数量限制为仅一个。有关如何使用该方法的详细信息,请参见下面的“一次多行”部分。

获取(可选)— 仅用于查询(因为 DDL 和 DCL

语句不返回结果)。在不执行查询的游标上,这些方法将引发 InterfaceError 异常。

cx_Oracle.Cursor.fetchall()

以字节组列表形式获取结果集中的所有剩余行。如果没有剩余的行,它返回一个空白列表。获取操作可以通过设置游标的 arraysize

属性进行调整,该属性可设置在每个底层请求中从数据库中返回的行数。arraysize

的设置越高,需要在网络中往返传输的次数越少。arraysize 的默认值为 1。

cx_Oracle.Cursor.fetchmany([rows_no])

获取数据库中接下来的 rows_no 行。如果该参数未指定,该方法获取的行数是 arraysize 的数量。如果 rows_no

大于获取到的行的数目,该方法获取的行数是剩余的行数。

cx_Oracle.Cursor.fetchone()

从数据库中获取单个字节组,如果没有剩余行,则返回 none。

在继续了解游标示例前,请先了解 pprint 模块的 pprint 函数。它用于以清晰、可读的形式输出 Python

数据结构。

>>>

from pprint import pprint

>>>

cursor.execute('SELECT feed_id, feed_url,

XMLType.GetClobVal(feed_xml) FROM rss_feeds')

>>>

cursor.execute('SELECT * FROM jobs')

[,

,

,

None>]

>>>

pprint(cursor.fetchall())

[('AD_PRES', 'President', 20000, 40000),

('AD_VP', 'Administration Vice President', 15000, 30000),

('AD_ASST', 'Administration Assistant', 3000, 6000),

('FI_MGR', 'Finance Manager', 8200, 16000),

('FI_ACCOUNT', 'Accountant', 4200, 9000),

?

('PR_REP', 'Public Relations Representative', 4500,

10500)]

cx_Oracle 游标是迭代器。利用这些强大的 Python

结构,您可以一种自然的方式对序列进行迭代,该方式仅根据需要获取后续的项。高成本的数据库选择操作自然符合这一思路,因为数据只在需要时才被获取。您可以进行迭代操作直至找到需要的值或满足另一条件,而不必创建或获取整个的结果集。

>>>

cursor = db.cursor()

>>>

cursor.execute('SELECT * FROM jobs')

[,

,

,

None>]

>>> for row in cursor:

## notice that this is plain English!

... print row

...

('AD_VP', 'Administration Vice President', 15000, 30000)

('AD_ASST', 'Administration Assistant', 3000, 6000)

('FI_MGR', 'Finance Manager', 8200, 16000)

('FI_ACCOUNT', 'Accountant', 4200, 9000)

('AC_MGR', 'Accounting Manager', 8200, 16000)

?

('PR_REP', 'Public Relations Representative', 4500,

10500)

执行 list(cursor) 后,会针对 cursor.fetchall() 执行相同的任务。这是因为内置的 list()

函数会在给定的迭代器结束前一直进行迭代。

数据类型

在获取阶段,基本的 Oracle 数据类型会映射到它们在 Python 中的等同数据类型中。cx_Oracle

维护一个单独的、有助于这一转换的数据类型集合。Oracle - cx_Oracle - Python 映射为:

Oracle

cx_Oracle

Python

VARCHAR2

NVARCHAR2

LONG

cx_Oracle.STRING

str

CHAR

cx_Oracle.FIXED_CHAR

NUMBER

cx_Oracle.NUMBER

int

FLOAT

float

DATE

cx_Oracle.DATETIME

datetime.datetime

TIMESTAMP

cx_Oracle.TIMESTAMP

CLOB

cx_Oracle.CLOB

cx_Oracle.LOB

BLOB

cx_Oracle.BLOB

除涉及大型对象的情况外,上述数据类型对于用户通常是透明的。截至版本 4.3,cx_Oracle

仍然自已处理这些数据类型,而没有与内置的文件类型打包到一起。

cx_Oracle 目前不负责处理的其他数据类型包括 XMLTYPE

和所有复杂的类型。目前所有对未支持类型的列的查询都会失败,同时引发 NotSupportedError

异常。您需要从查询中清除它们或将它们转换为支持的数据类型。

例如,考虑下面用于存储聚合的 RSS 信源提供的表:

CREATE TABLE rss_feeds

(

feed_id NUMBER PRIMARY KEY,

feed_url VARCHAR2(250) NOT NULL,

feed_xml XMLTYPE

);

尝试使用 Python 查询此表时,需执行一些额外的步骤。在下例中,XMLType.GetClobVal() 用于以 CLOB

值形式从表中返回 XML。

>>>

cursor.execute('SELECT * FROM rss_feeds')

Traceback (most recent call last):

File "", line 1, in

cursor.execute('SELECT * FROM rss_feeds')

NotSupportedError: Variable_TypeByOracleDataType: unhandled data

type 108

>>>

cursor.execute('SELECT feed_id, feed_url,

XMLType.GetClobVal(feed_xml) FROM rss_feeds')

[,

,

None>]

您可能已经注意到了,cx_Oracle.Cursor.execute* 系列方法为查询返回列数据类型。这些是变量对象列表(DB

API 2.0 的扩展),它们在获取阶段之前获取值

None,在获取阶段之后获取合适的数据值。有关数据类型的详细信息,可以通过游标对象的 description

属性获得。description 是一个包含 7

项内容的字节组,每个字节组包含列名、列类型、显示大小、内部大小、精度、小数位数以及是否存在空的可能。注意列信息仅可供 SQL

查询语句访问。

>>>

column_data_types = cursor.execute('SELECT * FROM employees')

>>> print

column_data_types

[,

,

,

,

,

,

,

,

,

,

None>]

>>>

pprint(cursor.description)

[('EMPLOYEE_ID',

'cx_Oracle.NUMBER'>, 7, 22, 6, 0, 0),

('FIRST_NAME',

'cx_Oracle.STRING'>, 20, 20, 0, 0, 1),

('LAST_NAME',

'cx_Oracle.STRING'>, 25, 25, 0, 0, 0),

('EMAIL', ,

25, 25, 0, 0, 0),

('PHONE_NUMBER',

'cx_Oracle.STRING'>, 20, 20, 0, 0, 1),

('HIRE_DATE',

'datetime.datetime'>, 23, 7, 0, 0, 0),

('JOB_ID', ,

10, 10, 0, 0, 0),

('SALARY', ,

12, 22, 8, 2, 1),

('COMMISSION_PCT',

'cx_Oracle.NUMBER'>, 6, 22, 2, 2, 1),

('MANAGER_ID',

'cx_Oracle.NUMBER'>, 7, 22, 6, 0, 1),

('DEPARTMENT_ID',

'cx_Oracle.NUMBER'>, 5, 22, 4, 0,

1)]

绑定变量模式

正如 Oracle 大师 Tom Kyte 介绍的那样,绑定变量是数据库开发的核心原则。它们不仅使程序运行更快,同时可以防范 SQL

注入攻击。请看以下查询:

SELECT * FROM

emp_details_view WHERE department_id=50

SELECT * FROM emp_details_view WHERE department_id=60

SELECT * FROM emp_details_view WHERE department_id=90

SELECT * FROM emp_details_view WHERE department_id=110

逐个运行时,它们需要分别进行分析,这为您的应用程序增加了额外的开销。通过使用绑定变量,您可以告诉 Oracle

对一个查询只分析一次。cx_Oracle 支持按名称或位置绑定变量。

按名称传递绑定变量要求执行方法的 parameters 参数是一个字典或一组关键字参数。下面的 query1 和 query2

是等同的:

>>> named_params =

{'dept_id':50, 'sal':1000}

>>> query1 =

cursor.execute('SELECT * FROM employees WHERE

department_id=:dept_id AND salary>:sal',

named_params)

>>> query2 =

cursor.execute('SELECT * FROM employees WHERE

department_id=:dept_id AND salary>:sal', dept_id=50,

sal=1000)

在使用已命名的绑定变量时,您可以使用游标的 bindnames() 方法检查目前已指定的绑定变量:

>>> print

cursor.bindnames()

['DEPT_ID', 'SAL']

按位置传递与此相似,但是您需要谨慎命名。变量名是任意的,因此这种方式很容易使查询混乱。在下例中,三个查询 r1、r2 和 r3

都是等同的。parameters 变量必须作为序列提供。

>>> r1 =

cursor.execute('SELECT * FROM locations WHERE country_id=:1 AND

city=:2', ('US', 'Seattle'))

>>> r2 =

cursor.execute('SELECT * FROM locations WHERE country_id=:9 AND

city=:4', ('US', 'Seattle'))

>>> r3 =

cursor.execute('SELECT * FROM locations WHERE country_id=:m AND

city=:0', ('US', 'Seattle'))

在绑定时,您可以首先准备该语句,然后利用改变的参数执行 None。根据绑定变量时准备一个语句即足够这一原则,Oracle

将如同在上例中一样对其进行处理。准备好的语句可执行任意次。

>>>

cursor.prepare('SELECT * FROM jobs WHERE

min_salary>:min')

>>> r =

cursor.execute(None, {'min':1000})

>>> print

len(cursor.fetchall())

19

您已经限制了分析次数。在下一段中,我们将消除不必要的执行,尤其是成本高昂的批量插入。

一次多行

大型的插入操作不需求多次的单独插入,这是因为 Python 通过 cx_Oracle.Cursor.executemany

方法完全支持一次插入多行。限制执行操作的数量极大地改善了程序性能,因此在编写存在大量插入操作的应用程序时应首先考虑这一功能。

我们首先为 Python 模块列表创建一个表,这次直接从 Python 开始。您将在以后删除该表。

>>>

create_table = """

CREATE TABLE python_modules (

module_name VARCHAR2(50) NOT NULL,

file_path VARCHAR2(300) NOT NULL

)

"""

>>> from sys import

modules

>>>

cursor.execute(create_table)

>>> M = []

>>> for m_name, m_info

in modules.items():

... try:

... M.append((m_name, m_info.__file__))

... except AttributeError:

... pass

...

>>> len(M)

76

>>>

cursor.prepare("INSERT INTO python_modules(module_name, file_path)

VALUES (:1, :2)")

>>>

cursor.executemany(None, M)

>>> db.commit()

>>> r =

cursor.execute("SELECT COUNT(*) FROM python_modules")

>>> print

cursor.fetchone()

(76,)

>>>

cursor.execute("DROP TABLE python_modules PURGE")

仅向数据库发出一个执行操作,要求将 76

个模块名称全部插入。这对大型插入操作而言是一个巨大的性能提升。注意此处的两点小的不同:cursor.execute(create_tab)

不产生任何输出,这是因为它是一个 DDL 语句,而 (76,) 是一个有单个元素的字节组。不含逗号的 (76) 完全等同于整数

76。

总结

熟悉 Oracle-Python 连接性的基本概念之后,您就可以开始编写自己的数据库驱动的应用程序了。我强烈建议花一些时间来使用

Python 交互式 shell,因为它确实会使学习过程更加容易。

您了解了 SQL 语句经历的三个阶段,也了解了如何将 Oracle

数据库需要执行的步骤减至最少。绑定变量是数据库应用程序开发不可避免的一部分,Python 支持按名称或位置进行绑定。

您还了解了 Oracle 和 Python

数据类型间的平滑转换,以及在将游标作为迭代器进行处理的上下文中数据库数据的自然处理方式。所有这些特性都促进了生产效率的提高并支持专注于数据,而这正是核心所在。

Przemyslaw Piotrowski

是一名信息技术专家,专门研究新兴技术和动态、灵活的开发环境。他拥有很强的 IT

专业技术背景(包括管理、开发和设计),并发现了许多软件互操作方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大学c语言项目,项目大学C语言程序设计期末复习重点.doc

期末复习课笔试试卷基本情况1、单项选择(本题共15个小题,每题2分。30分)在四个备选答案中选择一个正确的。答案唯一。2、阅读程序选择运行结果(本题共有8个小题,每个题3分。24分)考核基本运算。答案唯一。3、阅读程序并填空(本题共有6个小题,…

单片机c语言 oxfe,AVR单片机入门及C语言高效设计实践(五)

ATMEAGl6L的中断系统什么是“中断”?顾名思义中断就是中断某一工作过程去处理一些与本工作过程无关或间接相关或临时发生的事件,处理完后,则继续原工作过程。比如:你在看书,电话响了,你在书上做个记号后去接电话&…

python中property魔法方法原理_Python类中的魔法方法之 __slots__原理解析

在类中每次实例化一个对象都会生产一个字典来保存一个对象的所有的实例属性,这样非常的有用处,可以使我们任意的去设置新的属性。每次实例化一个对象python都会分配一个固定大小内存的字典来保存属性,如果对象很多的情况下会浪费内存空间。可…

c语言 4则运算符,C语言学习之路之四-----------C语言的运算符与表达式

C语言的运算符与表达式运算符与表达式C语言的运算符又称为操作符,是数据间进行运算的符号。C语言的运算符按运算类型可分为赋值运算符、算术运算符、逻辑运算符、关系运算符、位运算符、指针运算符和取成员运算符等;按运算对象(又称为操作数)的个数又可分…

python中if控制语句_Python中流程控制语句之IF语句

生活中经常遇到的各种选择和判断在程序中也会遇到,比如玩色子,猜大小,比如选择哪条路回家?Python程序中同样也会遇到。IF语句就是用作条件判断的控制语句。语法一:if 条件:  # 引号是将条件与结果分开结果1 #tab键&a…

android 生成 资源文件,SVG-Android开源库——SVG生成Vector资源文件的编辑预览工具...

Vector矢量图在Android项目中的利用愈来愈广泛,但是如果你想用Android Studio自带的工具将SVG图片转化成Vector资源文件却是相当麻烦,首先能支持的SVG规范较少,其次操作流程麻烦。而另外一种方式就是通过http://inloop.github.io/svg2android…

python常用序列类型_Python基础-序列类型的常用方法

python 是一门编程语言,是一门完全面向对象的编程语言。各序列类型的自带方法序列的常用方法元组的常用方法字符串的常用方法①列表的常用方法L.append(obj)>>>在列表末尾添加新的对象L.clear()>>>清空整个列表L.copy()>>>复制列表L.cou…

android 内存占用工具,Android系统检测程序内存占用各种方法

1.检查系统总内存liuhxuc ~ $ adb shell cat /proc/meminfoMemTotal: 840868 kBMemFree: 457344 kBBuffers: 1744 kBCached: 203064 kBSwapCached: 0 kBActive: 234932 kBInactive: 129644 kBActive(anon)…

android微信朋友圈相册背景,Android 仿微信朋友圈图片拖拽返回

目前的app的动画效果是越来越炫了,很多主流app的图片预览返回都有类似功能,比较常见的是ios自带相册,微信朋友圈等等。自己项目中也有类似功能,最近整理了一下这个功能的代码,做个笔记记录,有兴趣的朋友可以…

python文本筛选html_python 正则表达式过滤文本中的html标签 源代码解析

#py2.7#coding:utf-8import reimport osimport chardetdef filter_tag(htmlstr):re_cdata re.compile(^>]*>, re.I)re_script re.compile(]*>[^, re.I) #过滤脚本re_style re.compile(]*>[^, re.I) #过滤stylere_br re.compile()re_h re.compile(?\w[^>]*…

erp采购总监个人总结_《用友 ERP 培训教程:财务核算/供应链管理/物料需求计划》ERP概述 : ERP基础知识...

第1章 ERP概述本章重点_- _ERP概要_- _ERP实施成功的必要条件_- _ERP几个重要的名词解释用友ERP-U8(V8 .72)简介及功能按钮说明1.1 ERP基础知识1.1.1 ERP基本概念ERP(Enterprise Resources Planning)中文叫做企业资源规划&…

android studio1.5 for mac,适用于Mac的Android Studio 1.5.x随机崩溃

适用于Mac的Android Studio 1.5(AI-141.2456560)经常随机崩溃.我正在使用Macbook Pro 15“Retina(2105年中期)和Mac OS X 10.11.1真的很烦人.你有过这些崩溃的经历吗?你知道任何解决方法吗?提前致谢.这是崩溃日志的标题:Process: studio [425…

python 八大排序_八大排序算法的 Python 实现

1、插入排序def insert_sort(lists):# 插入排序count len(lists)for i in range(1, count):key lists[i]j i - 1while j > 0:if lists[j] > key:lists[j 1] lists[j]lists[j] keyj - 1return lists2、希尔排序def shell_sort(lists):# 希尔排序count len(lists)st…

soc 设计soc设计 uml实务手册_企业内训“软件需求设计建模方法学全程实例剖析”训练方案(2020年)...

※训练介绍※利润需求-设计。软件开发中,需求是解决“系统怎样好卖”的问题,设计是解决“降低开发成本”的问题。要迈向“低成本制造好卖的产品”的境界,并非喊喊口号就能达到。口号:我们只做最重要的需求,尽快把系统推…

鸿蒙分布式通讯子系统,【鸿蒙】分布式通信子系统--让华为手机发现Hi3861开发板...

目录:工具步骤运行结果工具:1. 华为手机,需要有多设备协同功能。在设置->更多连接->多设备协同,查看是否有多设备协同功能,此功能使用的就是coap协议。2. Hi3861开发板步骤:1. 修改源码,…

python2.7 pyqt4创建qtapp_python-2.7 – 向TabWidget pyqt4添加加号按钮

以下代码提供了一个可以动态添加选项卡的选项卡界面import sys,randomfrom PyQt4 import QtCore,QtGuiclass TabContainer(QtGui.QWidget):def __init__(self):super(TabContainer,self).__init__()self.next_item_is_table Falseself.initUI()def initUI(self):self.setGeome…

html怎样在一张图片里写字,用HTML代码在图片上写字

效果一:文字居中cellSpacing0 cellPadding0 width410 aligncenterbackgroundhttp://bbs.guqu.net/UploadFile/2005-1/200512211045825.gifborder0> type"vertical" spacer>size7>百年爱情文字在图片中的位置。由中的aligncenter决定。center&…

winform 统计大量数据重复的元素个数_DAY10——推断统计之概率与概率分布:常见的离散型概率分布...

「数学期望——某件事情大量发生之后的平均结果」----------------分割又分割----------------------昨天文章排版出了问题,今天重新排版。数据的三个统计维度:集中程度、离散程度、分布情况。集中程度:期望离散程度:方差、标准差…

数组转换为html,如何将多维PHP数组转换为html表

我正在尝试使用多维数组变量制作一个HTML表,该变量$array2是一个查询(来自mysql数据库PHP查询而不是一个自制查询),如下所示;Array([0] > Array([0] > M2TYEE[1] > Jean[2] > Harvey[3] > London[4] > 0314686334)[1] >…

xss跨站脚本攻击_常见攻击之xss跨站脚本攻击

前言随着互联网的不断发展,web应用的互动性也越来越强。相应的,在用户体验提升的同时安全风险也会跟着有所增加。今天,我们就来讲一讲web渗透中常见的攻击方式之一,XSS攻击。首先需要了解他是如何工作的,以及我们如何利…