0

1 つの UPDATE クエリで 2 つのテーブルを更新したいと考えています。そのために単純な LEFT JOIN を使用します。不思議なことに、一致するすべての行が変更されるわけではありません。これはテーブルの例です:

DROP TABLE IF EXISTS `test_continents`, `test_agents`;

CREATE TABLE IF NOT EXISTS `test_continents` (
  `key` char(2) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;

INSERT INTO `test_continents` (`key`) VALUES('EU');
INSERT INTO `test_continents` (`key`) VALUES('NA');


CREATE TABLE IF NOT EXISTS `test_agents` (
  `name` char(64) COLLATE utf8_unicode_ci NOT NULL,
  `continent` char(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`name`),
  KEY `continent` (`continent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;

INSERT INTO `test_agents` (`name`, `continent`) VALUES('006', 'EU');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('007', 'EU');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('008', 'NA');
INSERT INTO `test_agents` (`name`, `continent`) VALUES('009', 'NA');

OPTIMIZE TABLE `test_continents`, `test_agents`;

これはサンプルの SELECT クエリで、すべての行に一致します。

SELECT

`test_agents`.`continent`,
`test_agents`.`name`

FROM `test_continents`

LEFT JOIN `test_agents` ON (
    `test_agents`.`continent` = `test_continents`.`key`
)

WHERE

`test_continents`.`key` = 'NA'

これは UPDATE クエリです。

UPDATE `test_continents`

LEFT JOIN `test_agents` ON (
    `test_agents`.`continent` = `test_continents`.`key`
)

SET

`test_continents`.`key` = 'SA',
`test_agents`.`continent` = `test_continents`.`key`

WHERE

`test_continents`.`key` = 'NA'

更新後、テーブルは次のようになります。

テスト大陸:

key
EU
SA

テストエージェント:

name   continent
006    EU
007    EU
008    SA
009    NA

更新後、test_agent 009 の大陸フィールドがまだ「NA」のままである理由を誰か説明できますか?

INT フィールドを使用する場合、これは発生しないようですが、CHAR(2) フィールドが必要なので、テーブル構造については議論しないでください。これはバグ、機能、またはその他のものであるとだけ言ってください。

私はUbuntu 12.04とMySQL 5.5.29-1〜dotdeb.0を使用しています。私は15年以上コーダーであり、通常はそのようなお粗末な質問はしませんが、説明することはできず、助けが必要です...

アップデート:

CHAR(2) の代わりに INT(2) フィールドを使用して 2 番目の例を作成しました。この場合、UPDATE はすべての行に一致します。

CREATE TABLE IF NOT EXISTS `test_agents` (
  `name` char(64) COLLATE utf8_unicode_ci NOT NULL,
  `continent` int(2) NOT NULL DEFAULT '0',
  PRIMARY KEY (`name`),
  KEY `continent` (`continent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;

INSERT INTO `test_agents` (`name`, `continent`) VALUES('006', 1);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('007', 1);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('008', 2);
INSERT INTO `test_agents` (`name`, `continent`) VALUES('009', 2);

CREATE TABLE IF NOT EXISTS `test_continents` (
  `key` int(2) NOT NULL,
  PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED;

INSERT INTO `test_continents` (`key`) VALUES(1);
INSERT INTO `test_continents` (`key`) VALUES(2);

--

SELECT

`test_agents`.`continent`,
`test_agents`.`name`

FROM `test_continents`

LEFT JOIN `test_agents` ON (
    `test_agents`.`continent` = `test_continents`.`key`
)

WHERE

`test_continents`.`key` = 2

--

UPDATE `test_continents`

LEFT JOIN `test_agents` ON (
    `test_agents`.`continent` = `test_continents`.`key`
)

SET

`test_continents`.`key` = 3,
`test_agents`.`continent` = `test_continents`.`key`

WHERE

`test_continents`.`key` = 2

更新後の test_agents:

name   continent
006    1
007    1
008    3
009    3

--

これが正常な動作だとは信じられません。両方の例の唯一の違いはフィールド タイプであるため、同じ行に影響するかどうか? クエリは 100% 正しいと確信しています。

誰か説明がありますか?

前もって感謝します。

4

0 に答える 0