6.8 其他主题
本节包括几个主题,这些主题不完全适合于本章从client1到client5 的开发中的任一小节的内容:
■ 在使用结果集元数据帮助验证这些数据适合于计算之后,使用结果集数据计算结果。
■ 如何处理很难插入到查询中的数据。
■ 如何处理图形数据。
■ 如何获得表结构的信息。
■ 常见的MySQL程序设计错误及如何避免。
6.8.1在结果集上执行计算
迄今为止,我们集中而主要地使用了结果集元数据来打印行数据,但很明显,除打印之外,还有需要使用数据做其他事情的时候。例如,计算基于数据值的统计信息,应用元数据确保数据适合它们要满足的需求。哪种类型的需求?对于启动程序来说,可能要校验一下正
要执行数字计算的列实际上是否包含着数字!
下面的列表显示了一个简单函数summary _ stats ( ) ,它获取结果集和列索引,并产生列值的汇总统计。该函数还列出缺少数值的数量,它是通过检查NULL 来检测的。这些计算包括两个数据所必须满足的需求, summary_stats() 用结果集元数据来校验:
■ 指定的列必须存在(也就是说,列索引必须在结果集列值的范围内)。
■ 此列必须包括数字值。
如果这些条件不满足,则summary_stats() 只打印出错误消息并返回。代码如下:
请注意在mysql_fetch_row() 循环前面调用的mysql_ data _ seek( )。为获得同样的结果集,它允许多次调用summary _ stats()(假设要计算几列的统计值的话)。每次调用summary _ stats( )都要“重新回到”到结果集的开始(这里假设mysql_store_result() 创建结果集,如果用mysql_use_result() 创建结果集就只能按顺序处理行,而且只能处理一次)。summary_stats() 是个相对简单的函数,但它给我们一个提示,就是如何编写一个比较复杂的计算程序,如两个列的最小二乘回归或者标准统计,如t -检验。
6.8.2 对查询中有疑问的数据进行编码
包括引号、空值和反斜线的数据值,如果把它们插入到查询中,在执行查询时就会产生一些问题。下面的讨论论述了这些难点,并介绍了解决的办法。假设要建造一个SELECT 查询,它基于由name 指向的空终结串的内容:
如果name 的值类似于“0’Malley, Brian”,这时进行的查询就是非法的,因为引号在引用的字符串里出现:
需要特别注意这个引号,以便使服务器不将它解释为name 的结尾。一种方法是在字符串内使用双引号,这就是ANSI SQL 约定。SQL 支持这个约定,也允许引号在反斜线后使用:
另一个有问题之处是查询中任意二进制数据的使用,例如,在把图形存储到数据库这样的应用程序中会发生这种情况。因为二进制数值含有一些字符,把它放到查询中是不安全的。为了解决这个问题,可使用mysql_ escape _ string( ),它可以对特殊字符进行编码,使其在引用的字符串中可以使用。mysql_escape_string() 认为的特殊字符是指空字符、单引号、双引号、反斜线、换行符、回车符和C ontrol - Z(最后一个在Windows 语言环境中出现)。什么时候使用mysql_escape_string() 呢?最保险的回答是“始终”。然而,如果确信数据的形式并且知道它是正确的—可能因为预先执行了确认检查—就不必编码了。例如,如果处理电话号码的字符串,它完全由数字和短线组成,那么就不必调用mysql_ escape _ string( )了,否则还是要调用。
mysql_escape_string() 对有问题的字符进行编码是将它们转换为以反斜线开头的2个字符的序列。例如,空字符转换为‘ \ 0’,这里的0 是可打印的ASCII 码0,而不是空。反斜线、单引号和双引号分别转换为‘ \ \’、‘\’’和‘\”’。调用mysql_escape_string() 的过程如下:
mysql_escape_string() 对from_str 进行编码,并把结果写入to _ str中,还添加了空终结值,这样很方便,因为可以利用像strcpy() 和strlen() 这样的函数使用该结果串。from_str 指向包括将要编码的字符串的char 缓冲区,这个字符串可能包含任何内容,其中包括二进制数据。to_str 指向一个存在的char 缓冲区,在这个缓冲区里,可以写入编码的字符串;不要传递未初始化的指针或NULL 指针,希望由mysql_escape_string() 分配空间。由to_str 指向的缓冲区的长度至少是(from_len*2)+1个字节(很可能from_str 中的每个字符都需要用2 个字符来编码;额外的字节是空终结值)。
from_len 和to_len 都是unsigned int 值,from_len 表示from_str 中数据的长度;提供这个长度是非常必要的,因为from_str 可能包含空值字节,不能把它当作空终结串。从mysql_escape_string() 返回的to_len 值是作为结果的编码字符串的实际长度,没有对空终结值进行计数。
当mysql_escape_string() 返回时, to _ str中编码的结果就可看作是空终结串,因为from_str 中的空值都被编码为‘ \ 0’。
为了重新编写构造SELECT 的代码,使名称的值即使包含引号也能工作,我们进行下面的操作:
6.8.3 图像数据的处理
mysql_escape_string() 的基本功能之一就是把图像数据加载到一个表中。本节介绍如何进行这项工作(这个讨论也适用于二进制数据的其他形式)。假设想从文件中读取图像,并将它们连同唯一的标识符存储到表中。BLOB 类型对二进制数据来讲是个很好的选择,因此可以使用下面的表说明:
实际上,要想从文件中获取图像并放入images 表,利用下面的函数load_image() 可以实现,给出一个标识符号码和一个指向包括这个图像数据的打开文件的指针:
load_image() 不会分配非常大的查询缓冲区( 10 0 K),因此它只能处理相对较小的图形。
在实际的应用程序中,可以根据图形文件的大小动态地分配缓冲区。处理从数据库中恢复的图形数据(或任何二进制数据)并不像开始把它放入时那样问题重重,因为在变量MYSQL_ROW 中数据值的原始形式是有效的,通过调用mysql_ fetch _length ( ),这个长度也是有效的。必须将值看作是计数串,而不是空终结串。
6.8.4 获取表信息
MySQL允许使用下面的查询获取有关表结构的信息(下面两者是等价的):
与SELECT 相类似,两个语句都返回结果集。为了在表中找出有关列,所需做的就是处理结果集中的行,从中获取有用的信息。例如,如果从mysql客户机上发布DESCRIBE images 语句,就会返回这样的信息:
如果从自己的客户机上执行同样的查询,可以得到相同的信息(没有边框)。如果只想要单个列的信息,则使用如下这个查询:
SHOW FIELDS FROM tbl _ name LIKE “col _ name”
此查询会返回相同的列,但只是一行(如果列不存在就不返回行)。
6.8.5 需要避免的客户机程序设计错误
本节讨论一些常见的MySQLC API 程序设计错误,以及如何避免其发生(这些问题在MySQL邮件清单中会周期性地突然出现)。
1. 错误1——使用未初始化的连接处理程序指针在本章的样例中,我们已经通过传递NULL 参数调用了mysql_ i n i t ( ),这就是让它分配并且初始化MYSQL 结构,然后返回一个指针。另外一种方法是将指针传递到一个已有的MYSQL 结构中。在这种情况下, mysql_init() 会将结构初始化并返回一个指针,而不必自己分配结构。如果要使用第二种方法,则要小心会出现一些微妙的问题。下面的讨论指出了需要注意的一些问题。如果将一个指针传递给mysql_ init( ),它应该实际指向某些东西。看下面的代码段:
这个问题是,mysql_init() 得到了一个指针,但指针没有指向所知的任何地方。conn 是一个局部变量,因此在main() 开始执行时它是一个能指向任何地方的未初始化的存储器,这就是说mysql_init() 将使用指针,并可在内存的一些任意区域滥写。如果幸运的话, conn 将指向您的程序地址空间的外部,这样,系统将立即终止,使您能尽早意识到代码中出现的问题。
如果不幸的话, conn 将指向程序中以后才使用的一些数据的内部,直到再次使用那个数据时才发现问题。因此实际出现问题的地方远比执行程序时出现的问题多,也更难捕捉到。下面是一段有问题的代码:
此时, conn 是一个全局变量,因此在程序启动前,将它初始化为0(就是NULL)。mysql_init() 遇到NULL 参数,因此初始化并分配一个新的连接处理程序。只要将conn 传递给需要非NULL 连接处理程序的MySQLCAPI 函数,系统就会崩溃。这些代码段的修改就是确保conn 有一个可知的值。例如,可以将它初始化到已经分配的MYSQL 结构地址中去:
然而,推荐的(较容易的!)解决方案仅仅是将NULL 显式地传递给mysql_ init( ),让该函数分配MYSQL 结构,并将返回值赋值给conn:
无论如何不要忘记检验mysql_init() 的返回值,以确保它不是NULL。
2. 错误2——有效结果集检验的失败
请记住检查希望得到的结果集的调用状态。下面的代码没有做到这一点:
不幸地是,如果mysql_store_result() 失败,res_set 为NULL,while 循环也不执行了,应测试返回结果集函数的返回值,以确保实际上在进行工作。
3. 错误3—— NULL 列值引起的失败
不要忘记检查mysql_fetch_row() 返回的数组MYSQL_ROW 中列值是否为NULL 指针。如果row[i] 为NULL,则在一些机器上,下面的代码就会引起崩溃:
该错误危害最大的部分是,有些printf() 的版本很宽容地对NULL指针输出了“( null )”,这就使错误很容易逃脱而没有把错误定位。如果把程序给了朋友,而他只有不太宽容printf( )版本,程序就会崩溃,您的朋友会认为您是个无用的程序员。循环应该写成下面这样:
不需要检查列值是否为NULL 的惟一一次是当已经从列信息结构确定IS _ NOT _ NULL( )为真时。
4. 错误4——传递无意义的结果缓冲区
需要您提供缓冲区的客户机库函数通常要使这些缓冲区真正存在,下面的代码违反了这个规则:
问题是什么呢?to_str 必须指向一个存在的缓冲区,而在这个样例中没有,因此,它指向了随意的位置。不要向mysql_escape_string 传递无意义的指针作为to_str 参数,否则它会恣意践踏内存。
MYSQL图像数据的处理
时间: 2024-09-25 16:53:56
MYSQL图像数据的处理的相关文章
请问mysql导入数据时,文件名可以用正则表达吗?
问题描述 请问mysql导入数据时,文件名可以用正则表达吗? 我现在有很多iis产生的log文件,想要每天自动导入前一天的log日志到 mysql数据库,现在我只能通过load data local infile '/tmp/ex150801.log'手动导前一天的数据. 如果我要排job自动导出该怎么做? 解决方案 写一个程序定时去跑比较简单,而且灵活. 解决方案二: 用脚本等命令行去调用mysqlimport命令等去加载文件导入数据吧.LOAD DATA语法应该不支持正则
php 解决MySQL插入数据出现 Incorrect string value: &;amp;#39;\xF0\x9F\x92\x8BTi...&;amp;#39;错误
在项目中向MySQL插入数据时,发现数据插入不完整,通过调试,发现插入语句也没什么特殊的错误.但是就是差不进去,于是就打开mysqli错误的调试 $ret = mysqli_query($this->conn, $sql) or die(mysqli_error($this->conn)); 结果弹出如下错误信息: Incorrect string value: '\xF0\x9F\x92\x8BTi...' 有错误信息就好办了,结果上网一查结果是:mysql编码格式utf-8格式,不支持带四
小技巧:用批处理对MySQL进行数据操作
mysql|技巧|数据 批处理是一种非交互式运行mysql程序的方法,如同您在mysql中使用的命令一样,你仍然将使用这些命令. 为了实现批处理,您重定向一个文件到mysql程序中,首先我们需要一个文本文件,这个文本文件包含有与我们在mysql中输入的命令相同的文本. 比如我们要插入一些数据,使用包含下面文本的文件(文件名为New_Data.sql,当然我们也可以取名为New_Data.txt及任何其他的合法名字,并不一定要以后缀sql结尾): USE Meet_A_Geek; INSE
SQL Server存储图像数据的策略与方法
server|策略|数据 目前对于图像数据的管理大都采用表+实体的方法,即图像数据以文件形式存放于指定的计算机目录下,在数据库表中只反映图像数据文件的存储路径.这种管理模式,给数据的维护增加了难度,同时,也给数据的安全带来一定的隐患.因此,要真正做到各类数据在数据库中安全管理,研究和探索直接将图像数据存储在数据库关系表中的方法是非常必要的. 笔者在Visual Basic 6.0开发环境中,采用客户机/服务器的工作方式,针对SQL Server数据库关系表中存储图像数据的问题进行了初步探讨,提出
教你实现MySQL表数据迁移自动化
一.背景 之前我写过关于SQL Server的数据迁移自动化的文章:SQL Server 数据库迁移偏方,在上篇文章中设计了一张临时表,这个临时表记录搬迁的配置信息,用一个存储过程读取这张表进行数据的迁移,再由一个Job进行迭代调用这个存储过程. 在这次MySQL的实战中,我的数据库已经做了4个分片,分布在不同的4台机器上,每台机器上的数据量有1.7亿(1.7*4=6.8亿),占用空间260G(260*4=1040G),这次迁移的目的就是删除掉一些历史记录,减轻数据库压力,有人说这为什么不使用表
mysql dba系统学习(12)mysql的数据文件
mysql的数据文件 一,系统参数datadir 在MySQL 中每一个数据库都会在定义好(或者默认)的数据目录下存在一个以数据库名字命名的文件夹,用来存放该数据库中各种表数据文件 datadir指定的目录是数据库目录的上级目录,一般的创建数据库的时候会创建两个数据库mysql和test,如果再创建一个数据库的话就会多出一个对应的数据库文件夹 mysql> show variables like "%datadir%"; +---------------+------------
用VB存取SQL Server中的图像数据
本文介绍MIS SQL Server对图像数据的存储机制和存取方法.针对VB开发工具,介绍了一种通过ADO Field 对象的GetChunk 方法和AppendChunk 方法来存取MIS SQL Server中的图像数据的方法. 在一个完善的医院信息MIS中,图像数据的存取是必不可少的,比如X光片.CT像片的保存.一方面,这些图像数据在远程诊疗为准确诊断病情提供了重要的依据,另一方面,也为快速查阅病人资料提供了基本条件.图像数据的存取在其它应用系统如GIS中也有广泛的应用. 1.SQL Se
SQL Server存储图像数据的机制介绍
本文介绍MIS SQL Server对图像数据的存储机制和存取方法.针对VB开发工具,介绍了一种通过ADO Field 对象的GetChunk 方法和AppendChunk 方法来存取MIS SQL Server中的图像数据的方法. 在一个完善的医院信息MIS中,图像数据的存取是必不可少的,比如X光片.CT像片的保存.一方面,这些图像数据在远程诊疗为准确诊断病情提供了重要的依据,另一方面,也为快速查阅病人资料提供了基本条件.图像数据的存取在其它应用系统如GIS中也有广泛的应用. 1.SQL Se
MySQL改善数据装载操作效率的策略
[导读]本文介绍MySQL改善数据装载操作效率的策略.多时候关心的是优化SELECT 查询,因为它们是最常用的查询,而且确定怎样优化它们并不总是直截了当.相对来说,将数据装入数据库是直截了当的. 多时候关心的是优化SELECT 查询,因为它们是最常用的查询,而且确定怎样优化它们并不总是直截了当.相对来说,将数据装入数据库是直截了当的.然而,也存在可用来改善数据装载操作效率的策略,其基本原理如下: 成批装载较单行装载更快,因为在装载每个记录后,不需要刷新索引高速缓存:可在成批记录装入后才刷新. 在