2009-07-15 4 views
0

이 함수가 데이터베이스에 레코드를 삽입하지 않는 이유를 찾을 수 없습니다. :( 내가 어떠한 오류 메시지 나 데이터베이스에서 단지 아무것도 얻을이 쿼리에서 내가 뭘 잘못하고 있니?

편집 :.이 내 쿼리가 지금 모습입니다 .. 아직 아무것도 ..

connection.Open(); 
XmlNodeList nodeItem = rssDoc.SelectNodes("/edno23/posts/post"); 

foreach (XmlNode xn in nodeItem) 
{ 
    cmd.Parameters.Clear(); 
    msgText = xn["message"].InnerText; 
    C = xn["user_from"].InnerText; 
    avatar = xn["user_from_avatar"].InnerText; 
    string endhash = GetMd5Sum(msgText.ToString()); 
    cmd.Parameters.Add("@endhash",endhash); 
    cmd.CommandText = "Select * FROM posts Where [email protected]"; 
    SqlCeDataReader reader = cmd.ExecuteReader(); 

    while (reader.Read()) 
    { 
     string msgs = reader["hash"].ToString(); 

     if (msgs != endhash || msgs == null) 
     { 
      sql = "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)"; 
      cmd.CommandText = sql; 
      cmd.Parameters.Add("@username", C); 
      cmd.Parameters.Add("@messige", msgText.ToString()); 
      cmd.Parameters.Add("@userpic", avatar.ToString()); 
      cmd.Parameters.Add("@thedate", dt); 
      cmd.Parameters.Add("@hash", endhash); 
      cmd.ExecuteNonQuery();// executes query 
      adapter.Update(data);// saves the changes 
     } 
    } 

    reader.Close(); 
} 

connection.Close(); 
+0

while 루프를 입력하고 if 블록으로 들어가는 것을 확인 했습니까? –

+2

디버거를 사용하여 코드를 단계별로 실행하면 더 빨리 익힐 수 있습니다 –

답변

2

합니까 nodeItem :-) 도움이되기를 바랍니다? 그렇지 않으면 foreach 루프의 내용이 실행되고 있지 않습니다.

사용중인 어댑터 및 데이터는 무엇입니까? 쿼리와 업데이트는 다른 명령과 리더를 통해 수행됩니다.

'해시'에는 실제로 무엇이 들어 있습니까? 이것이 해시 인 경우 왜 while 루프 내부에서 해시의 내용을 해시하고 있습니까? 그렇지 않은 경우 쿼리의 해시와 비교되는 이유는 무엇입니까 SELECT * FROM posts WHERE hash = @endhash?

while 루프가 끝나기 전에 연결을 닫지 않으면 루프를 제어하는 ​​데 사용되는 판독기가 무효화됩니까?

+0

내가 해시 할 일을하고있다 사촌 내가 콘텐츠를 100 % 독창적 인 경우 콘텐츠를 삽입하지 않으면 그 콘텐츠를 삽입 이전 콘텐츠와 동일하면 건너 뜁니다 :) 나는 이미 연결을 닫습니다 이동 – Aviatrix

+1

@Aviatrix : 나는 당신을 생각합니다 해시 질문으로 요점을 놓쳤습니다. 'hash' 컬럼은 해쉬를 포함합니다, 그렇습니까? 당신은 특별히'endhash'에 포함 된 해시를 가진 레코드를 쿼리합니다. 그런 다음 해당 열에 포함 된 값을 99.99 % * gauranteed *로 해시하여 완전히 다른 해시를 생성하고 원래 쿼리 값과 비교합니다. * 결코 * 일치하지 않습니다. –

+0

나는 그것을 고정 .. 그 두 해시를 비교하고 싶었지만 실수로 내가 해시를 해시 .. OO 모든 사람 .. 아직 어떤 레코드가 추가되지 않습니다 메신저 : ( – Aviatrix

0

프로그램을 디버깅하는 방법 : http://www.drpaulcarter.com/cs/debug.php

심각하게도 작동하는 위치에 대한 정보를 더 게시 할 수 있습니까? SQL CE 대신 SQL Server Express를 사용하면 작동합니까? 그렇다면 SQL 프로필러를 분해하고 SQL 명령을 살펴볼 수 있습니까? 실행 했습니까?

0

같은 SqlCeCommand 인스턴스를 다시 사용하려고하는 것이 문제라고 생각됩니다.

while 루프 내에서 새 SqlCeCommand를 만들어보십시오. 또한 using 문을 사용하여 데이터 개체를 닫을 수 있습니다.


당신의 모든 데이터 집합을 변경하지 않는 때문에 왜 adapter.Update(data)을 요구하고있다

? adapter.Fill(data)에 전화하고 싶습니다. Update 메서드는 데이터 집합의 모든 변경 내용을 데이터베이스에 저장합니다. 많은 것들이 여기에가는

1

...

당신은 삽입을 실행하기 위해 while 문 안에 같은 'cmd를'명령을 사용하여 다음 DataReader를 함께 기록을 통해 루프 명령 'cmd를'을 사용하고 있습니다 성명서. 이전에 다른 명령 'cmdAdd'를 선언했지만 다른 곳에서는 사용하지 않는 것으로 보입니다. insert 문에 사용하려는 의도입니까?

또한 데이터 루프를 반복하는 while 루프 내에서 데이터 연결을 닫습니다. 하나의 레코드 만 읽은 다음 데이터베이스 연결을 닫습니다. 삽입 조건이 충족되지 않으면 데이터베이스에 아무 것도 쓰지 않을 것입니다.

편집 :

당신은 정말 열고 된 XMLNodes에 foreach는 외부 데이터베이스에 대한 연결을 닫아야합니다. 10 노드를 반복한다면 DB 연결은 10 번 열리고 닫히게됩니다. (물론 연결 풀링은 그걸 막을 수는 있지만 여전히 ...)

또한 전체 '게시물' 테이블을 데이터 집합으로 변환 할 필요가 없습니다. 데이터 셋의 값을 변경하지 않고 반복적으로 업데이트를 호출하고 있습니다 ("save teh shanges"). 'posts'테이블이 원격으로 큰 경우에도, 아무런 이유없이 많은 양의 메모리를 낭비하게됩니다 (핸드 헬드 장치에서는 그다지 효과적이지 않습니다).

+0

다시 쿼리를 보았습니다. :) – Aviatrix

