用于为父行设置id的触发器

时间:2013-09-27 00:45:18

标签: mysql triggers

我确定我在这里犯了几件错事。让我设定目标。

我有一个简单的表格,其中包含以下列:

-----------------------------------------
id | name   | code | parentCode | parentId
1  | locOne | loc1 |            | 
2  | locTwo | loc2 | loc1       | (grab value of 1)
3  | locThr | loc3 | loc2       | (grab value of 2)

我想从csv文件导入名称,代码和parentCode。 id将自动输入

然后我希望可以编写一个触发器,它会将自动输入的id输入parentId列,从parentCode = code中获取id。

1)第一个问题 - 这可能吗?

我正在使用SequelPro,并尝试将此作为更新的触发器:

INSERT INTO location (parentId)
SELECT id
FROM location
WHERE parentCode=code

引发了错误:

  

无法写行

MySQL说:

  

无法更新存储的函数/触发器中的表'location',因为它是   已经被调用此存储函数/触发器的语句使用。

2)第二个问题 - 如何?

1 个答案:

答案 0 :(得分:1)

在MySQL中,您无法在已定义触发器的表上发出DML语句。 但您可以使用BEFORE触发器来更改正在插入或更新的值。

现在假设您的表的架构看起来像

CREATE TABLE location
(
  id int not null auto_increment primary key, 
  name varchar(128), 
  code varchar(128), 
  parentCode varchar(128), 
  parentId int
)

您的触发器可能看起来像

CREATE TRIGGER tg_bi_location
BEFORE INSERT ON location
FOR EACH ROW
  SET NEW.parentId = (SELECT id 
                        FROM location 
                       WHERE code = NEW.parentCode);

这是 SQLFiddle 演示


现在假设您的CSV文件看起来像

name,code,parentCode 
"locOne","loc1",
"locTwo","loc2","loc1"
"locThr","loc3","loc2"

您可以使用LOAD DATA INFILE批量加载数据

LOAD DATA INFILE '/path/to/your/file.csv'
INTO TABLE location
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n' -- or `\r\n` if it's Windows
IGNORE 1 LINES -- use this if your file contains a header line
(name, code, parentcode);