将存储过程参数插入表中只会插入第一个字母

时间:2018-10-11 08:04:18

标签: sql-server stored-procedures

我有存储过程,其中有数据类型为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的长度未声明

1 个答案:

答案 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