MySQL对分隔符的处理(二)

本文深入探讨MySQL客户端如何处理系统命令与SQL语句的区别,特别是针对带有分号结尾的系统命令可能导致的问题。通过分析源代码揭示了find_command和add_line函数的工作原理,并提供了详细的MySQL系统命令列表。

 

(接上篇)

    问题就出在find_command函数这里,让我们find_command干了什么事。它并没有像我们想像的那样在长格式的系统命令的行尾添加分号不会影响命令的正常执行。

Code:

 

 

    

    客户端没有把source pp#idhuishou.sql;当成命令处理,接下来就交给了add_line来处理了,而add_line又会把井号后面的内容全部当做注释处理掉,不会传给MySQL然后接着等待另一个分号的输入以做为语句的结束,因此source pp#idhuishou.sql;就变成了source pp。下面就是add_line函数的代码:

 

 

 

 

    如果输入的系统命令结尾带有分号find_command就会将系统命令当成普通的SQL语句来处理,不使用单独的处理函数,这样会不会有问题呢?下面以com_source为例,看一看MySQL是如何处理SOURCE命令的。

 

 

 

    看到这里还有个疑问,既然MySQL的系统命令分别有单独的函数进行处理,

 

 

static int com_source(String *buffer, char *line)                                                                                                             {   ... ...   error= read_and_execute(false);//以非交互模式嵌套调用read_and_execute函数... ...

return error; 

//可见com_source并没做什么实事,检测了一下将要处理的文件的可读性,

//和普通SQL语句一样把又任务交给了read_and_execute结尾处的com_go函数来处理

}

下面列举所有的MySQL系统命令如下:

mysql> ?  

For information about MySQL products and services, visit:http://www.mysql.com/

 

For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Network Support, training, or other products, visit:https://shop.mysql.com/ List of all MySQL commands: Note that all text commands must be first on line and end with ';' ? (\?) Synonym for `help'. clear (\c) Clear command. connect (\r) Reconnect to the server. Optional arguments are db and host. delimiter (\d) Set statement delimiter. NOTE: Takes the rest of the line as new delimiter. edit (\e) Edit command with $EDITOR. ego (\G) Send command to mysql server, display result vertically. exit (\q) Exit mysql. Same as quit. go (\g) Send command to mysql server. help (\h) Display this help. nopager (\n) Disable pager, print to stdout. notee (\t) Don't write into outfile. pager (\P) Set PAGER [to_pager]. Print the query results via PAGER. print (\p) Print current command. prompt (\R) Change your mysql prompt. quit (\q) Quit mysql. rehash (\#) Rebuild completion hash. source (\.) Execute an SQL script file. Takes a file name as an argument. status (\s) Get status information from the server. system (\!) Execute a system shell command. tee (\T) Set outfile [to_outfile]. Append everything into given outfile. use (\u) Use another database. Takes database name as argument. charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets. warnings (\W) Show warnings after every statement. nowarning (\w) Don't show warnings after every statement. For server side help, type 'help contents'

总结 要清楚的知道哪些语句是系统命令,哪些语句是标准的SQL语句,系统命令结尾最好不要有分号。

MySQL手册也有盲点,还是代码靠谱。

 

 

 

tatic bool add_line(String &buffer,char *line,char *in_string,
                     bool *ml_comment)
{
... ...
 
 

else if (!*ml_comment && (!*in_string && (inchar == '#' || 

//就是这里把"#"号"-- "等后面的内容都当做注释处理掉了

inchar == '-' && pos[1] == '-' && my_isspace(charset_info,pos[2])))) break; // comment to end of line ... ... }

 

 

static COMMANDS *find_command(char *name,char cmd_char){     ... ...

if (strstr(name, "\\g") || (strstr(name, delimiter) &&  

//语句中含有分号,\g或通过delimiter指定的其他分隔符,客户端就不会把这条语句当成系统命令。

//问题就出在这里,当find_command函数看到分号或\g无论如何它都不会把语句当成系统命令来处理


!(strlen(name) >= 9 && !my_strnncoll(charset_info, (uchar*) name, 9, (const uchar*) "delimiter", 9))))

DBUG_RETURN((COMMANDS *) 0); 

//判断不是系统命令就返回一个空指针

if ((end=strcont(name," \t"))) { len=(uint) (end - name); while (my_isspace(charset_info,*end)) end++; if (!*end)

end=0;  

// no arguments to function

} else len=(uint) strlen(name); ... ... }

 











本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/748591,如需转载请自行联系原作者

MySQL 中,`CREATE TABLE` 语句本身并不支持直接通过 `SET FIELD DELIMITER` 或类似的语法来指定字段分隔符。字段分隔符的设置通常用于数据导入导出操作,而不是在创建表时定义。 ### 数据导入时使用字段分隔符 当从文本文件(如 CSV 文件)导入数据到 MySQL 表中时,可以使用 `LOAD DATA INFILE` 或 `mysqlimport` 工具,并在其中指定字段分隔符。例如: ```sql LOAD DATA INFILE '/path/to/data.csv' INTO TABLE your_table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS; ``` 在此示例中,`FIELDS TERMINATED BY ','` 指定了字段以逗号分隔[^1]。 ### 使用 `FIELDS TERMINATED BY` 的注意事项 - `FIELDS TERMINATED BY` 仅适用于 `LOAD DATA INFILE` 和 `SELECT ... INTO OUTFILE` 操作。 - 如果字段之间使用的是制表符(Tab),可以将分隔符设置为 `\t`。 - 确保文件中的字段顺序和类型与目标表的列匹配。 ### 存储过程中动态处理字段分隔符 如果需要在存储过程中动态控制字段分隔符,可以通过构造 SQL 语句并执行预处理语句来实现。例如: ```sql DELIMITER $$ CREATE PROCEDURE ImportDataWithDelimiter(IN delimiterChar VARCHAR(5)) BEGIN SET @sql = CONCAT('LOAD DATA INFILE ''/path/to/data.csv'' INTO TABLE your_table FIELDS TERMINATED BY ''', delimiterChar, ''' LINES TERMINATED BY ''\\n'' IGNORE 1 ROWS'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END $$ DELIMITER ; ``` 调用该存储过程时,可以传入不同的分隔符字符: ```sql CALL ImportDataWithDelimiter(','); ``` ### 字段分隔符与 `CREATE TABLE` 虽然不能在 `CREATE TABLE` 中直接设置字段分隔符,但可以在设计表结构时确保其与外部数据源的格式一致。例如,若要导入的数据是以分号 `;` 分隔的,则表的列定义应与该格式对应: ```sql CREATE TABLE example_table ( id INT PRIMARY KEY, name VARCHAR(255), age INT ); ``` 然后,在导入数据时再指定分隔符: ```sql LOAD DATA INFILE '/path/to/data.csv' INTO TABLE example_table FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n'; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值