3

我有存储过程

if OBJECT_ID(N'dbo.spGetProducts') is not null
drop procedure dbo.spGetProducts
go

CREATE procedure [dbo].[spGetProducts]
(
 @sort_col varchar(100), @sort_dir varchar(4),
 @start int, @num int, @filters nvarchar(2000)) as
 begin
 declare @end int
 declare    
  @res table 
  (
   row_num int,
   product_name nvarchar(max)
  )
set @end = @start+@num
insert into @res
EXEC
(
 'select * from 
  (
   select (ROW_NUMBER() OVER (ORDER BY '+@sort_col+' '+@sort_dir+')) row_num,
   * FROM (select product_name from Products where '+@filters+') as x
  ) as tmp where row_num between '+@start+' and '+@end
) select row_num, product_name from @res
 end 
go

当我完美地执行存储过程时latin characters,但是当我使用cyrillic字符时does not return anything..

这是执行行:

  1. 拉丁字符 - 工作:

    exec dbo.spGetProducts 'product_name','desc',0,50,' 
    product_name like N''%abs%'''
    
  2. 西里尔字符 - 不工作:

    exec dbo.spGetProducts 'product_name','desc',0,50,' 
    product_name like N''%абв%'''
    

我也手动设置要使用的存储过程

'product_name like N''%абв%'''

入行

select product_name from Products where '+@filters+'

IE

 select product_name from Products where product_name like N''%абв%'''

这个 WORKS ,所以我不知道如何解决这个问题..

4

2 回答 2

3

至于西里尔文内部参数的问题,您只需在发送时将另一个 N 放在整个过滤器参数前面

exec dbo.spGetProducts 'product_name','desc',0,50, N'product_name like N''%абв%'''
                                                   ^
                                                   ^
                                                  here

但也请阅读我关于安全问题的评论并重新考虑更改您的设计。

SQLFiddle 演示

编辑 - 一点解释:如果你没有指定你的输入参数是 NVARCHAR 它将被隐式声明为 VARCHAR,并且你的西里尔字母在它们被传递给过程之前就会абв丢失并被替换。???

如果您从 C# 或 VB 传递参数,则声明它们DBType.NVarChar应该足以避免该问题。

于 2013-06-04T13:09:15.973 回答
0

我并不感到意外。您应该使用参数而不是连接的 SQL。

但由于您使用的是动态 SQL,您的整个过程似乎需要重新编写。

在这里阅读,它会帮助你。

于 2013-06-04T12:30:55.063 回答