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我明白你的观点,并感谢你的反馈,我显然必须重新审视我的逻辑,以避免注射风险。我还必须再次检查其他数据类型的工作情况。我提供的代码稍微简化了一点,实际上大部分信息都是参数化的(表名、列名、设置和后的两个参数,其中),因此该过程可以用于多个表(可以是标准化的或平面的)。