StupidBeauty
Read times:2269Posted at:Thu May 17 23:52:39 2012
- no title specified

MySQL++3.1.0用户手册翻译:4. 模板查询,4. Template Queries

4. 模板查询

上一章

下一章

4. 模板查询

MySQL++的另一个强大技能是使用模板查询。这些东西与C语言的 printf() 类似:妳向MySQL++提供一个字符串,其中包含查询语句的不变部分,也包含可变部分的占位符,稍后再将参数值填充到占位符中。

下面的程序演示咯如何使用这个技能。对应的文件是 examples/tquery1.cpp :

#include "cmdline.h"

#include "printdata.h"

#include <iostream>

using namespace std;

int

main(int argc, char *argv[])

{

//从命令行获取数据库连接参数

const char* db = 0, *server = 0, *user = 0, *pass = "";

if (!parse_command_line(argc, argv, &db, &server, &user, &pass)) {

return 1;

}

try {

//连接到数据库服务器。

mysqlpp::Connection con(db, server, user, pass);

//构造一个模板查询,根据条目名字查询存货条目。

mysqlpp::Query query = con.query(

"select * from stock where item = %0q");

query.parse();

//获取一个由resetdb 添加的条目;如果在执行resetdb 之后运行过tquery*或ssqls3,则它会消失。

mysqlpp::StoreQueryResult res1 = query.store("Nürnberger Brats");

if (res1.empty()) {

throw mysqlpp::BadQuery("UTF-8 bratwurst item not found in "

"table, run resetdb");

}

//使用另一个模板查询,将原来的德文名字替换成一个7位的ASCII近似单词。

query.reset(); //清除上次使用的模板查询数据

query << "update stock set item = %0q where item = %1q";

query.parse();

mysqlpp::SimpleResult res2 = query.execute("Nuerenberger Bratwurst",

res1[0][0].c_str());

//输出新的表格内容。

print_stock_table(query);

}

catch (const mysqlpp::BadQuery& er) {

//处理查询错误

cerr << "Query error: " << er.what() << endl;

return -1;

}

catch (const mysqlpp::BadConversion& er) {

//处理转换过程中的错误

cerr << "Conversion error: " << er.what() << endl <<

"\tretrieved data size: " << er.retrieved <<

", actual size: " << er.actual_size << endl;

return -1;

}

catch (const mysqlpp::Exception& er) {

//处理其它MySQL++异常

cerr << "Error: " << er.what() << endl;

return -1;

}

return 0;

}

query.parse() 之前的那一行就是用来设置模板的,而随后调用的parse 使它生效。从这个时候开始,妳可以通过调用Query 的任意支持查询模板参数的成员函数来重用这个查询对象咯。在这个示例中,我们使用的是 Query::execute()

让我们来深入研究一下这个技能。

4.1. 设置模板查询

要设置一个模板查询的话,妳只需简单地在Query 对象中想要改变查询语句的地方插入带编号的占位符。然后,调用parse()函数,告诉Query 对象,这是一个模板查询,需要分析:

query << "select (%2:field1, %3:field2) from stock where %1:wheref = %0q:what";

query.parse();

占位符的格式是:

%###(modifier)(:name)(:)

其中,“###”是一个数,最多有3位数字。它表示的是参数被赋予给 SQLQueryParms 对象的顺序,从0开始计数。

modifier”可以是以下值:

%

输出一个真正的“%”

""

无论如何,不要引用,不要转义。

q

这将会使用MySQL 的C语言API 中的 mysql_escape_string() 函数来对当前条目进行转义处理。并且会根据实际使用的值进行判断,在必要的情况下用单引号引用起来。

Q

按照与“q”相同的规则来引用,但不进行转义处理。如果妳确定妳的字符串不需要经过转义处理,则可以通过这个来节约一点处理时间

:name”是一个可选的名字,用来辅助填充SQLQueryParms。名字可包含任意的字母、数字和下划线。妳可以带上一个冒号,但是它会被忽略。如果妳确实需要在名字末尾带上一个冒号的话,则写上两个冒号。第一个冒号表示名字的结尾,第二个冒号会被原样保留。

4.2. 在执行时设置参数

要想要执行查询时指定参数,只需使用 Query::store(const SQLString &parm0, [..., const SQLString &parm11]) 。这种多次重载的情况也存在于 Query::storein() Query::use() Query::execute() 中。“parm0”对应于第一个参数,如此类推。妳最多可以指定25个参数。例如:

StoreQueryResult res = query.store("Dinner Rolls", "item", "item", "price")

对于前面说过的模板查询,会产生以下查询语句:

select (item, price) from stock where item = "Dinner Rolls"

至于这里我们为什么不按照数字顺序来写上模板参数勒。

select (%0:field1, %1:field2) from stock where %2:wheref = %3q:what

稍后再向妳解释。

4.3. 默认参数

模板查询机制允许妳设置默认参数值。妳只需将一个值赋予 Query::template_defaults 数组中对应位置的参数即可。妳可以用位置或名字来引用对应的参数:

query.template_defaults[1] = "item";

query.template_defaults["wheref"] = "item";

上面两条语句是同样的效果。

这个机制与C++的默认函数参数机制类似:如果妳在参数列表的末尾设置咯某些参数的默认值,则妳无需传递所有参数值便可以调用 Query 的查询执行方法。如果这个查询需要四个参数,而妳已经为后面三个参数设置咯默认值,则妳可以只显式传递一个参数便执行查询。

现在妳知道我们在前面的某个例子里为什么不按照数字顺序来写模板查询参数咯。我们让那些不怎么会改变的参数的编号更大,这样我们就不用总是传递这些参数咯。我们可以为它们设置默认值,然后,在默认值有效的情况下,直接使用默认值。当一个模板查询中的某些参数变化得比较少时,这种方法最有效。例如:

query.template_defaults["field1"] = "item";

query.template_defaults["field2"] = "price";

StoreQueryResult res1 = query.store("Hamburger Buns", "item");

StoreQueryResult res2 = query.store(1.25, "price");

上面的代码片段分别将以下两条查询语句的结果储存到 res1 res2 中:

select (item, price) from stock where item = "Hamburger Buns"

select (item, price) from stock where price = 1.25

在这个示例中,默认参数是有用的,因为我们有两个查询要执行,其中2号和3号参数保持不变,而0号和1号参数发生变化。

某些人曾采用这种方法来设置一个查询中的所有模板参数:

query.template_defaults["what"] = "Hamburger Buns";

query.template_defaults["wheref"] = "item";

query.template_defaults["field1"] = "item";

query.template_defaults["field2"] = "price";

StoreQueryResult res1 = query.store();

这样有可能正常运行,但是 按照我们的设计,是不应该这样做的 。事实上,已知在某种常见的情况下,这种方法会失效。如果妳在邮件列表中报怨说这种方法无效,那么没人会同情妳。如果妳的代码在后续的查询中连一个参数都不显式地重用的话,那么妳就是在滥用MySQL++, 而且它狠有可能会惩罚妳(☯,本座极不喜欢这种威胁式的手册)。

上一章

下一章

3. 教程

首页

5. 特殊SQL 结构

Your opinions
Your name:Email:Website url:Opinion content:
Recent comments
2017年4月~2019年4月垃圾短信排行榜Posted at:Thu Sep 26 04:51:48 2024
Qt5.7文档翻译:QWebEngineCookieStore类,QWebEngineCookieStore ClassPosted at:Fri Aug 11 06:50:35 2023盲盒kill -9 18289 Grebe.20230517.211749.552.mp4