Teil 2: Über 600 Gutscheine mit SQL korrigieren


Die Ausgangslage

Im Shop liefen rund 600 automatisch generierte Gutscheine, die vom ERP gesteuert wurden. Alle waren vom Typ „fester Warenkorb-Rabatt“ und sollten flexibel einsetzbar sein. Doch plötzlich funktionierten sie nicht mehr – obwohl technisch nichts an den Gutscheinen geändert wurde.

Der Grund: Einige Produkte waren als „nicht rabattfähig“ markiert. Wie ich in Teil 1 erklärt habe, blockiert WooCommerce in so einem Fall den gesamten Gutschein, auch wenn er korrekt eingerichtet ist.

Die Lösung bestand darin, bei den Prozentgutscheinen gezielt eine Ausschluss-Produktkategorie zu definieren, während die festen Rabattgutscheine weiterhin uneingeschränkt auf alle Produkte angewendet werden dürfen.

2. Gutscheine mit bestimmten Bedingungen filtern – Beispiel discount_type = 'percent'

SELECT p.ID, pm.meta_value AS discount_type
FROM wp_postmeta pm
JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.post_type = 'shop_coupon'
  AND pm.meta_key = 'discount_type'
  AND pm.meta_value = 'percent';

So bekommst du alle Prozent-Gutscheine – wichtig, um gezielt nur die zu verändern, die du brauchst.

3. Einen einzelnen Gutschein prüfen

Bevor du Massenupdates machst, teste an einem einzelnen Gutschein, z.B. mit ID 22951:

SELECT * FROM wp_postmeta 
WHERE post_id = 22951 
	AND meta_key = 'exclude_product_categories';

Variante A: Update vorhandener Meta-Eintrag

UPDATE wp_postmeta
SET meta_value = 'a:1:{i:0;i:454;}'
WHERE post_id = 22951
	AND meta_key = 'exclude_product_categories';

Variante B: Einfügen, falls noch nicht vorhanden

INSERT INTO wp_postmeta (post_id, meta_key, meta_value)
SELECT p.ID, 'exclude_product_categories', 'a:1:{i:0;i:454;}'
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id 
	AND pm.meta_key = 'exclude_product_categories'
WHERE p.post_type = 'shop_coupon'
  AND pm.post_id IS NULL
  AND p.ID = 22951;

🗄️ Was in der Datenbank passiert

In WooCommerce (bzw. WordPress) sind Coupons Custom Post Types vom Typ shop_coupon.
Die Einschränkungen (z. B. Ausschluss von Kategorien) werden über Post Meta gespeichert.

Relevante Tabellen:

SELECT p.ID, 'exclude_product_categories', 'a:1:{i:0;i:454;}'
FROM wpstg0_posts p
INNER JOIN wpstg0_postmeta pm_discount
  ON p.ID = pm_discount.post_id
  AND pm_discount.meta_key = 'discount_type'
  AND pm_discount.meta_value = 'percent'
WHERE p.post_type = 'shop_coupon'
  AND p.post_status = 'publish'
  -- AND p.ID = 56258 -- optional, für gezielte Auswahl
  AND NOT EXISTS ( -- verhindert Insertion und Doppelte Einträge
    SELECT 1
    FROM wpstg0_postmeta pm2
    WHERE pm2.post_id = p.ID
      AND pm2.meta_key = 'exclude_product_categories'
  );
  • wp_posts – enthält die Coupons selbst (post_type = 'shop_coupon')
  • wp_postmeta – enthält Meta-Felder wie exclude_product_categories
  • wp_term_taxonomy / wp_terms – enthält Kategorien
START TRANSACTION;

INSERT INTO wp_postmeta (post_id, meta_key, meta_value)
SELECT p.ID, 'exclude_product_categories', 'a:1:{i:0;i:127;}'
FROM wp_posts p
INNER JOIN wp_postmeta pm_discount
  ON p.ID = pm_discount.post_id
  AND pm_discount.meta_key = 'discount_type'
  AND pm_discount.meta_value = 'percent'
WHERE p.post_type = 'shop_coupon'
  AND p.post_status = 'publish'
  -- AND p.ID = 59601 -- optional, für einzelne Gutscheine
  AND NOT EXISTS ( -- verhindert Insertion und Doppelte Einträge
    SELECT 1
    FROM wp_postmeta pm2
    WHERE pm2.post_id = p.ID
      AND pm2.meta_key = 'exclude_product_categories'
  );
  
SELECT COUNT(*) FROM `wp_postmeta` WHERE `meta_key` 
= 'exclude_product_categories';

ROLLBACK;

--COMMIT

Inhaltsverzeichnis