【问题标题】:Passing cyrillic character into stored procedure doesn't work Sql Server将西里尔字符传递到存储过程中不起作用 Sql Server
【发布时间】:2013-06-04 12:24:35
【问题描述】:

我有存储过程

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+'

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

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

【问题讨论】:

  • 首先,我必须指出,将 where 子句作为参数传递并在动态 SQL 中使用它确实是个坏主意,因为它容易受到 SQL 注入的攻击。我不知道从某个应用程序中输入了什么参数,但想象一下,如果有人给您发送类似@filters = '1=1)AS x)AS y; DROP TABLE Products; --' 的内容
  • 感谢您的建议,我知道这很容易受到 SQL 注入的影响,但我自己生成过滤器,因此没有 sql 注入的空间。

标签: sql sql-server tsql stored-procedures


【解决方案1】:

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

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

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

SQLFiddle Demo

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

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

【讨论】:

  • 如果我们输入两个类似的语句会发生什么? N会同时申请吗?
  • @Aleks 如果你的意思是同一个 @filters 参数中有两个喜欢 - 是的,前面的 N 代表整个参数。像这样的东西? sqlfiddle.com/#!6/8125e/1
【解决方案2】:

我并不感到惊讶。您应该使用参数而不是串联的 SQL。

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

阅读here,它会帮助你。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-13
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多