我有一个下面的SQL表:
Types table -------------------------------------- |Name(varchar(50))|Type (varchar(50))| -------------------------------------- | Car | varchar(50) | | Apples | int | --------------------------------------
我正在使用另一个表来存储值,例如:
Apples table: ---------------------------- |Value (providedType - int)| ---------------------------- |50 | |60 | ----------------------------
要将值插入这些表中,我正在使用存储过程(其中一部分):
CREATE PROCEDURE [dbo].[AddValue] @value sql_variant @name varchar(50) @tableName (50) AS BEGIN DECLARE @Sql NVARCHAR(MAX) DECLARE @valueType VARCHAR(50) SET @valueType = (SELECT [Type] FROM [dbo].[Types] WHERE [Name] = @name) SET @Sql = N'INSERT INTO [dbo].'+ @tableName + N' VALUES(' + @value + N')' EXECUTE sp_executesql @Sql ...
动态执行将引发一个异常,即不允许隐式转换sql_variant。有什么方法可以将sql_variant类型转换为varchar提供的类型?如:
CONVERT(@valueType, @value)
其中@valueType是varchar而不是datetype
是的,您可以将sql_variants参数作为传递给sp_executesql,但是您需要使用“转换为”类型继续沿动态SQL路由进行下去,并使用为所使用的列确定的类型名称CAST。
sql_variants
sp_executesql
CAST
以这个为例:
CREATE TABLE Foo ( ID INT ); declare @type NVARCHAR(20) = N'INT'; -- Substitute your Type here. declare @tableName NVARCHAR(50) = 'Foo'; declare @value sql_variant; set @value = 1234; DECLARE @Sql AS NVARCHAR(MAX) = N'INSERT INTO [dbo].'+ @tableName + N' VALUES(CAST(@value AS ' + @type + '))'; EXECUTE sp_executesql @Sql, N'@value sql_variant', @value = @value;
不用说,您将需要确保您的@tableName和Type数据需要针对白名单运行,以便使用这种动态Sql来防止Sql Injection漏洞。
@tableName
Type
SqlFiddle在这里