mysql find_in_set 能,有没有类似mysql的find
一、oracle***有没有类似mysql的find***in***set功能
楼上的说法不错:将该字段进行某种函数的处理后进行排序。
但这里的数据看上去似乎没有什么函数关系。
MYSQL的这个功能不错,可惜在ORACLE里没有见过。
既然是用户自己的排序方法,那么感觉这个问题更偏重于应用逻辑。
一个思路:自己建立一个排序字段(PX),录入信息的时候,用户可以决定该条记录的排序等级(自动、手动填写该字段都可以)。应用的时候可以按照这个字段进行排序。这里是用户指定的排序方式,以后要调整顺序时,修改这个排序字段的值就可以了。
二、mysql 与oracle中的存储过程及函数有什么区别,尽可能详细哦
本质上没区别。只是函数有如:只能返回一个变量的限制。而存储过程可以返回多个。而函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行。执行的本质都一样。
函数限制比较多,比如不能用临时表,只能用表变量.还有一些函数都不可用等等.而存储过程的限制相对就比较少
由于我现在基本上是DBA的工作,因此平时也看一些数据库方面的书籍。但是我一直对存储过程和函数之间的区别掌握不透。我向来认为存储过程可以实现的*作,函数也一样可以实现。近,刚好大学的老师给我们上SQL-Server的课程,我对这个问题的疑惑终于慢慢解开。今天晚上顺便看了些网上的资料,觉得以下分析比较合理:
1.一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
2.对于存储过程来说可以返回参数,而函数只能返回值或者表对象。
3.存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
4.当存储过程和函数被执行的时候,SQL Manager会到procedure cache中去取相应的查询语句,如果在procedure cache里没有相应的查询语句,SQL Manager就会对存储过程和函数进行编译。
Procedure cache中保存的是执行计划(execution plan),当编译好之后就执行procedure cache中的execution plan,之后SQL SERVER会根据每个execution plan的实际情况来考虑是否要在cache中保存这个plan,评判的标准一个是这个execution plan可能被使用的频率;其次是生成这个plan的代价,也就是编译的耗时。保存在cache中的plan在下次执行时就不用再编译了。
存储过程和用户自定义函数具体的区别
存储过程
存储过程可以使得对数据库的管理、以及显示关于数据库及其用户信息的工作容易得多。存储过程是 SQL语句和可选控制流语句的预编译**,以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量、有条件执行以及其它强大的编程功能。
存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数、输出参数、返回单个或多个结果集以及返回值。
可以出于任何使用 SQL语句的目的来使用存储过程,它具有以下优点:
可以在单个存储过程中执行一系列 SQL语句。
可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。
存储过程在创建时即在服务器上进行编译,所以执行起来比单个 SQL语句快。
用户定义函数
函数是由一个或多个 Transact-SQL语句组成的子程序,可用于封装代码以便重新使用。Microsoft? SQL Server? 2000并不将用户限制在定义为 Transact-SQL语言一部分的内置函数上,而是允许用户创建自己的用户定义函数。
可使用 CREATE FUNCTION语句创建、使用 ALTER FUNCTION语句修改、以及使用 DROP FUNCTION语句除去用户定义函数。每个完全合法的用户定义函数名(database_name.owner_name.function_name)必须唯一。
必须被授予 CREATE FUNCTION权限才能创建、修改或除去用户定义函数。不是所有者的用户在 Transact-SQL语句中使用某个函数之前,必须先给此用户授予该函数的适当权限。若要创建或更改在 CHECK约束、DEFAULT子句或计算列定义中引用用户定义函数的表,还必须具有函数的 REFERENCES权限。
函数中的有效语句类型包括:
DECLARE语句,该语句可用于定义函数局部的数据变量和游标。
为函数局部对象赋值,如使用 SET给标量和表局部变量赋值。
游标*作,该*作引用在函数中声明、打开、关闭和释放的局部游标。不允许使用 FETCH语句将数据返回到客户端。仅允许使用 FETCH语句通过 INTO子句给局部变量赋值。
控制流语句。
SELECT语句,该语句包含带有表达式的选择列表,其中的表达式将值赋予函数的局部变量。
INSERT、UPDATE和 DELETE语句,这些语句修改函数的局部 table变量。
EXECUTE语句,该语句调用扩展存储过程。
在查询中指定的函数的实际执行次数在优化器生成的执行计划间可能不同。示例为 WHERE子句中的子查询唤醒调用的函数。子查询及其函数执行的次数会因优化器选择的访问路径而异
三、数据库mysql创建表格老是出错,看不懂英文提示
来自:51CTO(作者:superZS)
我在刚开始学习数据库的时候,没少走弯路。经常会遇到各种稀奇古怪的 error信息,遇到报错会很慌张,急需一个解决问题的办法。跟无头苍蝇一样,会不加思索地把错误粘到百度上,希望赶紧查找一下有没有好的处理问题的方法。我想这个应该是刚从事数据库的小白,都会遇到窘境。
今天就给大家列举 MySQL数据库中,经典的十大错误案例,并附有处理问题的解决思路和方法,希望能给刚入行,或数据库爱好者一些帮助,今后再遇到任何报错,我们都可以很淡定地去处理。
学习任何一门技术的同时,其实就是自我修炼的过程。沉下心,尝试去拥抱数据的世界!
Top 1:
Too many connections(连接数过多,导致连接不上数据库,业务无**常进行)
问题还原
解决问题的思路:
1、首先先要考虑在我们 MySQL数据库参数文件里面,对应的 max_connections这个参数值是不是设置的太小了,导致客户端连接数超过了数据库所承受的大值。
●该值默认大小是151,我们可以根据实际情况进行调整。
●对应解决办法:set global max_connections=500
但这样调整会有隐患,因为我们无法确认数据库是否可以承担这么大的连接压力,就好比原来一个人只能吃一个馒头,但现在却非要让他吃 10个,他肯定接受不了。反应到服务器上面,就有可能会出现宕机的可能。
所以这又反应出了,我们在新上线一个业务系统的时候,要做好压力测试。保证后期对数据库进行优化调整。
2、其次可以限制 Innodb的并发处理数量,如果 innodb_thread_concurrency= 0(这种代表不受限制)可以先改成 16或是64看服务器压力。如果非常大,可以先改的小一点让服务器的压力下来之后,然后再慢慢增大,根据自己的业务而定。个人建议可以先调整为 16即可。
MySQL随着连接数的增加性能是会下降的,可以让开发配合设置 thread pool,连接复用。在MySQL商业版中加入了thread pool这项功能
另外对于有的监控程序会读取 information_schema下面的表,可以考虑关闭下面的参数
innodb_stats_on_metadata=0
set global innodb_stats_on_metadata=0
Top 2:(主从**报错类型)
Last_SQL_Errno: 1062(从库与主库数据冲突)
Last_Errno: 1062
Last_Error: Could not execute Write_rows event on table test.t;
Duplicate entry'4' for key'PRIMARY',
Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY;
the event's master log mysql-**n.000014, end_log_pos 1505
针对这个报错,我们首先要考虑是不是在从库中误*作导致的。结果发现,我们在从库中进行了一条针对有主键表的 sql语句的插入,导致主库再插入相同 sql的时候,主从状态出现异常。发生主键冲突的报错。
解决方法:
在确保主从数据一致性的前提下,可以在从库进行错误跳过。一般使用 percona-toolkit中的 pt-slave-restart进行。
在从库完成如下*作
[root@zs **n]#./pt-slave-restart-uroot-proot123
2017-07-20T14:05:30 p=...,u=root node4-relay-**n.000002 1506 1062
之后好在从库中开启 read_only参数,禁止在从库进行写入*作
Last_IO_Errno: 1593(server-id冲突)
Last_IO_Error:
Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids;
these ids must be different for replication to work
(or the--replicate-same-server-id option must be used on slave but this
does not always make sense; please check the manual before using it)
这个报错出现之后,就看一目了然看到两台机器的 server-id是一样的。
在搭建主从**的过程中,我们要确保两台机器的 server-id是唯一的。这里再强调一下 server-id的命名规则(服务器 ip地址的后一位+本 MySQL服务的端口号)
解决方法:
在主从两台机器上设置不同的 server-id。
Last_SQL_Errno: 1032(从库少数据,主库更新的时候,从库报错)
Last_SQL_Error:
Could not execute Update_rows event on table test.t; Can't find record
in't', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the
event's master log mysql-**n.000014, end_log_pos 1708
解决问题的办法:
根据报错信息,我们可以获取到报错日志和position号,然后就能找到主库执行的哪条sql,导致的主从报错。
在主库执行:
/usr/local/mysql/**n/mysql**nlog--no-defaults-v-v--base64-output=decode-rows/data/mysql/mysql-**n.000014|grep-A 10 1708> 1.log
cat 1.log
#170720 14:20:15 server id 3 end_log_pos 1708 CRC32 0x97b6bdec Update_rows: table id 113 flags: STMT_END_F
### UPDATE `test`.`t`
### WHERE
###@1=4/* INT meta=0 nullable=0 is_null=0*/
###@2='dd'/* VARSTRING(60) meta=60 nullable=1 is_null=0*/
### SET
###@1=4/* INT meta=0 nullable=0 is_null=0*/
###@2='ddd'/* VARSTRING(60) meta=60 nullable=1 is_null=0*/
# at 1708
#170720 14:20:15 server id 3 end_log_pos 1739 CRC32 0xecaf1922 Xid= 654
COMMIT/*!*/;
DELIMITER;
# End of log file
ROLLBACK/* added by mysql**nlog*/;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET@@SESSION.PSEUDO_SL**E_MODE=0*/;
获取到 sql语句之后,就可以在从库反向执行 sql语句。把从库缺少的 sql语句补全,解决报错信息。
在从库依次执行:
mysql> insert into t(b) values('ddd');
Query OK, 1 row affected(0.01 sec)
mysql> stop slave;
Query OK, 0 rows affected(0.00 sec)
mysql> exit
Bye
[root@node4 **n]#./pt-slave-restart-uroot-proot123
2017-07-20T14:31:37 p=...,u=root node4-relay-**n.000005 283 1032
Top 3:MySQL安装过程中的报错
[root@zs data]#/usr/local/mysql/**n/mysqld_safe--defaults-file=/etc/myf&[1] 3758
[root@zs data]# 170720 14:41:24 mysqld_safe Logging to'/data/mysql/error.log'.
170720 14:41:24 mysqld_safe Starting mysqld daemon with databases from/data/mysql170720
14:41:25 mysqld_safe mysqld from pid file/data/mysql/node4.pid ended
170720 14:41:24 mysqld_safe Starting mysqld daemon with databases from/data/mysql2017-07-20
14:41:25 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated.
Please use--explicit_defaults_for_timestamp server option
(see documentation for more details)./usr/local/mysql/**n/mysqld:
File'/data/mysql/mysql-**n.index' not found(Errcode: 13- Permission denied)
2017-07-20 14:41:25 4388 [ERROR] Aborting
解决思路:
遇到这样的报错信息,我们要学会时时去关注错误日志 error log里面的内容。看见了关键的报错点 Permission denied。证明当前 MySQL数据库的数据目录没有权限。
解决方法:
[root@zs data]# chown mysql:mysql-R mysql
[root@zs data]#/usr/local/mysql/**n/mysqld_safe--defaults-file=/etc/myf&
[1] 4402
[root@zs data]# 170720 14:45:56 mysqld_safe Logging to'/data/mysql/error.log'.
170720 14:45:56 mysqld_safe Starting mysqld daemon with databases from/data/mysql
启动成功。
如何避免这类问题,个人建议在安装 MySQL初始化的时候,一定加上--user=mysql,这样就可以避免权限问题。
./mysql_install_db--basedir=/usr/local/mysql/--datadir=/data/mysql/--defaults-file=/etc/myf--user=mysql
Top 4:数据库密码忘记的问题
[root@zs~]# mysql-uroot-p
Enter password:
ERROR 1045(28000): Access denied for user'root'@'localhost'(using password: YES)
[root@zs~]# mysql-uroot-p
Enter password:
ERROR 1045(28000): Access denied for user'root'@'localhost'(using password: YES)
我们有可能刚刚接手别人的 MySQL数据库,而且没有完善的交接文档。root密码可以丢失或者忘记了。
解决思路:
目前是进入不了数据库的情况,所以我们要考虑是不是可以跳过权限。因为在数据库中,mysql数据库中user表记录着我们用户的信息。
解决方法:
启动 MySQL数据库的过程中,可以这样执行:
/usr/local/mysql/**n/mysqld_safe--defaults-file=/etc/myf--skip-grant-tables&
这样启动,就可以不用输入密码,直接进入 mysql数据库了。然后在修改你自己想要改的root密码即可。
update mysql.user set password=password('root123') where user='root';
Top 5:truncate删除数据,导致自动清空自增ID,前端返回报错 not found。
这个问题的出现,就要考虑下 truncate和 delete的区别了。
看下实验演练:
首先先创建一张表;
CREATE TABLE `t`(
`a` int(11) NOT NULL AUTO_INCREMENT,
`b` varchar(20) DEFAULT NULL,
PRIMARY KEY(`a`),
KEY `b`(`b`)
) ENGINE=InnoDB AUTO_INCREMENT=300 DEFAULT CHARSET=utf8
插入三条数据:
mysql> insert into t(b) values('aa');
Query OK, 1 row affected(0.00 sec)
mysql> insert into t(b) values('bb');
Query OK, 1 row affected(0.00 sec)
mysql> insert into t(b) values('cc');
Query OK, 1 row affected(0.00 sec)
mysql> select* from t;
+-----+------+
| a| b|
+-----+------+
| 300| aa|
| 301| bb|
| 302| cc|
+-----+------+
3 rows in set(0.00 sec)
先用 delete进行删除全表信息,再插入新值。
结果发现 truncate把自增初始值重置了,自增属性从1开始记录了。当前端用主键id进行查询时,就会报没有这条数据的错误。
个人建议不要使用 truncate对表进行删除*作,虽然可以回收表空间,但是会涉及自增属性问题。这些坑,我们不要轻易钻进去。
Top 6:
阿里云 MySQL的配置文件中,需要注意一个参数设置就是:
lower_case_table_names= 0;默认情况
lower_case_table_names= 1;是不区分大小写.如果报你小写的表名找不到,那你就把远端数据库的表名改成小写,反之亦然.注意 Mybatis的 Mapper文件的所有表名也要相应修改
Top 7:
有同学经常会问张老师,为什么我的数据库总会出现中文*码的情况。一堆????不知道怎么回事。当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。
解决思路:
对于中文*码的情况,记住老师告诉你的三个统一就可以。还要知道在目前的mysql数据库中字符集编码都是默认的UTF8
处理办法:
1、数据终端,也就是我们连接数据库的工具设置为 utf8
2、*作系统层面;可以通过 cat/etc/sysconfig/i18n查看;也要设置为 utf8
3、数据库层面;在参数文件中的 mysqld下,加入 character-set-server=utf8。
Emoji表情符号录入 mysql数据库中报错。
Caused by: java.sql.SQLException: Incorrect string value:'\xF0\x9F\x98\x97\xF0\x9F...' for column'CONTENT' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)
解决思路:针对表情插入的问题,一定还是字符集的问题。
处理方法:我们可以直接在参数文件中,加入
vim/etc/myf
[mysqld]
init-connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
注:utf8mb4是 utf8的超集。
Top 8:使用 **nlog_format=statement这种格式,跨库*作,导致从库丢失数据,用户访问导致出现错误数据信息。
当前数据库二进制日志的格式为:**nlog_format=statement
在主库设置**nlog-do-db=mydb1(只同步mydb1这一个库)
在主库执行use mydb2;
insert into mydb1.t1 values('bb');这条语句不会同步到从库。
但是这样*作就可以;
use mydb1;
insert into mydb1.t1 values('bb');因为这是在同一个库中完成的*作。
在生产环境中建议使用**nlog的格式为row,而且慎用**nlog-do-db参数。
Top 9:MySQL数据库连接超时的报错;
org.hibernate.util.JDBCExceptionReporter- SQL Error:0, SQLState: 08S01
org.hibernate.util.JDBCExceptionReporter- The last packet successfully received from the server was43200 milliseconds ago.The last packet sent successfully to the server was 43200 milliseconds ago, which is longer than the server configured value of'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection'autoReconnect=true' to avoid this problem.
org.hibernate.event.def.AbstractFlushingEventListener- Could not synchronize database state with session
org.hibernate.exception.JDBCConnectionException: Could not execute JDBC batch update
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
org.hibernate.util.JDBCExceptionReporter- SQL Error:0, SQLState: 08003
org.hibernate.util.JDBCExceptionReporter- No operations allowed after connection closed. Connection was implicitly closed due to underlying exception/error:
** BEGIN NESTED EXCEPTION**
大多数做 DBA的同学,可能都会被开发人员告知,你们的数据库报了这个错误了。赶紧看看是哪里的问题。
这个问题是由两个参数影响的,wait_timeout和 interactive_timeout。数据默认的配置时间是28800(8小时)意味着,超过这个时间之后,MySQL数据库为了节省资源,就会在数据库端断开这个连接,Mysql服务器端将其断开了,但是我们的程序再次使用这个连接时没有做任何判断,所以就挂了。
解决思路:
先要了解这两个参数的特性;这两个参数必须同时设置,而且必须要保证值一致才可以。
我们可以适当加大这个值,8小时太长了,不适用于生产环境。因为一个连接长时间不工作,还占用我们的连接数,会消耗我们的系统资源。
解决方法:
可以适当在程序中做判断;强烈建议在*作结束时更改应用程序逻辑以正确关闭连接;然后设置一个比较合理的timeout的值(根据业务情况来判断)
Top 10:can't open file(errno:24)
有的时候,数据库跑得好好的,突然报不能打开数据库文件的错误了。
解决思路:
首先我们要先查看数据库的 error log。然后判断是表损坏,还是权限问题。还有可能磁盘空间不足导致的不能正常访问表;*作系统的限制也要关注下;用 perror工具查看具体错误!
linux:/usr/local/mysql/**n#./perror 24
OS error code 24: Too many open files
超出大打开文件数限制!ulimit-n查看系统的大打开文件数是65535,不可能超出!那必然是数据库的大打开文件数超出限制!
在 MySQL里查看大打开文件数限制命令:show variables like'open_files_limit';
发现该数值过小,改为2048,重启 MySQL,应用正常
处理方法:
repair table;
chown mysql权限
清理磁盘中的垃圾数据