使用sqoop將Oracle中數據按照日期、小時批量導入報錯與解決

這裏對使用sqoop將Oracle中的數據按照日期、小時批量導入數據報錯與解決做一個總結。

之前mysql導入數據過,那時候對於  --query  後的sql語句因爲涉及到日期與時間,如果是單引號的話則會跟外面的單引號衝突,導致錯誤,所以mysql中解決辦法就是裏面涉及日期與時間的字段改成雙引號即可。然後再弄Oracle時候,我也試着改成雙引號,並且因爲sqoop導入時候用到了where判斷,所以需要添加了 $CONDITIONS 條件:

sqoop import --connect jdbc:oracle:thin:@192.168.99.19:1521:jcxydb --username sjbzk --password sjbzk --driver oracle.jdbc.driver.OracleDriver --query 'select * from GXTS_MJSKXX where to_date(SKSJ,"yyyy-mm-dd HH24:mi:ss")>to_date(to_char(sysdate-1/24,"yyyy-mm-dd HH24"),"yyyy-mm-dd HH24:mi:ss") and to_date(SKSJ,"yyyy-mm-dd HH24:mi:ss")<to_date(to_char(sysdate,"yyyy-mm-dd HH24"),"yyyy-mm-dd HH24:mi:ss") and $CONDITIONS' --target-dir /user/jcxydb/GXTS_MJSKXX/$date_today/$hour --fields-terminated-by '\t' --lines-terminated-by '\n' --null-string '\\N' --null-non-string '\\N' --m 1;

結果報錯了,報錯信息:

20/04/09 14:07:05 INFO manager.SqlManager: Executing SQL statement: select * from GXTS_MJSKXX where to_date(SKSJ,"yyyy-mm-dd HH24:mi:ss")>to_date(to_char(sysdate-1/24,"yyyy-mm-dd HH24"),"yyyy-mm-dd HH24:mi:ss") and to_date(SKSJ,"yyyy-mm-dd HH24:mi:ss")<to_date(to_char(sysdate,"yyyy-mm-dd HH24"),"yyyy-mm-dd HH24:mi:ss") and  (1 = 0) 
20/04/09 14:07:05 ERROR manager.SqlManager: Error executing statement: java.sql.SQLException: ORA-00904: "yyyy-mm-dd HH24:mi:ss": invalid identifier

java.sql.SQLException: ORA-00904: "yyyy-mm-dd HH24:mi:ss": invalid identifier

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1051)
    at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1156)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3415)
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3460)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:776)
    at org.apache.sqoop.manager.SqlManager.execute(SqlManager.java:785)
    at org.apache.sqoop.manager.SqlManager.getColumnInfoForRawQuery(SqlManager.java:288)
    at org.apache.sqoop.manager.SqlManager.getColumnTypesForRawQuery(SqlManager.java:259)
    at org.apache.sqoop.manager.SqlManager.getColumnTypesForQuery(SqlManager.java:252).....

這裏報了 ORA-00904: "yyyy-mm-dd HH24:mi:ss": invalid identifier 錯誤。

因爲Oracle中需要使用單引號,我之前測試用的是單引號,但是因爲之前寫mysql時候單引號會報錯,所以我就改成了雙引號。如果雙引號直接複製到Oracle中測試也會報00904這個錯誤。

這就遇到一個問題了,如果就使用單引號呢,外面那個單引號就會報別的錯誤。如下:

然後我就自己開始瞎鼓搗:

A.比如單引號前面加個反引號.

B.在單引號前面加個單引號


當然這些都是不可以的。。。大家也不要這樣嘗試了。

然後想了想還是要裏面to_date這些一定要用單引號,那麼只能外面的–query的單引號改了,然後我講外面改成雙引號,則報了下面的這個錯誤:

這個錯誤跟我之前第一次使用不加$CONDITIONS一樣的錯,可是我這裏明明寫了的??

後面看了一篇博客,還有就是查了好幾個資料,使用sqoop中的-query要注意的坑:

“–query“:如果這裏SQL語句裏邊用過單引號了,那外邊必須要用雙引號;

  • 這裏的SQL假如直接使用 “FROM STORE“的話,是會報 table 找不見,或者不存在的,因爲使用“–query“的話沒有指定 Schema ,所以這裏必須使用 . 的形式。
  • where 後邊必須有 $CONDITIONS 條件,sqoop 運行的時候,看日誌發現sqoop 會在這裏插入(1=0)或(1=1)來控制這條語句的執行。外邊使用雙引號的話,$CONDITIONS 前邊需要加反斜槓 即:\$CONDITIONS。 Free form query in Sqoop Import with WHERE clause。

終於懂了需要在$CONDITIONS前面加上 "\",然後測試果然成功了。最後成功的代碼如下:

sqoop import --connect jdbc:oracle:thin:@192.168.99.19:1521:jcxydb --username sjbzk --password sjbzk --driver oracle.jdbc.driver.OracleDriver --query "SELECT * FROM GXTS_MJSKXX WHERE TO_DATE(SKSJ,'yyyy-mm-dd HH24:mi:ss')>TO_DATE(TO_DATE(sysdate-1/24,'yyyy-mm-dd HH24'),'yyyy-mm-dd HH24:mi:ss') AND TO_DATE(SKSJ,'yyyy-mm-dd HH24:mi:ss')<TO_DATE(TO_DATE(sysdate,'yyyy-mm-dd HH24'),'yyyy-mm-dd HH24:mi:ss') AND \$CONDITIONS" --target-dir /user/jcxydb/GXTS_MJSKXX/$date_today/$hour --fields-terminated-by '\t' --lines-terminated-by '\n' --null-string '\\N' --null-non-string '\\N' --m 1;


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章