为啥 sp_executesql 需要 ntext/nchar/nvarchar 而不是 text/char/varchar?
Posted
技术标签:
【中文标题】为啥 sp_executesql 需要 ntext/nchar/nvarchar 而不是 text/char/varchar?【英文标题】:Why does sp_executesql REQUIRE ntext/nchar/nvarchar as opposed to text/char/varchar?为什么 sp_executesql 需要 ntext/nchar/nvarchar 而不是 text/char/varchar? 【发布时间】:2012-09-22 01:41:00 【问题描述】:为什么 sp_executesql 需要 ntext/nchar/nvarchar 参数和语句而不是 text/char/varchar?
我了解如何解决此问题(通过将所有语句/参数声明为 nvarchar),但为什么 Microsoft 会强制执行此操作?有什么好处?
【问题讨论】:
【参考方案1】:我不确定这是出于特定于该程序的任何特定原因而强制执行的。另一个对数据类型很挑剔的系统存储过程的例子是sp_trace_create.
这不仅需要nvarchar
用于@tracefile
参数,而且参数@maxfilesize
必须作为'bigint' 传递,并且它不接受始终能够正确转换的文字整数。
这失败了
DECLARE @TraceID int
EXEC sp_trace_create @TraceID OUTPUT, 0, N'X:\Foo', 1, NULL
成功了
DECLARE @TraceID int
DECLARE @x bigint = 1
EXEC sp_trace_create @TraceID OUTPUT, 0, N'X:\Foo', @x, NULL
这两个都显示为master
数据库中的系统扩展存储过程。我假设这些扩展存储过程的调用机制与常规存储过程的调用机制不同,因此 SQL Server 不会隐式转换参数。
sp_executesql
像这样强制执行nvarchar
不一定是坏事。动态 SQL 可能出现的一个潜在问题是,如果以nvarchar
的形式提供字符串,然后对其进行清理然后强制转换为varchar
,则转换可能会打开 SQL 注入机会。 An example of that is in my answer here.
【讨论】:
但 OTOHxp_cmdshell
也是一个扩展存储过程,接受 varchar(8000)
或 nvarchar(4000)
以上是关于为啥 sp_executesql 需要 ntext/nchar/nvarchar 而不是 text/char/varchar?的主要内容,如果未能解决你的问题,请参考以下文章
[转]使用exec和sp_executesql动态执行SQL语句