2015-09-01 19 views
5

的,我想插入我想要實現的紅移 的SCD2但得到一個錯誤的記錄。列的類型是時間戳的無時區,但表達的類型是性格

目標表的DDL是

CREATE TABLE ditemp.ts_scd2_test (
    id INT 
    ,md5 CHAR(32) 
    ,record_id BIGINT IDENTITY 
    ,from_timestamp TIMESTAMP 
    ,to_timestamp TIMESTAMP 
    ,file_id BIGINT 
    ,party_id BIGINT 
    ) 

這是插入語句:

INSERT 
INTO ditemp.TS_SCD2_TEST(id, md5, from_timestamp, to_timestamp) 

SELECT TS_SCD2_TEST_STAGING.id 
    ,TS_SCD2_TEST_STAGING.md5 
    ,from_timestamp 
    ,to_timestamp 
FROM (
    SELECT '20150901 16:34:02' AS from_timestamp 
     ,CASE 
      WHEN last_record IS NULL 
       THEN '20150901 16:34:02' 
      ELSE '39991231 11:11:11.000' 
      END AS to_timestamp 
     ,CASE 
      WHEN rownum != 1 
       AND atom.id IS NOT NULL 
       THEN 1 
      WHEN atom.id IS NULL 
       THEN 1 
      ELSE 0 
      END AS transfer 
     ,stage.* 
    FROM (
     SELECT id 
     FROM ditemp.TS_SCD2_TEST_STAGING 
     WHERE file_id = 2 
     GROUP BY id 
     HAVING count(*) > 1 
     ) AS scd2_count_ge_1 
    INNER JOIN (
     SELECT row_number() OVER (
       PARTITION BY id ORDER BY record_id 
       ) AS rownum 
      ,stage.* 
     FROM ditemp.TS_SCD2_TEST_STAGING AS stage 
     WHERE file_id IN (2) 
     ) AS stage 
     ON (scd2_count_ge_1.id = stage.id) 
    LEFT JOIN (
     SELECT max(rownum) AS last_record 
      ,id 
     FROM (
      SELECT row_number() OVER (
        PARTITION BY id ORDER BY record_id 
        ) AS rownum 
       ,stage.* 
      FROM ditemp.TS_SCD2_TEST_STAGING AS stage 
      ) 
     GROUP BY id 
     ) AS last_record 
     ON (
       stage.id = last_record.id 
       AND stage.rownum = last_record.last_record 
       ) 
    LEFT JOIN ditemp.TS_SCD2_TEST AS atom 
     ON (
       stage.id = atom.id 
       AND stage.md5 = atom.md5 
       AND atom.to_timestamp > '20150901 16:34:02' 
       ) 
    ) AS TS_SCD2_TEST_STAGING 
WHERE transfer = 1 

和短的事情了,我試圖插入20150901 16:34:02from_timestamp39991231 11:11:11.000to_timestamp

,並得到

ERROR: 42804: column "from_timestamp" is of type timestamp without time zone but expression is of type character varying

任何人都可以請建議如何解決這個問題呢?

回答

4

的Postgres不能識別20150901 16:34:02(你的輸入)作爲有效時間/日期格式,所以它假定它是一個字符串。

改爲使用標準日期格式,最好是ISO-8601。 2015-09-01T16:34:02

SQLFiddle example

2

萬一有人在這裏結束了試圖插入到PostgreSQL中的timestamp或從一個變量在Groovy或Java中的timestampz從一個準備好的聲明,並得到同樣的錯誤(像我一樣),我設法將stringtype設置爲"unspecified"。根據documentation

指定類型時結合的PreparedStatement參數經由了setString設置 使用()。如果stringtype設置爲VARCHAR(默認值),那麼這些參數將作爲varchar參數發送到服務器。如果 stringtype設置爲未指定,參數將作爲非類型值發送到 服務器,服務器將嘗試推斷適當的類型。如果你有一個使用了setString()來設置實際上是一些其他的 類型的參數,如整數現有的應用程序 這是非常有用的,你是無法更改應用程序 使用適當的方法,如SETINT()。

Properties props = [user : "user", password: "password", 
driver:"org.postgresql.Driver", stringtype:"unspecified"] 
def sql = Sql.newInstance("url", props) 

帶有此屬性,您可以插入一個時間戳作爲一個字符串變量沒有在問題的標題引發的錯誤。例如:

String myTimestamp= Instant.now().toString() 
sql.execute("""INSERT INTO MyTable (MyTimestamp) VALUES (?)""", 
[myTimestamp.toString()] 

這樣,timegamp的類型(來自String)由postgresql正確地推斷出來。我希望這有幫助。

+1

幫我。謝謝。 – jeffcook2150

相關問題