0

MySQL 用に作成するソフトウェア アップグレード スクリプトがあります。

このアップグレードの一部には、既存のエンティティのテーブルに行を作成することが含まれます (ソフトウェアの新しいバージョンでは、新しい「親」エンティティに関連付けられた追加のエンティティが作成されますが、古いバージョンでは作成されなかったため、手動で作成する必要があります)。 . 子エンティティ ID は、自動インクリメントの代理キーではなく、命名規則に基づいて作成されます。

だから私はこの匿名化されたクエリを書いていました:

INSERT INTO CHILD_ENTITIES (CHILD_ID, DESCRIPTION, OBJECT_TYPE)
(SELECT 
    CONCAT('PRE_', PARENT_ID, '_SUFF') AS CHILD_ID,
    CONCAT('DESCRIPTION FOR ', PARENT_NAME) AS DESCRIPTION,
    'SYSTEM' AS OBJECT_TYPE
FROM
    PARENT_ENTITIES
WHERE
    CHILD_ID NOT IN (SELECT 
            CHILD_ID
        FROM
            CHILD_ENTITIES));

テーブル構造

CREATE TABLE `CHILD_ENTITIES` (
  `CHILD_ID` varchar(50) NOT NULL,
  `DESCRIPTION` varchar(200) DEFAULT NULL,
  `OBJECT_TYPE` varchar(20) NOT NULL,
  PRIMARY KEY (`CHILD_ID`)
)

クエリは、親テーブルからすべての親エンティティを選択し、行を操作して子エンティティの 3 つの列のみを取得し (FK 制約がないことに注意してください。これは DB 設計によるものです)、それらを子に挿入します。親ごとに、新しい子が作成されることになっています。このWHERE句は予防的なステートメントであり、実際には重複を避けるために書かれていますが、通常のセットアップではクエリが失敗しないと想定されていますWHERE(これらの ID は規則によって生成され、手動で挿入されることはないため)。

問題は、クエリMySQL 5.1.69-communityが期待どおりに正常に動作することですが、(問題が5.6.10あれば Navicat を使用して) 実行すると、動作が異なります。親エンティティが存在する場合、レコードは挿入されません。

数回試行してクエリを分析したところWHERE CHILD ID NOT IN ( SELECT CHILD_ID...、親の選択の列ではなく、サブクエリの列を参照して、誤解されていることがわかりました。クエリを少し変更すると

SELECT 
    CONCAT('PRE_', PARENT_ID, '_SUFF') AS CHILD_ID,
    CONCAT('DESCRIPTION FOR ', PARENT_NAME) AS DESCRIPTION,
    'SYSTEM' AS OBJECT_TYPE
FROM
    PARENT_ENTITIES
WHERE
    CHILD_ID NOT IN (SELECT 
            CHILD_ID AS DUMMY
        FROM
            CHILD_ENTITIES);

結果:Unknown column 'CHILD_ID' in 'IN/ALL/ANY subquery'

このエラーは、MySQL の両方のバージョンで発生します。

では、親の ID から始まる子エンティティを設定するために、このようなクエリを作成するにはどうすればよいでしょうか?

4

1 に答える 1

2

すべての列にテーブル プレフィックスを追加して、もう一度やり直すことをお勧めします。

INSERT INTO CHILD_ENTITIES (CHILD_ID, DESCRIPTION, OBJECT_TYPE)
SELECT 
    CONCAT('PRE_', p.PARENT_ID, '_SUFF') AS CHILD_ID,
    CONCAT('DESCRIPTION FOR ', p.PARENT_NAME) AS DESCRIPTION,
    'SYSTEM' AS OBJECT_TYPE
FROM
    PARENT_ENTITIES AS p
WHERE
    p.CHILD_ID NOT IN (SELECT 
            c.CHILD_ID
        FROM
            CHILD_ENTITIES AS c);

それもエラーで失敗する場合は、バグである可能性があります。最新 (5.6.13) バージョンにアップグレードし、エラーが続くかどうかを確認します。


クエリをもう一度読むと、重複を回避する方法がわかりません。もしかして、こう書きたかったのでは?

---
WHERE
    CONCAT('PRE_', p.PARENT_ID, '_SUFF') NOT IN (SELECT 
            c.CHILD_ID
        FROM
            CHILD_ENTITIES AS c);
于 2013-09-02T10:32:28.840 に答える