我有存储过程,其中有数据类型为sql_variant
的参数。然后,将转换此参数并将其插入到nvarchar(MAX)
数据类型的参数中。插入日期和浮点数效果很好。然后作为示例,插入varchar(60)
单元似乎无效,仅插入第一个字母。当我为存储过程中的参数添加SELECT
语句时,它会在正确执行要插入的信息后显示,并且只会使实际插入表失败。
如何将整个nvarchar
插入varchar(60
)或类似的单元格中?
这里是代码的重要组成部分,没有太多额外的内容:
CREATE PROCEDURE proc_name
@param1 nvarchar(30),
@param2 nvarchar(30),
@param3 sql_variant
AS
BEGIN
SET NOCOUNT ON;
DECLARE @update_param nvarchar(MAX);
SET @update_param = CONVERT(nvarchar(MAX), @param3);
-- Lots of not important stuff here such as getting datatype from INFORMATION_SCHEMA
DECLARE @Sql nvarchar(MAX);
SET @Sql = N' DECLARE @variable ' + QUOTENAME(@datatype) + N' = @update_param '
+ N' UPDATE table_name'
+ N' SET ' + @param1 + N' = @variable '
+ N' WHERE something = ' + @param2
Exec sp_executesql @Sql, N'@update_param nvarchar(MAX)', @update_param
在过程中添加SELECT @Sql
会得到以下结果:
DECLARE @variable [varchar] = @update_param
UPDATE table_name
SET column_name = @variable
WHERE something = thingsome
@param1 = column_name, @param2 = thingsome
编辑:我阅读了有关此主题的多个问题,他们都要求声明nvarchar长度。在这里,我将其声明为nvarchar(MAX)
。
Edit2:添加了代码位。
Edit3:添加代码并在注释中提供帮助后,答案是@datatype
中@Sql
的长度未声明
答案 0 :(得分:1)
这不能解决当前的问题,但是,您拥有的SP可以接受注入。像这样的原始字符串连接是一个危险的游戏。这要安全得多:
CREATE PROCEDURE proc_name
@param1 nvarchar(30),
@param2 nvarchar(30),
@param3 sql_variant
AS
BEGIN
SET NOCOUNT ON;
DECLARE @update_param nvarchar(MAX);
SET @update_param = CONVERT(nvarchar(MAX), @param3);
-- Lots of not important stuff here such as getting datatype from INFORMATION_SCHEMA
DECLARE @Sql nvarchar(MAX);
SET @Sql = N' DECLARE @variable ' + QUOTENAME(@datatype) + N' = @dupdate_param' --Where is the value of @datatype coming from?
+ N' UPDATE table_name'
+ N' SET ' + QUOTENAME(@param1) + N' = @variable '
+ N' WHERE something = @dparam2;'
Exec sp_executesql @Sql, N'@dupdate_param nvarchar(MAX), @dparam2 nvarchar(30)',@dupdate_param = @update_param, @dparam = @param2;
GO