我正在创建一个存储函数,该函数应该在表中插入新行。该表中还有一个唯一列。
如何检查一切是否顺利,是否确实插入了行?
我如何才能准确地检查是否找到此唯一列(例如-尝试添加重复值)?
您可以检查LAST_INSERT_ID()函数和INSERT IGNORE。
如果INSERT IGNORE成功,则返回主键。让我们创建一个带有自动递增主键和名称上的唯一键的表。
use test
DROP TABLE IF EXISTS nametable;
CREATE TABLE nametable
(
id int not null auto_increment,
name varchar(20) not null,
primary key (id),
unique key (name)
);
DELIMITER $$
DROP FUNCTION IF EXISTS `test`.`InsertName` $$
CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT
BEGIN
INSERT IGNORE INTO test.nametable (name) VALUES (newname);
RETURN LAST_INSERT_ID();
END $$
DELIMITER ;
SELECT InsertName('rolando');
SELECT InsertName('rolando');
SELECT InsertName('pamela');
SELECT InsertName('pamela');
SHOW CREATE TABLE test.nametable\G
SELECT * FROM test.nametable;
这是正在运行的示例:
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS nametable;
Query OK, 0 rows affected (0.04 sec)
mysql> CREATE TABLE nametable
-> (
-> id int not null auto_increment,
-> name varchar(20) not null,
-> primary key (id),
-> unique key (name)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS `test`.`InsertName` $$
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT
-> BEGIN
-> INSERT IGNORE INTO test.nametable (name) VALUES (newname);
-> RETURN LAST_INSERT_ID();
-> END $$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> SELECT InsertName('rolando');
+-----------------------+
| InsertName('rolando') |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.03 sec)
mysql> SELECT InsertName('rolando');
+-----------------------+
| InsertName('rolando') |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (0.02 sec)
mysql> SELECT InsertName('pamela');
+----------------------+
| InsertName('pamela') |
+----------------------+
| 3 |
+----------------------+
1 row in set (0.02 sec)
mysql> SELECT InsertName('pamela');
+----------------------+
| InsertName('pamela') |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.03 sec)
mysql> SHOW CREATE TABLE test.nametable\G
*************************** 1. row ***************************
Table: nametable
Create Table: CREATE TABLE `nametable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SELECT * FROM test.nametable;
+----+---------+
| id | name |
+----+---------+
| 3 | pamela |
| 1 | rolando |
+----+---------+
2 rows in set (0.00 sec)
mysql>
如上例所示,您可以检查函数的返回值。返回值非零表示INSERT IGNORE运行良好。返回值为零表示键重复,而没有在mysqld中引入错误号。
这种方法的缺点是,由于在密钥重复的情况下插入INSERT IGNORE的尝试失败,因此您无法返回并使用ID 2和ID 4。
让我们尝试另一个示例,该示例使用INSERT而不使用LAST_INSERT_ID()进行不同的存储函数设置:
use test
DROP TABLE IF EXISTS nametable;
CREATE TABLE nametable
(
id int not null auto_increment,
name varchar(20) not null,
primary key (id),
unique key (name)
);
DELIMITER $$
DROP FUNCTION IF EXISTS `test`.`InsertName` $$
CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT
BEGIN
DECLARE rv INT;
SELECT COUNT(1) INTO rv FROM test.nametable WHERE name = newname;
IF rv = 0 THEN
INSERT INTO test.nametable (name) VALUES (newname);
END IF;
RETURN rv;
END $$
DELIMITER ;
SELECT InsertName('rolando');
SELECT InsertName('rolando');
SELECT InsertName('pamela');
SELECT InsertName('pamela');
SHOW CREATE TABLE test.nametable\G
SELECT * FROM test.nametable;
结果如下:
mysql> use test
Database changed
mysql> DROP TABLE IF EXISTS nametable;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE nametable
-> (
-> id int not null auto_increment,
-> name varchar(20) not null,
-> primary key (id),
-> unique key (name)
-> );
Query OK, 0 rows affected (0.10 sec)
mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS `test`.`InsertName` $$
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION `test`.`InsertName` (newname VARCHAR(20)) RETURNS INT
-> BEGIN
-> DECLARE rv INT;
-> SELECT COUNT(1) INTO rv FROM test.nametable WHERE name = newname;
-> IF rv = 0 THEN
-> INSERT INTO test.nametable (name) VALUES (newname);
-> END IF;
-> RETURN rv;
-> END $$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> SELECT InsertName('rolando');
+-----------------------+
| InsertName('rolando') |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (0.04 sec)
mysql> SELECT InsertName('rolando');
+-----------------------+
| InsertName('rolando') |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
mysql> SELECT InsertName('pamela');
+----------------------+
| InsertName('pamela') |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.03 sec)
mysql> SELECT InsertName('pamela');
+----------------------+
| InsertName('pamela') |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
mysql> SHOW CREATE TABLE test.nametable\G
*************************** 1. row ***************************
Table: nametable
Create Table: CREATE TABLE `nametable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> SELECT * FROM test.nametable;
+----+---------+
| id | name |
+----+---------+
| 2 | pamela |
| 1 | rolando |
+----+---------+
2 rows in set (0.00 sec)
mysql>
在此示例中,如果INSERT正常,则存储的函数将返回0,并在名称上带有重复键的情况下返回1。优势?不会浪费auto_increment的ID号。劣势?每次执行SELECT语句以检查表中已经存在的名称。
您可以选择要使用哪种方式处理重复键。第一种方法使mysqld处理INSERT
IGNORE的条件。第二种方法具有存储功能,该功能首先在INSERT之前检查重复密钥。
问题内容: 如何检查存储过程或查询是否仍在SQL Server中运行? 主意 我曾经想过要在过程开始时在哪里写日志,并在过程结束时将日志删除。 缺陷: 使用过程监控器 我希望能有一个可以合并为一个存储过程的解决方案和/或,作为输入,所以使用SQL Server的界面将无法正常工作跟踪程序或解决方案。 更新#1 用法示例: 该过程应该像 并在运行时(20秒内)返回true,然后在函数失败或系统重新启
问题内容: 在我的代码中的某些情况下,只有在定义了该函数的情况下,我最终才调用该函数,否则我不应该调用该函数。我怎样才能做到这一点? 提出此问题的另一种方法可能是:如何确定函数是否在运行时定义,如果是,则调用。 问题答案: 尽管其他答复是有用的建议(,函数指针等),但是您 不能编译 引用不存在的函数的C ++代码。至少必须 声明 函数;如果不是,您的代码将无法编译。如果没有任何内容(编译单元,某些
问题内容: 我在我的项目中使用JobService。运行良好。但有时服务停止了。它不会再次重新启动。因此,如果没有运行,我将尝试分层JobService。但是我不知道如何检查JobService是否已经运行。请让我知道如何检查JobService是否正在运行。 我的工作服务课程: 我的实用程序类: 开始: 停止: 问题答案: 我找到了解决方案。 使用此方法,我们可以检查jobService是否正在
问题内容: 如何检查Java中是否存在类的方法?将一个声明是好的做法呢? 问题答案: 我假设您要检查该方法。 您可以尝试以下方法: 这将不起作用,因为该方法将在编译时解决。 您确实需要使用反射。而且,如果您可以访问要调用的方法的源代码,则最好使用要调用的方法创建一个接口。 [更新]附加信息是:有一个接口可能存在两个版本,一个是旧版本(不包含所需方法),一个是新版本(具有所需方法)。基于此,我提出以
问题内容: 我需要帮助检查数据库中是否存在行。就我而言,该行包含一个电子邮件地址。我得到结果: 这是我当前正在使用的代码: 有没有更好的方法来检查MySQL中是否存在行(在我的情况下,检查MySQL中是否存在电子邮件)? 问题答案: 以下是经过尝试,测试和证明的检查行是否存在的方法。 (其中一些我自己使用,或者过去使用过)。 编辑: 我在使用两次的语法中犯了一个先前的错误。请查阅修订版本。 即:
我需要帮助检查数据库中是否存在行。在我的例子中,该行包含一个电子邮件地址。我得到的结果是: 这是我目前使用的代码: 有没有更好的方法来检查MySQL中是否存在行(在我的例子中,检查MySQL中是否存在电子邮件)?