Existe-t-il un moyen de faire fonctionner la requête suivante?
ALTER PROCEDURE [dbo].[aTest] (@t nvarchar(20)) AS BEGIN SELECT [perno] ,[pName] FROM [dbo].[People] WHERE ([People].[pName] LIKE N'' +@t + '%') END
Je ne peux pas utiliser comme ça:
Where [pName] like N'Øس%'
Ou utiliser un procédure stockée:
declare @t nvarchar(20) set @t='Øس' SELECT [perno] ,[pName] FROM [dbo].[People] Where [pName] like N''+@t +'%'
3 Réponses :
Vous n'avez pas besoin d'utiliser le préfixe N
dans la clause WHERE
car votre variable est déjà nvarchar
et vous passez une variable pas une chaîne littérale .
Voici un exemple:
EXEC MyProc N'Øس'; --If you don't use N prefix then you are pass a varchar string
Vous avez peut-être vu du code Transact-SQL qui passe des chaînes en utilisant un préfixe N. Cela indique que la chaîne suivante est en Unicode (le N signifie en fait le jeu de caractères de la langue nationale). Ce qui signifie que vous transmettez une valeur NCHAR, NVARCHAR ou NTEXT, par opposition à CHAR, VARCHAR ou TEXT.
Depuis docs
Préfixe les constantes de chaîne de caractères Unicode avec la lettre N. Sans le préfixe N, la chaîne est convertie en page de codes par défaut de la base de données. Cette page de codes par défaut peut ne pas reconnaître certains caractères.
Pour répondre à votre question dans le commentaire avec une réponse simple, vous utilisez le mauvais type de données, donc ALTER
la procédure stockée et changez le type de données de votre paramètre de VARCHAR à NVARCHAR
.
UPDATE:
Puisque vous utilisez un SP, vous pouvez créer votre SP (selon votre comment ) comme
CREATE PROCEDURE MyProc ( @Var NVARCHAR(45) ) AS BEGIN SELECT * FROM People WHERE Name LIKE ISNULL(@Var, Name) + '%'; --Using ISNULL() will return all rows if you pass NULL to the stored procedure END
et appelez-le comme
CREATE TABLE People ( ID INT, Name NVARCHAR(45) ); INSERT INTO People VALUES (1, N'Øسا٠'), (2, N'ØساÙ'), (3, N'ØÙÙÙ '); DECLARE @Name NVARCHAR(45) = N'Øس';--You need to use N prefix when you pass the string literal SELECT * FROM People WHERE Name LIKE @Name + '%'; --You can use it here when you pass string literal, but since you are passing a variable, you don't need N here
Si vous voyez, vous avez besoin pour utiliser le préfixe N
lorsque vous passez une chaîne littérale à votre SP pas à l'intérieur du SP ou la clause WHERE
non plus.
correct je n'ai pas besoin de N Lors de la déclaration de variable mais lors de l'utilisation d'une procédure stockée avec paramètre?
@jaleel Alors pourquoi déclarez-vous votre variable avec le mauvais type de données?
mauvais type de données? Je vois que vous utilisez N, je pense que c'est le bon endroit mais j'ai toujours un problème sur la procédure stockée
@jaleel Je pense avoir répondu à cela dans la première citation, si vous n'utilisez pas N
alors SQL Server ne traitera pas la chaîne comme non-unicode Sans le préfixe N, le string est converti en page de codes par défaut de la base de données . De plus, je ne vois pas de procédure stockée dans votre question, donc si tel est le cas, veuillez modifier votre question
dans ces lignes
set @t=N'Øس'
le 'Øس'
est une constante varchar que vous attribuez ensuite à une variable nvarchar. Mais vous avez déjà perdu des données avec la conversion d'origine en cette constante varchar et vous ne pouvez pas les récupérer.
La solution consiste à utiliser une constante nvarchar :
declare @t nvarchar(20) set @t='Øس'
Cela pourrait être beaucoup plus simple:
Essayez ceci
set @t=N'Øس'; --<-- N-prefix
Vous déclarez correctement la variable comme NVARCHAR
. Mais le littéral ne connaît pas sa cible. Sans le N
, il est considéré comme un VARCHAR
avec le classement par défaut.
La ligne suivante
Where [pName] like N''+@t +'%'
recherchera un pName LIKE '??%'
.
La solution devrait être
declare @t nvarchar(20) set @t='Øس'; SELECT @t; --the result is "??"
Pourquoi avez-vous besoin de
N '
puisque votre variable est déjà nvarchar?N '
fait partie de la syntaxe string literal . Cela change le type de littéral de chaîne que vous écrivez. Il n'applique pas comme par magie les modifications aux chaînes obtenues par calcul ou à des valeurs attribuées à partir de littéraux complètement différents.deux mots, attaque par injection a >. Imaginez que le nom que vous recherchez est
N'haha ''); GO TRUNCATE [dbo]. [People]; - '
@Jodrell Où est l'opportunité d'injection SQL? Il n'y a pas de SQL dynamique présent, juste une concaténation de chaînes pour créer un modèle pour
comme
.@HABO, vous avez peut-être raison, je devrais l'essayer mais, le SQL dynamique est là
LIKE N '' + @ t + '%'
@Jodrell La concaténation de chaînes n'est pas du SQL dynamique. Dynamic SQL utilise
exécuter
ousp_executesql
pour exécuter une chaîne arbitraire contenant des instructions SQL. (Ou une méthode externe commeExecuteSqlCommand
.)@HABO, bonne référence ici sommarskog.se/dynamic_sql.html , mais avant de le lire, je Je pense que vous êtes probablement en sécurité, mais je vérifierais toujours.