Sql server 在表中插入存储过程参数时,仅插入第一个字母

Sql server 在表中插入存储过程参数时,仅插入第一个字母,sql-server,stored-procedures,Sql Server,Stored Procedures,我有一个存储过程,其中有数据类型为sql\u variant的参数。然后将此参数转换并插入到nvarchar(MAX)datatype的参数中。插入日期和浮动效果良好。然后,例如,插入varchar(60)单元格似乎不起作用,只插入第一个字母。当我为存储过程中的参数添加SELECT语句时,它会在执行要正确插入的信息后显示,而实际插入表时只会失败 如何将整个nvarchar插入varchar(60)或类似单元格 以下是代码的重要部分,没有太多额外内容: CREATE PROCEDURE proc_

我有一个存储过程,其中有数据类型为
sql\u variant
的参数。然后将此参数转换并插入到
nvarchar(MAX)
datatype的参数中。插入日期和浮动效果良好。然后,例如,插入
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\u name,@param2=thingsome

编辑:我读了很多关于这个主题的问题,他们都告诉我要声明nvarchar长度。这里我将它声明为
nvarchar(MAX)

Edit2:添加代码位


Edit3:在注释中添加代码和帮助后,答案是
@datatype
@Sql

中有未声明的长度。这并不能回答当前的问题,但是,您拥有的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

听起来好像您没有声明
(n)varchar
的长度,但是它默认为
(n)varchar(1)
。没有代码,这就是我们所能猜到的。
DECLARE@variable[varchar]=@update\u param
击败我@DiadoYep,它将抛出一个
无效数据类型
例外,如果您从
信息模式获取数据类型。列
您可以检查
字符的最大长度
列-for
(N)varchar(MAX)
它将被设置为
-1
。对于小于
MAX
的值,它将是实际值。对于
INT
和其他与其无关的数据类型,它将为
NULL
,没有理由声明
@变量
,它只会导致隐式强制转换并引入截断错误
dupdate_param
可以直接用在
SET
子句中,想想看,
SET@update_param=CONVERT(nvarchar(MAX),@param3)
可能也是一个bug-如果它是
@param3
sql\u变体
为什么不按原样传递呢?为什么要先将其转换为
nvarchar(max)
,然后再转换回原始类型?
@param3
更可能包含正确的值好吧,我有点头疼。这可能会造成比我当时想象的更多的麻烦first@PanagiotisKanavos我同意这些观点。我只是在讨论注射问题。在逻辑上有几个“奇怪”的选择,然而,注入是最糟糕的选择。解决这个问题应该是最重要的。@PanagiotisKanavos@Larnu我明白你的观点,并感谢你的反馈,我显然必须重新审视我的逻辑,以避免注射风险。我还必须再次检查其他数据类型的工作情况。我提供的代码稍微简化了一点,实际上大部分信息都是参数化的(表名、列名、设置
后的两个参数,其中
),因此该过程可以用于多个表(可以是标准化的或平面的)。