2009-03-24 9 views
1

Quelqu'un peut-il m'aider à comprendre pourquoi la déclaration SQL n'aime pas la ligne suivante 'et' + @SearchCat + 'comme'% '+ @ Keywords +'% ''. Cela a à voir avec le nombre de guillemets simples, mais je ne peux pas comprendre. Comment fonctionnent les citations? Quelle est la logique?sql variables

DECLARE @strStatement varchar(550) 
declare @state as varchar(50) 
declare @district as varchar(50) 
declare @courttype as varchar(50) 
declare @SearchCat as varchar(50) 
declare @KeyWords as varchar (50) 

select @State ='FL' 
select @district = '11' 
select @courtType = '1' 
select @SearchCat='CaseNumber' 
select @KeyWords='File' 


select @strStatement= 'SELECT CaseNumber FROM app_Case 
      where State ='''+ @State+ 
      ''' and District='''+ @District+ 
      ' and ' + @SearchCat + 'like '%'[email protected]+'%'' 


exec (@strStatement) 

Répondre

0

Je le découvre. Je manquais un espace avant « comme »

2

je manque un espace avant « comme »

Vous avez également un nombre incorrect de guillemets simples autour de vos personnages de « % », qui le confondra. Incidemment, vous vous êtes fait un joli petit trou de sécurité SQL injection là, de l'intérieur de SQL lui-même! Si l'un des paramètres contient une apostrophe, votre instruction sqlStatement sera rompue et tout code SQL non autorisé dans le nom du paramètre sera exécuté.

Vous pouvez utiliser la fonction Replace pour doubler les guillemets simples pour éviter cette attaque:

' AND '+QUOTENAME(@SearchCat)+' LIKE ''%'+REPLACE(@Keywords, '''', '''''')+'%''...' 

(Le QUOTENAME est nécessaire si le nom de colonne contient des caractères hors bande ou est un mot réservé.)

Une approche plus simple (mais plutôt verbeuse) pour générer le SQL que fastidieusement REMPLACER chaque littéral de chaîne est d'utiliser sp_executesql. Par exemple:

SELECT @strStatement= N' 
    SELECT @Number= CaseNumber FROM app_Case 
    WHERE [email protected] AND [email protected] 
    AND '+QUOTENAME(@SearchCat)+N' LIKE ''%''[email protected]+''%'' 
'; 
SELECT @params= N'@State varchar(50), @District varchar(50), @Keywords varchar(50), @Number int OUTPUT'; 

EXECUTE sp_executesql @strStatement, @params, @State, @District, @Keywords, @Number OUTPUT; 

Soit dit en passant, si @searchCat ne peut avoir un petit nombre de valeurs différentes, vous pouvez utiliser une solution de contournement pour éviter d'avoir à faire tout ce laborieux non-sens SQL dynamique du tout:

SELECT CaseNumber FROM app_Case 
WHERE [email protected] AND [email protected] 
AND CASE @searchCat 
    WHEN 'searchableColumnA' THEN searchableColumnA 
    WHEN 'searchableColumnB' THEN searchableColumnB 
END LIKE '%'[email protected]+'%'; 

Voir this plutôt bonne exploration des instructions SQL créées dynamiquement dans T-SQL pour plus d'arrière-plan et certains des risques auxquels vous êtes confronté.