有什么方法可以使以下查询正常工作吗?
declare @t nvarchar(20)
set @t='حس'
SELECT [perno] ,[pName]
FROM [dbo].[People]
Where [pName] like N''+@t +'%'
我不能这样使用:
Where [pName] like N'حس%'
或使用存储过程:
ALTER PROCEDURE [dbo].[aTest]
(@t nvarchar(20))
AS
BEGIN
SELECT [perno] ,[pName]
FROM [dbo].[People]
WHERE ([People].[pName] LIKE N'' +@t + '%')
END
答案 0 :(得分:4)
您不需要在N
子句中使用WHERE
前缀,因为您的变量已经是nvarchar
,并且您要传递的变量不是文字字符串。
这里是一个例子:
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
您可能已经看到过Transact-SQL代码,该代码使用N前缀传递字符串。这表示后续的字符串采用Unicode(N实际上代表本国语言字符集)。这意味着您要传递一个NCHAR,NVARCHAR或NTEXT值,而不是CHAR,VARCHAR或TEXT。
来自docs
使用字母N作为前缀Unicode字符串常量。如果没有N前缀,则该字符串将转换为数据库的默认代码页。此默认代码页可能无法识别某些字符。
要在注释中以简单答案回答您的问题,您使用了错误的数据类型,因此ALTER
存储过程将参数的数据类型从VARCHAR
更改为NVARCHAR
更新:
由于使用的是SP,因此您可以根据comment创建SP的方式为
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
并命名为
EXEC MyProc N'حس'; --If you don't use N prefix then you are pass a varchar string
如果看到的话,则在将文字字符串传递到SP而不是在SP或N
子句中时都需要使用WHERE
前缀。
答案 1 :(得分:1)
在这些行中
declare @t nvarchar(20)
set @t='حس'
'حس'
是一个 varchar 常量,然后将其分配给nvarchar变量。但是您已经丢失了原始转换为该varchar常量的数据,并且无法恢复该数据。
解决方案是使用 nvarchar 常量:
set @t=N'حس'
答案 2 :(得分:1)
这可能更简单:
尝试一下
declare @t nvarchar(20)
set @t='حس';
SELECT @t; --the result is "??"
您正确地将变量声明为NVARCHAR
。但是文字不知道其目标。如果没有N
,它将被视为具有默认排序规则的VARCHAR
。
以下行
Where [pName] like N''+@t +'%'
将搜索一个pName LIKE '??%'
。
解决方案应该是
set @t=N'حس'; --<-- N-prefix