Home > Mobile >  MYSQL ERROR CODE: 1288 - can't update with join statement
MYSQL ERROR CODE: 1288 - can't update with join statement

Time:01-06

Thanks for past help.

While doing an update using a join, I am getting the 'Error Code: 1288. The target table _____ of the UPDATE is not updatable' and figure out why. I can update the table with a simple update statement (UPDATE sales.customerABC Set contractID = 'x';) but can't using a join like this:

UPDATE (
    SELECT *                        #where '*' contains columns a.uniqueID and a.contractID
    FROM sales.customerABC
    WHERE contractID IS NULL
    ) as a
LEFT JOIN (
    SELECT uniqueID, contractID
    FROM sales.tblCustomers
    WHERE contractID IS NOT NULL
    ) as b
ON a.uniqueID = b.uniqueID
SET a.contractID = b.contractID;

If changing that update statement a SELECT such as:

SELECT * FROM (
    SELECT *
    FROM opwSales.dealerFilesCTS
    WHERE pcrsContractID IS NULL
    ) as a
LEFT JOIN (
    SELECT uniqueID, pcrsContractID
    FROM opwSales.dealerFileLoad
    WHERE pcrsContractID IS NOT NULL
    ) as b
ON a."Unique ID" = b.uniqueID;

the result table would contain these columns:

a.uniqueID, a.contractID, b.uniqueID, b.contractID
59682204,   NULL,       NULL,       NULL
a3e8e81d,   NULL,       NULL,       NULL
cfd1dbf9,   NULL,       NULL,       NULL
5ece009c,   ,           5ece009c,   B123
5ece0d04,   ,           5ece0d04,   B456
5ece7ab0,   ,           5ece7ab0,   B789
cfd21d2a,   NULL,       NULL,       NULL
cfd22701,   NULL,       NULL,       NULL
cfd23032,   NULL,       NULL,       NULL

I pretty much have all database privileges and can't find restrictions with the table reference data. Can't find much information online concerning the error code, either.

Thanks in advance guys.

CodePudding user response:

You cannot update a sub-select because it's not a "real" table - MySQL cannot easily determine how the sub-select assignment maps back to the originating table.

Try:

UPDATE customerABC
JOIN tblCustomers USING (uniqueID)
SET customerABC.contractID = tblCustomers.contractID
WHERE customerABC.contractID IS NULL AND tblCustomers.contractID IS NOT NULL

Notes:

  • you can use a full JOIN instead of a LEFT JOIN, since you want uniqueID to exist and not be null in both tables. A LEFT JOIN would generate extra NULL rows from tblCustomers, only to have them shot down by the clause requirement that tblCustomers.contractID be not NULL. Since they allow more stringent restrictions on indexes, JOINs tend to be more efficient than LEFT JOINs.
  • since the field has the same name in both tables you can replace ON (a.field1 = b.field1) with the USING (field1) shortcut.
  • you obviously strongly want a covering index with (uniqueID, customerID) on both tables to maximize efficiency
  • this is so not going to work unless you have "real" tables for the update. The "tblCustomers" may be a view or a subselect, but customerABC may not. You might need a more complicated JOIN to pull out a complex WHERE which might be otherwise hidden inside a subselect, if the original 'SELECT * FROM customerABC' was indeed a more complex query than a straight SELECT. What this boils down to is, MySQL needs a strong unique key to know what it needs to update, and it must be in a single table. To reliably update more than one table I think you need two UPDATEs inside a properly write-locked transaction.
  • Related