Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
与运算符一样,N和%SQL Server在nvarchar列上不工作_Sql_Sql Server_Tsql_Sql Like - Fatal编程技术网

与运算符一样,N和%SQL Server在nvarchar列上不工作

与运算符一样,N和%SQL Server在nvarchar列上不工作,sql,sql-server,tsql,sql-like,Sql,Sql Server,Tsql,Sql Like,有没有办法让下面的查询工作 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

有没有办法让下面的查询工作

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   
您不需要在WHERE子句中使用N prefix,因为您的变量已经是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
您可能看到过使用N前缀传递字符串的Transact-SQL代码。这表示后面的字符串是Unicode,N实际上代表国家语言字符集。这意味着您正在传递NCHAR、NVARCHAR或NTEXT值,而不是CHAR、VARCHAR或TEXT

以字母N作为Unicode字符串常量的前缀。如果不使用N前缀,字符串将转换为数据库的默认代码页。此默认代码页可能无法识别某些字符

要用简单的答案回答注释中的问题,您使用了错误的数据类型,因此请更改存储过程并将参数的数据类型从VARCHAR更改为NVARCHAR

更新:

由于您使用的是SP,因此可以根据您的as创建SP

并称之为

EXEC MyProc N'حس'; --If you don't use N prefix then you are pass a varchar string
如果您看到了,那么当您将文本字符串传递到SP(不在SP内)或WHERE子句(两者都不在SP内)时,需要使用N前缀

您不需要在WHERE子句中使用N prefix,因为您的变量已经是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
您可能看到过使用N前缀传递字符串的Transact-SQL代码。这表示后面的字符串是Unicode,N实际上代表国家语言字符集。这意味着您正在传递NCHAR、NVARCHAR或NTEXT值,而不是CHAR、VARCHAR或TEXT

以字母N作为Unicode字符串常量的前缀。如果不使用N前缀,字符串将转换为数据库的默认代码页。此默认代码页可能无法识别某些字符

要用简单的答案回答注释中的问题,您使用了错误的数据类型,因此请更改存储过程并将参数的数据类型从VARCHAR更改为NVARCHAR

更新:

由于您使用的是SP,因此可以根据您的as创建SP

并称之为

EXEC MyProc N'حس'; --If you don't use N prefix then you are pass a varchar string
如果您看到了,那么当您将文本字符串传递到SP(不在SP内)或WHERE子句(两者都不在SP内)时,需要使用N前缀

在这些方面

declare @t nvarchar(20)
set @t='حس'
“حس”是一个varchar常量,然后将其分配给nvarchar变量。但是您已经丢失了原始转换为该varchar常量的数据,并且无法恢复该数据

解决方案是使用nvarchar常量:

set @t=N'حس'
在这些方面

declare @t nvarchar(20)
set @t='حس'
“حس”是一个varchar常量,然后将其分配给nvarchar变量。但是您已经丢失了原始转换为该varchar常量的数据,并且无法恢复该数据

解决方案是使用nvarchar常量:

set @t=N'حس'

这可能要简单得多:

试试这个

declare @t nvarchar(20)
set @t='حس';

SELECT @t; --the result is "??"
您正确地将变量声明为NVARCHAR。但是文字不知道它的目标。如果没有N,它将被视为具有默认排序规则的VARCHAR

下一行

Where [pName] like N''+@t +'%'
将搜索类似“??%”的pName

解决办法应该是

set @t=N'حس'; --<-- N-prefix

这可能要简单得多:

试试这个

declare @t nvarchar(20)
set @t='حس';

SELECT @t; --the result is "??"
您正确地将变量声明为NVARCHAR。但是文字不知道它的目标。如果没有N,它将被视为具有默认排序规则的VARCHAR

下一行

Where [pName] like N''+@t +'%'
将搜索类似“??%”的pName

解决办法应该是

set @t=N'حس'; --<-- N-prefix

既然变量是alrady nvarchar,为什么需要N?N是字符串文字语法的一部分。它会更改您正在编写的字符串文字的类型。它不会神奇地将更改应用于通过计算获得的字符串或从完全不同的文本中指定的值。想象一下你正在寻找的名字是N'haha;去截断[dbo].[People];-'@Jodrell SQL注入的机会在哪里?没有动态SQL,只有字符串连接来创建like的模式。@HABO,你可能是对的,我必须尝试一下,但是动态SQL就像N+@t+'%'为什么需要N',因为你的变量是alrady nvarchar?N'是字符串文字语法的一部分。它会更改您正在编写的字符串文字的类型。它不会神奇地将更改应用于通过计算获得的字符串或从完全不同的文本中指定的值。想象一下你正在寻找的名字是N'haha;去截断[dbo].[People];-'@Jodrell SQL注入的机会在哪里?没有动态SQL,只有字符串连接来创建一个类似的模式。@HABO,你可能是对的,我必须尝试一下,但是动态SQL像N+@t+'%'一样存在。正确我在声明变量时不需要N,但在使用存储时需要N
带参数的d过程?@jaleel那么为什么用错误的数据类型声明变量?错误的数据类型?我看到您使用了N,认为它是正确的位置,但在存储上仍然存在问题procedure@jaleel我想我在第一句话中回答了这个问题,如果不使用N,那么SQL Server将不会将字符串作为非unicode处理,如果没有N前缀,字符串将转换为数据库的默认代码页。另外,我在您的问题中没有看到存储过程,因此如果是这种情况,请编辑您的问题更正我在声明变量时不需要N,但在使用带参数的存储过程时?@jaliel那么为什么您使用错误的数据类型声明变量?错误的数据类型?我看到您使用了N,认为它是正确的位置,但在存储上仍然存在问题procedure@jaleel我想我在第一句话中回答了这个问题,如果不使用N,那么SQL Server将不会将字符串作为非unicode处理,如果没有N前缀,字符串将转换为数据库的默认代码页。另外,我在您的问题中没有看到存储过程,因此如果是这种情况,请编辑您的问题