2014-06-09 184 views
1

「沒有這樣的欄目」我直接看sqlite documentation for the UPDATE statement,和我有一些SQL我認爲符合規定的語法:與UPDATE語句

CREATE TEMPORARY TABLE x (y INTEGER); 
INSERT into x SELECT value FROM table WHERE id IN (6,7,12,15) ORDER by value ASC; 
CREATE TEMPORARY TABLE z (y INTEGER); 
INSERT INTO z (y) VALUES (6),(7),(12),(15); 
WITH NewValues(f,g) AS 
    (SELECT a.y AS f,b.y AS g FROM 
     (SELECT rowid,y FROM x) AS a, 
     (SELECT rowid,y FROM z) as b 
    ON a.rowid==(1+b.rowid%4) 
    ) 
UPDATE table 
SET value = NewValues.g 
WHERE NewValues.f = table.id; 

但當我嘗試執行該語句,我得到的錯誤:

near "WITH": syntax error 

WITH之前的代碼是好的;如果我只是運行WITH的子選擇並刪除UPDATE的其餘部分,它會按照我的預期返回一個表。語法圖非常清楚地表明我可以將WITH置於語句的開頭。那麼我做錯了什麼?

更新: 我已經嘗試了給出的簡單examples之一:

WITH RECURSIVE 
    cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<1000000) 
SELECT x FROM cnt; 

,我只是從太出現語法錯誤!我的第一個想法可能是我沒有足夠新的sqlite版本,但我沒有看到它提到的最低版本的任何提及。

更新2: 我下載了最新的sqlite這是3.8.5,而我運行的是3.7.12。這固定了WITH語法錯誤,所以它似乎確實需要一個相當新的Sqlite版本。但我仍然得到:

no such column: q.g 

我不明白在查詢的上下文,因爲我已經定義了兩種方式。

+1

你確定你可以有一個在你的更新?它看起來不像我 –

+0

嘗試設置值= NewValues.v ...刪除從 –

+0

@MillieSmith是的,一旦我超過了「WITH」問題(顯然它*被引入3.7.12之後)我在'FROM'上得到了一個語法錯誤,所以我嘗試了你的建議,但現在我得到了「沒有這樣的列:NewValues.v」。 – Michael

回答

2

爲了引用WITH CTE,您需要從中選擇。

試試這個:

CREATE TEMPORARY TABLE x (y INTEGER); 
INSERT INTO X (y) VALUES (6),(7),(12),(15); 

CREATE TEMPORARY TABLE z (y INTEGER); 
INSERT INTO z (y) VALUES (6),(7),(12),(15); 


WITH NewValues(f,g) AS 
    (SELECT a.y AS f,b.y AS g FROM 
     (SELECT rowid,y FROM x) AS a, 
     (SELECT rowid,y FROM z) as b 
    ON a.rowid==(1+b.rowid%4) 
    ) 
UPDATE task 
SET value = (SELECT g FROM NewValues WHERE NewValues.f = task.id) 
WHERE id IN (SELECT f FROM NewValues); 
+0

但我仍然需要'WHERE'子句,因爲「UPDATE隻影響將WHERE子句表達式評估爲布爾表達式的結果爲真的那些行。」在你提供的語句中,它影響到所有行,有效地將'WITH'選擇中所有行上的'value'字段置零。 – Michael

+0

爲了澄清,我不確定'WHERE'子句應該是什麼......我也不能像現在那樣使用'NewValues.f',但我不知道如何將其改爲SELECT。 – Michael

+0

看起來我需要追加'WHERE table.id IN(SELECT f FROM q)' – Michael