2016-12-19 88 views
0

所以我有這個簡單的Oracle查詢返回我預期的記錄:ORA-01722無效的數字 - 表連接

SELECT to_number(substr(nr_key,5,4)) as numero 
FROM fattura_pa 
LEFT JOIN fattura_pa_status on status_id = id 
WHERE ute = 'BX' and length(nr_key) < 21 
and to_number(substr(nr_key,5,4)) = 88 

如果我將它轉換成:

SELECT * FROM ( 
    SELECT to_number(substr(nr_key,5,4)) as numero 
    FROM fattura_pa 
    LEFT JOIN fattura_pa_status on status_id = id 
    WHERE ute = 'BX' and length(nr_key) < 21 
) 
where numero = 88 

它給我的「ORA-01722無效號碼」 錯誤

我不能undrestand爲什麼,因爲我的 「NUMERO = 88」,實際上是一個數字...

最奇怪的是,如果我評論的加入,查詢再次運行:

SELECT * FROM ( 
    SELECT to_number(substr(nr_key,5,4)) as numero 
    FROM fattura_pa 
    --LEFT JOIN fattura_pa_status on status_id = id 
    WHERE ute = 'BX' and length(nr_key) < 21 
) 
where numero = 88 

和連接無關用TE「NUMERO」場...

至於問,我在這裏發佈表格:

CREATE TABLE "FE_ENGINE"."FATTURA_PA" 
    ( "UTE" VARCHAR2(2 BYTE) NOT NULL ENABLE, 
    "NR_KEY" VARCHAR2(21 BYTE) NOT NULL ENABLE, 
    "PROGRESSIVO_INVIO" VARCHAR2(20 BYTE) NOT NULL ENABLE, 
    "XML_CREATO" NUMBER(1,0) DEFAULT 0 NOT NULL ENABLE, 
    "XML_FILE_NAME" VARCHAR2(40 BYTE) NOT NULL ENABLE, 
    "POSIZIONE" NUMBER(4,0) DEFAULT 1 NOT NULL ENABLE, 
    "D3_FILE_NAME" VARCHAR2(40 BYTE) NOT NULL ENABLE, 
    "SPEDITA_IL" DATE, 
    "ACCETTATA_IL" DATE, 
    "ARCHIVIATA_IL" DATE, 
    "STATUS_ID" NUMBER(4,0) NOT NULL ENABLE, 
    "RIELABORARE" NUMBER(1,0) DEFAULT 0 NOT NULL ENABLE, 
    "ROW_INSTIME" DATE DEFAULT SYSDATE NOT NULL ENABLE, 
    "ROW_UPTIME" DATE, 
    "NR_KEY_OLD" VARCHAR2(20 BYTE), 
    CONSTRAINT "UQ_FATTURA_PA_FILE_NAME_POSIT" UNIQUE ("XML_FILE_NAME", "POSIZIONE") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
    TABLESPACE "D3_USR" ENABLE, 
    CONSTRAINT "FATTURA_PA_PK" PRIMARY KEY ("UTE", "NR_KEY", "PROGRESSIVO_INVIO") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
    TABLESPACE "D3_USR" ENABLE, 
    CONSTRAINT "FK_FATTURA_PA_FATTURA_PA_STATU" FOREIGN KEY ("STATUS_ID") 
     REFERENCES "FE_ENGINE"."FATTURA_PA_STATUS" ("ID") ENABLE 
    ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
    TABLESPACE "D3_USR" ; 

CREATE TABLE "FE_ENGINE"."FATTURA_PA_STATUS" 
    ( "ID" NUMBER(4,0) NOT NULL ENABLE, 
    "COD_STATUS" VARCHAR2(16 BYTE) NOT NULL ENABLE, 
    "DESC_STATUS" VARCHAR2(100 BYTE) NOT NULL ENABLE, 
    CONSTRAINT "PK_FATTURA_PA_STATUS" PRIMARY KEY ("ID") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
    TABLESPACE "D3_USR" ENABLE 
    ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
    TABLESPACE "D3_USR" ; 

有什麼想法嗎?

+2

[編輯]你的問題,並添加'創建table'所涉及表的語句。 [**格式**](http://stackoverflow.com/help/formatting)文本請,[無屏幕截圖](http://meta.stackoverflow.com/questions/285551/why-may-i-not -o -load-images-of-code-on-so-when-asked-question-285557#285557) –

+2

我相信其原因可能在於Oracle在三個查詢中使用的不同執行計劃;你可以請張貼計劃嗎? – Aleksej

+1

絕對是執行計劃。 'substr(nr_key,5,4)'不總是計算一個數字。不同的執行計劃會評估_every_記錄的表達式或僅記錄一部分記錄。短期來說,你需要確定哪些數據是問題。長期來看,你不應該在varchar字段中存儲數字。 –

回答

0

感謝我得到的建議,一些測試後,只有這樣我能得到它的工作是這樣的:

SELECT to_number(numero) FROM ( 
SELECT substr(nr_key,5,4) as numero 
FROM fattura_pa 
LEFT JOIN fattura_pa_status on status_id = id 
WHERE ute = 'BX' and length(nr_key) < 21 
) 
where numero = lpad('88',4,'0') 
+0

有很多有用的建議評論,例如'從選擇列表中刪除'to_number'。現在你所擁有的問題是,如果執行計劃發生變化(執行計劃等等,決定數據庫執行什麼操作以使其運行速度最快),那麼錯誤可能會再次出現。您不想將代碼放入可隨時中斷而不會發出警告的系統中。執行計劃可隨時根據行數或統計數據進行更改。 –

+0

換句話說,現在執行計劃決定在'select'之前評估'where',這意味着非數字記錄永遠不會到達select。但是,當你向表中添加行時,執行計劃可能會改變爲在'where'之前計算'select',然後它將'to_number'應用於每一行,並且你的查詢將會崩潰。所以簡短的答案是:從你的選擇中刪除'to_number'。 –

+0

我已將to_number移至「外部」選擇。我認爲現在子查詢中的位置必須在外部選擇之前完成(這保證了我的數值)。或者我錯了? – Maik

相關問題