2016-04-25 4 views
1

In meinem iOS und Android-Projekten, habe ich eine SQLite-Tabelle, die etwa wie folgt aussieht:aktualisieren Textspalte basierend auf dem Inhalt mit einem einzigen Nachschlag in SQLite

id words 
----------- 
1  apple, banana, orange, peach, strawberry 
2  car, plane, orange 
3  sheep, car, plane, horse, cow 
.  ... 
. 
. 

Die words Spalte ist eine TEXT Spalte, die eine hält Komma abgegrenzte Liste von Wörtern.

Ich möchte die Wortliste einer bestimmten Zeile aktualisieren, indem Sie ein Wort an den Anfang der Liste hinzufügen. Die Liste sollte nicht mehr als 5 Einträge enthalten, daher würde ich auch das letzte Wort löschen.

Zum Beispiel, wenn ich row id 1 mit cherry Aktualisierung wurde dann würde ich

cherry, apple, banana, orange, peach 

bekomme Oder wenn ich das gleiche Update auf row id 2 tut, dann würde ich

cherry, car, plane, orange 

Meine Frage bekommen

Ich weiß, dass ich aq tun könnte Um die Zeile zu erhalten, bearbeiten Sie den Text und aktualisieren Sie dann die Zeile. Dies würde jedoch zwei Tabellennachschlagevorgänge erfordern, einen für die Abfrage und einen für die Aktualisierung. Ist dies mit einem einzelnen Update-Lookup möglich?

Ich weiß, dass es die replace() function gibt, aber ich ersetze hier nichts. Ich bin auch nicht einfach incrementing an integer. Ich habe nichts Offensichtliches in der SQLite core functions gesehen.

Antwort

3

Richtige Lösung

Die Worte Spalte eine Textspalte ist, die ein Komma deliminated Liste von Wörtern enthält.

1 NF. Spalte enthält atomare Daten. Normalisieren Sie das Schema, um sauberen Code und bessere Leistung zu erhalten.

Abhilfe Lösung:

SQLite nicht eingebaut in reverse Funktion hat, ist, warum es ein bisschen hässlich ist:

CREATE TABLE mytable(id INTEGER NOT NULL, words TEXT); 

INSERT INTO mytable(id,words) VALUES (1,'apple, banana, orange, peach, strawberry'); 
INSERT INTO mytable(id,words) VALUES (2,'car, plane, orange'); 
INSERT INTO mytable(id,words) VALUES (3,'sheep, car, plane, horse, cow'); 
INSERT INTO mytable(id,words) VALUES (4,'sheep, cherry, plane, horse, cow'); 

UPDATE mytable 
SET words = CASE 
      WHEN (LENGTH(words) - LENGTH(REPLACE(words, ',', ''))) < 4 
      THEN 'cherry, ' || words 
      ELSE SUBSTR('cherry, ' || words, 1, 
         LENGTH(words) + LENGTH('cherry, ') - 
         LENGTH(SUBSTR(SUBSTR(
         SUBSTR(SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), 
         INSTR(SUBSTR(SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), ',') + 1), 
         INSTR(SUBSTR(
         SUBSTR(SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), 
         INSTR(SUBSTR(SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), ',') + 1),',')+1)) -1 
        ) 
      END 
WHERE words NOT LIKE '%cherry%'; 

SELECT * FROM mytable; 

SqlFiddleDemo

machen mehr Allgemein müssen Sie cherry mit Ihrem Wert ändern.

Ausgang:

╔════╦══════════════════════════════════════╗ 
║ id ║    words     ║ 
╠════╬══════════════════════════════════════╣ 
║ 1 ║ cherry, apple, banana, orange, peach ║ 
║ 2 ║ cherry, car, plane, orange   ║ 
║ 3 ║ cherry, sheep, car, plane, horse  ║ 
║ 4 ║ sheep, cherry, plane, horse, cow  ║ 
╚════╩══════════════════════════════════════╝ 

Wie es funktioniert:

  • UPDATE ... WHERE words NOT LIKE '%cherry%'; keine Zeilen aktualisieren, die cherry bereits
  • SET words = CASE WHEN (LENGTH(words) - LENGTH(REPLACE(words, ',', ''))) < 4 wenn Anzahl von Trennzeichen (Komma) haben, ist niedriger als 4 nur Wert verketten zu string
  • Wenn die Anzahl der Kommas 4 ist, bedeutet das, dass es 5 Werte hat. In gewünschte Zeichenkette am Anfang, dann verwenden SUBSTRING von 1 zum letzten Komma

SQL Server Version zum Vergleich:

DECLARE @val VARCHAR(100) = 'cherry'; 

UPDATE mytable 
SET words = CASE 
      WHEN LEN(words)-LEN(REPLACE(words, ',', '')) < 4 THEN @val + ', ' + words 
      ELSE LEFT(@val + ', ' + words, 
         LEN(@val + ', ' + words) - CHARINDEX(',', REVERSE(words))) 
      END 
WHERE words NOT LIKE '%'+ @val +'%'; 

SELECT * FROM mytable; 

LiveDemo

+1

Wow, ich bin beeindruckt . Ich muss mehr darüber lernen, wie ich mein Schema normalisieren kann. – Suragch