2011-10-27 9 views
2
String s1 = "create table " +tableName+ 
    "(id number NOT NULL PRIMARY KEY, " + 
    "url varchar(1000) NOT NULL, " + 
    "urlHash varchar(1000) NOT NULL, " + 
    "contentHash varchar(1000), " + 
    "modDate date, " + 
    "contentLocation varchar(1000), " + 
    "status integer, " + 
    "lastCrawlDate date) "; 

String s3 = "create sequence " +sequenceName+ " start with 1 increment by 1 nomaxvalue"; 

    stmt=conn.createStatement(); 
    stmt.executeUpdate(s1); 
    stmt.executeUpdate(s3); 

ps = conn.prepareStatement (
      "INSERT INTO testing (id, url, urlHash, contentHash, modDate, contentLocation, status, lastCrawlDate) VALUES(test_seq.nextval,?,?,?,?,?,?,?)"); 


      ps.setString (1, url); 
      ps.setString (2, urlHash); 
      ps.setString (3, contentHash); 
      ps.setString (4, modDate); 
      ps.setString (5, contentLocation); 
      ps.setLong (6, status); 
      ps.setString (7, lastCrawlDate); 

나는 자동 증가를 위해 테이블과 시퀀스를 생성합니다. 그런 다음 준비된 문을 사용하여 oracle 데이터베이스에 삽입합니다. 그리고이 테이블은 엄청난 양의 데이터를 약 20,000 개의 엔트리를 가지고 있습니다.오라클 SQL 그렇다면 다음과 같이하십시오. do else do do else

첫 번째 문제 : - 나는 URL을이 테이블에 존재하거나 있는지 확인하기 위해 테이블 ​​내에서 검색 할이 테이블에있는 URL 및 기타 해당 데이터를 추가해야하는 경우 그래서 지금은 무엇을해야 입니다 아니. 존재하지 않으면이 URL을 테이블 및 기타 해당 데이터에 추가하십시오. 그렇다면 이걸 어떻게 달성 할 수 있습니까? 다음은 그렇지 않으면 oracle sql의 기능입니다. 경우 다음

rs = stmt.executeQuery("SELECT urlHash FROM " +tableName+ " where urlHash ='urlHash' "); 
      while (rs.next()) { 
       String last = rs.getString("urlHash"); 
       } 

을 추가하고 그 값을 비교하지 않는 경우

는 첫 번째 문제를 들어 나는 URL이 존재 여부 있는지 확인하기 위해 URL 또는 urlHash에 선택 쿼리를 해고 할 수 그것은 그것을 비교하지 않습니다. 나는 이것이 내가 가야 할 길은 아니라고 생각한다. 그리고 무슨 일이 ..

둘째 Problem- 그리고이 URL이 존재하고 수정있어 경우 둘째 (우리가 마지막으로 수정 된 헤더에서 볼 수 있으며, 나는이 값을 저장하고이 첫 번째 문제를 할 수있는 가장 빠른 방법이 될 것입니다 modDate) 그런 다음 다른 해당 데이터로 URL을 업데이트하십시오.

는 따라서이 문제의 종류의

if URL does not Exists { 
Add to the oracle table and other data 
} else if(url got modified by checking the modDate) { 
update the url into oracle database and other data 
} 

Upate 단락 기호 솔루션에 따라 : - 내가 여기에 날짜 형식 문자열 날짜 형식으로 변환하려고하지만 누락으로 오류를 얻고있다 또는 인덱스 8의 OUT 매개 변수. 왜 그렇게됩니까?

