2016-12-11 2 views
0

레코드가 있는지 확인하는 것이 가장 좋은 방법인지 조사하기 위해 시간을 보냈습니다. 이걸로 끝났어.SQL에 레코드가 있는지 확인하십시오.

var checkExistance = "SELECT TOP 1 exerVariName FROM exerciseVariants WHERE exerVariName = '" + exerVariName + "'"; 

그러나 내 페이지에서이 작업을 사용하는 데 여러 번 실패했습니다.

var exerVariName = Request.Form["exerVariName"]; 

var checkExistance = "SELECT TOP 1 exerVariName FROM exerciseVariants WHERE exerVariName = '" + exerVariName + "'"; 

if (IsPost && Validation.IsValid()) { 
    if (ModelState.IsValid) { 
     foreach (var c in db.Query(checkExistance)) {      
      if (c.exerVariName != exerVariName) { 
       var insertData = "INSERT INTO exerciseVariants (exerVariName, exerVariNameID) " + 
       "VALUES (@0, @1)"; 

       db.Execute(insertData, exerVariName, exerciseID); 
       Response.Redirect("~/insertexervariname"); 
      } 
     } 
    } 
} 

그래서 나는 SQL 라인에 투입 변수 나는 이미 내가 그것을 게시 할 그나마 존재하는 경우는, 데이터베이스에 존재하는지 확인하려는 자사의 사용자 입력 그래서 요청 양식 것입니다. 그리고 위의 내용은 foreach으로 시도한 것이며 if ispost입니다.

어떻게 이것을 달성 할 수 있습니까? (C# razor/cshtml)

답변

0

코드에는 경쟁 조건이 있습니다.

당신이 원하는 것을 할 수있는 가장 좋은 방법은 데이터베이스가 고유 인덱스/제약 조건 사용하여 제약 조건을 적용하는 것입니다 : 당신이 업데이트에 오류가 발생하지 않도록하려면

create unique index unq_exerciseVariants_exerVariName on exerciseVariants(exerVariName); 

을, 당신은으로 확인하실 수 있습니다

INSERT INTO exerciseVariants (exerVariName, exerVariNameID) 
     SELECT exerVariName, exerVariNameID 
     FROM (SELECT @0 as exerVariName, @1 as exerVariNameID 
      ) x 
     WHERE NOT EXISTS (SELECT 1 
         FROM exerciseVariants 
         WHERE ev.exerVariName = x.exerVariName 
         ); 

두 개의 다른 스레드가 동시에 같은 이름을 삽입하려고하면 경쟁 조건으로 인해이 검사가 충분하지 않을 수 있습니다. 따라서 데이터베이스에 고유성을 적용하는 것이 가장 좋습니다.

+0

이 'create unique index' 행은 어디에 넣을까요? –

+0

@ PontusSvedberg. . . 데이터베이스에 연결하여 한 번 실행하십시오. –

+0

불행히도 데이터베이스를 작성하지 않아 webmatrix에 내장되어있어서 열을 클릭하고 이름을 지정할 수 있습니다. –

0

저는 어떤 사람이든 C# 인물이 아니지만 현재 코드에 논리적 인 문제가 하나 있습니다. 현재 EXISTSINSERT 개의 쿼리가 별도로 실행되며 여러 줄의 .NET 코드와 더 많은 실제 기계 명령어로 구분됩니다. 그물 (의도하지 않은 의도 없음) 결과는 존재 확인이 사실로 나타나지만 더 이상 사실이 아닐 때 삽입하게 될 수 있다는 것입니다. 이를 방지하려면 존재 확인이 INSERTWHERE 절에 나타나야합니다. 이런 식으로 뭔가 작업을해야합니다 :

INSERT INTO exerciseVariants (exerVariName, exerVariNameID) 
VALUES (@0, @1) 
WHERE EXISTS 
(
    SELECT * exerVariName 
    FROM exerciseVariants 
    WHERE exerVariName = '" + exerVariName + "'"; 
) 

는 이제 INSERT이 원자 적으로 발생해야 관계없이 다른 스레드가 무엇을하고 있는지, 수표와 모두 같은 시간에 수행됩니다 실제 삽입을 의미한다.

+0

if ispost의 코드를 다음과 같이 수정했습니다. 'var insertData = "INSERT INTO exerciseVariants (exerVariName, exerVariNameID) VALUE (@ 0, @ 1) WHERE EXISTS (SELECT * exerVariName FROM exerciseVariants WHERE exerVariName ='"+ exerVariName + " ') ';'그리고이 오류가 발생했습니다. (토큰 행 번호 = 1, 토큰 행 오프셋 = 77, 토큰 오류 = WHERE)이 줄을 강조 표시했습니다. db.Execute (insertData, exerVariName , exerciseID); –

관련 문제