Member 13007002 Ответов: 2

Я создал таблицы с именами столбцов, такими как iname и quantity. Я хочу взять параметры пользователя 'имя_таблицы' 'имя_экземпляра' и 'количество' . Показывает ошибку пожалуйста помогите


alter procedure spinserttable 
@tname varchar (50)
as 
begin
declare @sql nvarchar(max)
declare @parameter varchar(100)
declare @iname varchar(50)
declare @quantity int
set @sql= 'insert into ' + @tname + '(iname, quantity) values ( '+ @iname +', '+ @quantity +')'
set @parameter = '@iname varchar(50) @quantity int'
execute sp_executesql @sql, @parameter, @iname ,@quantity
end


Что я уже пробовал:

я дал себе ошибку
'must declare scaler variable 'iname' so i declare iname and quantity' now it gives me error 'Conversion failed when converting the varchar value ')' to data type int'

2 Ответов

Рейтинг:
1

Richard Deeming

Вы используете конкатенацию строк для построения динамического SQL-запроса. Это оставляет ваш код открытым для SQL-инъекция[^].

Вам нужно передать параметры как параметры, а не объединять их значения в запрос.

К сожалению, вы не можете сделать это для имени таблицы. Вместо этого вам нужно будет проверить, что переданное имя является допустимым именем таблицы.

Вы также захотите иметь возможность передавать значения для вставки в хранимую процедуру.

ALTER PROCEDURE spinserttable 
    @tname sysname,
    @iname varchar(50),
    @quantity int
As 
BEGIN
DECLARE @SchemaName sysname, @TableName sysname;
DECLARE @sql nvarchar(max);
DECLARE @params nvarchar(100);
    
    SET NOCOUNT ON;
    
    SELECT
        @SchemaName = S.name,
        @TableName = T.name
    FROM
        sys.tables As T
        INNER JOIN sys.schemas As S
        ON S.schema_id = T.schema_id
    WHERE
        T.name = @tname
    ;
    
    If @@ROWCOUNT = 0 RAISERROR('Invalid table name: %s', 16, 1, @tname);
    
    SET @sql = N'INSERT INTO ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N' (iname, quantity) VALUES (@iname, @quantity)';
    
    SET @params = N'@iname varchar(50), @quantity int';
    
    EXECUTE sp_executesql @sql, @params, @iname, @quantity;
END


Рейтинг:
0

Jin Vincent Necesario

Привет Мацей,

Я попробую это сделать. Может быть, ты сможешь это сделать.

set @sql= 'insert into ' + @tname + '(iname, quantity) values ('+ @iname +','+ CONCAT( @quantity, ')')
Это исправит вашу текущую ошибку.

Ваша текущая проблема заключается в следующем.
et @sql= 'insert into ' + @tname + '(iname, quantity) values ( '+ @iname +', '+ @quantity +')'
Это приводит к ошибке, когда происходит конкатенация с числовым значением с помощью nvarchar.

Вот что я сделал.
declare @tname varchar (50)
declare @sql nvarchar(max)
declare @parameter varchar(100)
declare @iname varchar(50)
declare @quantity int
set @sql= 'insert into ' + @tname + '(iname, quantity) values ('+ @iname +','+ CONCAT( @quantity, ')')


Работает с моей стороны. Спасибо.

Овации,
Джин


Richard Deeming

Это все еще оставляет код уязвимым для SQL-инъекция[^].