Mauvaise requête: syntaxe incorrecte près de ')'

asp.net dapper sql-server-2008

Question

J'ai une application ASP.NET et nous utilisons la bibliothèque Dapper. Le code qui génère l'erreur ressemble à ceci:

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;
}

Lorsque je lance l'application, elle lance l'exeption suivante: Syntaxe incorrecte près de ')'

Comme vous pouvez le voir, il peut y avoir plus de tickets (type IEnumerable) avec la même date et le même utilisateur.

Je ne suis pas sûr de ce qui se passe.

Réponse acceptée

C'est parce que le SQL n'est pas valide pour démarrer avec un if (Si vous voulez utiliser T-SQL c'est le cas, mais vous devez écrire la totalité de l'instruction if )

Je pense qu'un case simple est ce dont vous avez besoin:

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

Réponse populaire

Si votre résultat dépend du nombre de lignes et non de ce qui est renvoyé par le SQL, vous pouvez essayer ceci:

if exists ([whatever]) select 1

Cela fonctionne, car s'il n'y a pas de valeurs correspondantes, aucun jeu d'enregistrements n'est renvoyé et le nombre d'enregistrements affectés est égal à zéro.

Vous pourriez aussi essayer quelque chose de plus simple:

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

Mais cela a l'inconvénient de retourner une ligne pour autant de disques que vous avez. Cela peut être beaucoup, selon l'application et le contexte, et dans tous les cas, vous ne voulez pas extraire des données que vous n'allez pas utiliser.

Je ne recommanderais pas une instruction CASE , car SELECT CASE EXISTS ([whatever]) THEN 1 END renverra toujours un enregistrement, et le nombre d'enregistrements affectés sera égal à 1 même si aucun enregistrement n'existe.

Le problème avec votre SQL d'origine, à propos: L'instruction est incomplète. Vous dites "si existe ..." mais vous ne le terminez jamais avec l'équivalent d'un "alors". Vous devez dire "si existe () sélectionnez 1" ou quelque chose de similaire.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi