2015-07-17 7 views
2

У меня есть приложение ASP.NET, и мы используем библиотеку Dapper. Код, который производит ошибку выглядит следующим образом:Неверный запрос: неправильный синтаксис рядом с ')'

public bool CheckIfExists(IEnumerable<long> ticketGroups, long dateId, int userId) 
{ 
    bool bRetVal = false; 
    string sql = "if exists (select * from T_TicketGroupsToChangePrice where SubTypeId = @SubTypeId and DateId = @dateId and UserId = @userId)"; 
    using (var conn = CreateSqlConnection()) 
    try 
    { 
     int rows = conn.Execute(sql, ticketGroups.Select(g => new { SubTypeId = g, UserId = userId, dateId })); 
     if (rows > 0) 
      bRetVal = true; 
    } 
    catch (SqlException ex) 
    { 
     throw new Exception("Error", ex); 
    } 

    return bRetVal; 
} 

При запуске приложения оно бросает Exeption: Неправильный синтаксис около «)»

Как вы можете видеть, может быть больше билетов (IEnumerable типа) с той же датой и пользователем.

Я не уверен, что происходит.

+1

Не ответ, но ваша логика выглядит немного странно. Кажется, вы запрашиваете db для логического ответа (если существует), но затем вы оцениваете результат против ожидаемого количества строк. – Matt

+0

Да. Если число возвращаемых строк больше 0, это означает, что существует строка (строки), и метод возвращает true. В противном случае это ложь. Почему ты имеешь в виду, что это странно? – tesicg

+0

Но запрос, который вы задаете в db, не «сколько строк есть?». Вы спрашиваете: «Есть ли какие-нибудь строки?». Разные вещи. Просто очень незначительное наблюдение. – Matt

ответ

8

Это потому, что он не является действительным SQL начать с if (Если вы имеете в виду использовать T-SQL она есть, но тогда вы должны написать все if заявление)

Я думаю, что просто case является что вам нужно:

select case 
     when exists (select * from T_TicketGroupsToChangePrice where SubTypeId = @SubTypeId and DateId = @dateId and UserId = @userId) 
     then 1 
     else 0 
     end 
+0

Проблема заключается в том, что метод Execute возвращает количество затронутых строк. – tesicg

+0

Извините. Не заметил этого. Затем используйте 'ExecuteScalar'. –

+0

Возникла ошибка: нужно объявить скалярную переменную "@SubTypeId". – tesicg

0

Ваш запрос «если существует (выберите * из T_TicketGroupsToChangePrice где SubTypeId = @SubTypeId и DateId = @dateId и UserId = @userId)» вернуть некоторые данные, если таблица имеет некоторые так и для что для этого требуется что-то для работы. Как, если другое условие в программировании мы можем изменить это, как:

if exists 
(select * from T_TicketGroupsToChangePrice where SubTypeId = @SubTypeId and DateId = @dateId and UserId = @userId) 
Print 'Have Data' 
else 
Print 'Don't Have data' 

Переписывая код:

public bool CheckIfExists(IEnumerable<long> ticketGroups, long dateId, int userId) 
{ 
    bool bRetVal = false; 
    string sql = "if exists (select * from T_TicketGroupsToChangePrice where SubTypeId = @SubTypeId and DateId = @dateId and UserId = @userId) Print '**your code to execute if exist data**' else Print '**your code to execute if doesnot exist data**'"; 
    using (var conn = CreateSqlConnection()) 
    try 
    { 
     int rows = conn.Execute(sql, ticketGroups.Select(g => new { SubTypeId = g, UserId = userId, DateId = dateId })); 
     if (rows > 0) 
      bRetVal = true; 
    } 
    catch (SqlException ex) 
    { 
     throw new Exception("Error", ex); 
    } 

    return bRetVal; 
} 

эта ссылка поможет вам больше: https://dba.stackexchange.com/questions/30159/exist-select-from-my-table

0

Если результат зависит от количества of rows и not on what, возвращаемое с SQL, вы можете попробовать следующее:

if exists ([whatever]) select 1 

Это работает, потому что, если нет подходящих значений, никакой набор записей не возвращается, а ваш счетный номер записи равен нулю.

Вы также можете попробовать что-то немного проще:

select 1 
from T_TicketGroupsToChangePrice 
where SubTypeId = @SubTypeId 
    and DateId = @dateId 
    and UserId = @userId; 

Но это имеет тот недостаток, возвращая одну строку для однако много записей, которые Вы имеете. Это может быть много, в зависимости от приложения и контекста, и в любом случае вы не хотите извлекать данные, которые вы не собираетесь использовать.

Я бы не рекомендовал инструкцию CASE, потому что SELECT CASE EXISTS ([whatever]) THEN 1 END по-прежнему будет возвращать одну запись, и ваш счетчик записей будет равен 1, даже если записей не существует.

Проблема с вашим исходным SQL, кстати: заявление является неполным. Вы говорите «если есть ...», но вы никогда не закончите его с эквивалентом «затем». Вам нужно сказать «if exists() выбрать 1» или что-то подобное.

Смежные вопросы