+0

해시가 이미 존재하지 않는 경우에만 레코드를 삽입하고 싶습니까? 그렇다면 데이터 저장소를 반복 할 필요조차 없습니다. 대신, "게시물에서 hashcount로 count (*)를 선택하십시오. 여기서 hash = @ endhash"; 값이 0이면 레코드를 삽입하십시오. –

+1

@Aviatrix : 이미 루프에있는 것들을 다시 사용하는 대신 매번 * new * 매개 변수를 명령 객체의 매개 변수 컬렉션에 추가합니다. –

1

왜 데이터베이스 연결을 닫고 있습니까 while 루프?
게시 된 코드 cmd.ExecuteNonQuery()에 개봉하지 않은 DB 연결 개체를 호출하려고하면이 예외를 throw해야합니다.

SqlCeCommand.ExecuteNonQuery() 메서드는 영향을받는 행 수를 반환합니다.
아래 표시된 것처럼 디버거에서 1이 반환되는지 여부를 확인하지 않는 이유는 무엇입니까?

int rowsAffectedCount = cmd.ExecuteNonQuery(); 

실제로 어떤 항목이이

1

"* FROM posts where Where hash = @ endhash"에서 아무 것도 반환되지 않습니까? 당신은 블록을 "사용"구현되지와 함께 몇 가지 문제가있어

1

그렇지 않으면, while 루프 문제 안에 아무것도 .... 아래 코드를 추가했습니다. 연결 및 선택 명령 블록은 내 생각에 좀더 희망적인 생각입니다. 데이터 어댑터에서도 동일한 작업을 수행하기를 바랍니다.

using (var connection = new SqlCeConnection(connectionString)) 
{ 
    connection.Open(); 
    var nodeItem = rssDoc.SelectNodes("/edno23/posts/post"); 

    foreach (XmlNode xn in nodeItem) 
    { 
     using (
      var selectCommand = 
       new SqlCeCommand(
        "Select * FROM posts Where [email protected]", 
        connection)) 
     { 
      var msgText = xn["message"].InnerText; 
      var c = xn["user_from"].InnerText; 
      var avatar = xn["user_from_avatar"].InnerText; 
      var endhash = GetMd5Sum(msgText); 
      selectCommand.Parameters.Add("@endhash", endhash); 
      selectCommand.CommandText = 
       "Select * FROM posts Where [email protected]"; 
      using (var reader = selectCommand.ExecuteReader()) 
      { 
       while (reader.Read()) 
       { 
        var msgs = reader["hash"].ToString(); 

        if (msgs == endhash && msgs != null) 
        { 
         continue; 
        } 

        const string COMMAND_TEXT = 
         "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)"; 
        using (
         var insertCommand = 
          new SqlCeCommand(
           COMMAND_TEXT, connection)) 
        { 
         insertCommand.Parameters.Add("@username", c); 
         insertCommand.Parameters.Add(
          "@messige", msgText); 
         insertCommand.Parameters.Add(
          "@userpic", avatar); 
         insertCommand.Parameters.Add("@thedate", dt); 
         insertCommand.Parameters.Add(
          "@hash", endhash); 
         insertCommand.ExecuteNonQuery(); 
          // executes query 
        } 
        adapter.Update(data); // saves teh changes 
       } 

       reader.Close(); 
      } 
     } 
    } 

    connection.Close(); 
} 

물론 추가 중첩을 사용하면 부품을 별도의 방법으로 분류해야합니다.

+0

솔루션을 해결해 주셔서 고마워하지만 내가 잘못 SQL을 사용하는 것 같아요 명령 모두 함께;) 내가 필요한 모든 것을 읽는 ExecuteReader() 대신 ExecuteScalar()는 결과 1 개만 반환하고 더 이상 필요하지 않습니다 :) 해쉬가/isnt인지 확인해야합니다 :) http : // /avi.pastebin.com/f5aca84f4 << 가끔은 그것보다 더 간단합니다 : D – Aviatrix

관련 문제