2016-12-11 6 views
0

Итак, я потратил некоторое время на исследование того, каким лучшим способом было проверить, существует ли запись. Закончилось этим.Проверка SQL, если существует запись

Однако я не смог многократно сделать эту работу, используя ее на своей странице!

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, поэтому вы просто щелкаете и называете столбцы hehe. –

0

Я не человек C# любым способом, но я вижу одну логическую проблему с вашим текущим кодом. В настоящее время ваши запросы EXISTS и INSERT запускаются раздельно, разделенные несколькими строками кода .NET и, возможно, гораздо более актуальными машинными инструкциями. Чистая (не предназначенная для каламбура) результат заключается в том, что вы можете вставить ее, когда проверка существования окажется правдой, но больше не верна. Чтобы этого избежать, проверка существования должна появиться в предложении WHEREINSERT. Нечто подобное должно работать:

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

Теперь INSERT должно происходить атомарно, то есть чек и фактическую вставку все будет сделано в то же время, независимо от того, что другие потоки могут делать.

+0

Я обновил код в ispost для этого 'var insertData =" INSERT INTO exerciseVariants (exerVariName, exerVariNameID) VALUES (@ 0, @ 1) WHERE EXISTS (SELECT * exerVariName FROM exerciseVariants WHERE exerVariName = '"+ exerVariName +"') «;» и он дал эту ошибку (произошла ошибка, анализирующая запрос. [Номер строки токена = 1, смещение линии токена = 77, токен с ошибкой = ГДЕ]) и выделил эту строку 'db.Execute (insertData, exerVariName , exerciseID); –