ps = conn.prepareStatement(
         "MERGE INTO testing " + 
         "USING ( SELECT ? AS url, " +     // We will maybe add this record 
         "    ? AS urlHash, " + 
         "    ? AS contentHash, "+ 
         "   TO_DATE(?, 'YYYY-MM-DD'T'HH24:MI:SS'Z'') AS modDate, "+ 
         "   ? AS contentLocation, "+ 
         "   ? AS status, "+ 
         "  TO_DATE(?, 'YYYY-MM-DD'T'HH24:MI:SS'Z'') AS lastCrawlDate "+ 
         "   FROM dual) maybe "+ 
         " ON (maybe.urlHash = testing.urlHash) "+ 
         "   WHEN MATCHED THEN "+ 
          // We only need update the fields that might have changed 
         "  UPDATE SET testing.contentHash  = maybe.contentHash, "+ 
         "     testing.modDate   = maybe.modDate, "+ 
         "     testing.contentLocation = maybe.contentLocation, "+ 
         "     testing.status   = maybe.status, "+ 
         "     testing.lastCrawlDate = maybe.lastCrawlDate "+ 
          // But only if the new record is more recent 
         "  WHERE TO_CHAR(testing.modDate, 'YYYY-MM-DD'T'HH24:MI:SS'Z'') < TO_CHAR(maybe.modDate, ''YYYY-MM-DD'T'HH24:MI:SS'Z''') "+ 
         "   WHEN NOT MATCHED THEN "+ 
          // Insert new URL record 
         " INSERT VALUES (test_seq.nextval, maybe.url, maybe.urlHash, maybe.contentHash, maybe.modDate, maybe.contentLocation, maybe.status, maybe.lastCrawlDate)"); 


ps.setString (1, "http://www.computergeeks.com"); 
      ps.setString (2, "ahsasoiowiewie"); 
      ps.setString (3, "sgasjwhwueybdbfndf"); 
      ps.setString (4, "2011-07-28T23:54:14Z"); 
      ps.setString (5, "c://"); 
      ps.setLong (6, 0); 
      ps.setString (7, "2011-07-28T23:54:14Z"); 
      ps.executeUpdate(); 
      ps.close(); 

답변

8

면책 조항 : 지금 당장은 테스트 할 수 없습니다. modDate이 더 새로운 경우에만 업데이트 할 논리가있는 "UPSERT"와 같은 것을 원합니다.

오라클에서 그 MERGE 가능해야한다 :

MERGE INTO testing 
USING ( SELECT ? AS url,     -- We will maybe add this record 
       ? AS urlHash, 
       ... 
       ? AS lastCrawlDate 
      FROM dual) maybe 
    ON (maybe.urlHash = testing.urlHash) 
WHEN MATCHED THEN 
    -- We only need update the fields that might have changed 
     UPDATE SET testing.contentHash  = maybe.contentHash, 
        testing.modDate   = maybe.modDate, 
        testing.contentLocation = maybe.contentLocation, 
        testing.status   = maybe.status, 
        testing.lastCrawlDate = maybe.lastCrawlDate 
    -- But only if the new record is more recent 
     WHERE testing.modDate < maybe.modDate 
WHEN NOT MATCHED THEN 
    -- Insert new URL record 
    INSERT VALUES (test_seq.nextval, maybe.url, maybe.urlHash, ...); 
그들이해야처럼 당신이 당신의 testing 테이블에 몇 가지 제약 조건을 누락하는 것처럼 보인다 통과에주의합니다

(예, urlurlHash이 보인다 UNIQUE 이상)

(업데이트 : ruakh의 의견에 따라 수정)

+0

한 전체, 몇 가지 작은 확률값 있기는하지만 귀하의 코드와 함께. 예를 들어, 몇 곳에서'newurl'을 사용하고 다른 곳에서는'maybe'를 사용합니다; 'WHEN MATCHED' 절은'WHEN NOT MATCHED' 절 앞에 와야합니다. – ruakh

+0

@ruakh, 고맙습니다. - 모든 사람은 훌륭한 편집자/교정자/코드 평론가가 필요합니다. – pilcrow

+0

@pilcrow 상세한 솔루션을 제공해 주셔서 감사합니다. 정말로 감사드립니다. 나는 하나 더 질문이 있습니다. 테이블에 아무것도 없다면 오라클 데이터베이스에 처음 삽입하기 위해 삽입하려고합니다. 위의 쿼리는 작동하지 않을 것입니다. 테이블에 데이터가 없으므로 첫 번째 부분 (테이블 업데이트)이 자동으로 실패합니다.그리고 그것은 삽입의 두 번째 부분 (일치하지 않을 때)에 올 것입니다. 제가 맞습니까? – ferhan