如何将datatable列作为参数传递给存储过程

时间:2015-11-27 09:35:08

标签: sql stored-procedures datatable dynamic-sql

create procedure insert_data
(@Table-name,
@column-name,
@column-value)
as 
Begin 
......
end

我有一个数据表,其中有3列名为table-namecolumn-namecolumn-values,我希望将其传递给存储过程。

在存储过程中,我想获取数据表值,我想要    创建一个应该创建INSERT语句的动态SQL    使用table-name中的column-namecolumn-valuesdata-table

示例:

insert into @table-name(@column-name) values(@column-values)

1 个答案:

答案 0 :(得分:0)

在您走这条路之前,我强烈建议您阅读The Curse and Blessings of Dynamic SQL

您没有指定您使用的RDBMS,因此我使用SQL Server作为示例:

CREATE TABLE mytable(ID INT IDENTITY(1,1), col1 VARCHAR(100),
                     col2 INT, col3 DATETIME);
GO

CREATE PROCEDURE [dbo].[insert_data]
    @Table_Name    SYSNAME
   ,@Column_Name   SYSNAME
   ,@Column_Value  NVARCHAR(MAX)
AS
BEGIN
   SET NOCOUNT ON;

   -- here you should check metadata if table/column exists
   -- you can get also the column datatype and validate with `TRY_PARSE`

   SELECT @Table_Name = QUOTENAME(@Table_Name),
          @Column_Name = QUOTENAME(@Column_Name);

   DECLARE @sql NVARCHAR(MAX)  =
     N'INSERT INTO @Table_Name(@Column_Name)
       VALUES (@Column_Value);';

   SET @sql = REPLACE(@sql, '@Table_Name', @Table_Name);
   SET @sql = REPLACE(@sql, '@Column_Name', @Column_Name);

   -- debug
   -- SELECT @sql

   EXEC dbo.sp_executesql
          @sql
          ,N'@Column_Value NVARCHAR(MAX)'
          ,@Column_Value;
END
GO

通话:

您可以使用CURSOR/LOOP从表格中读取数据,并为每一行调用程序。

EXEC [dbo].[insert_data] 
   @Table_Name     = 'mytable' 
   ,@Column_Name   = 'col1'
   ,@Column_Value  = 'Text Sample';
GO

EXEC [dbo].[insert_data] 
   @Table_Name     = 'mytable' 
   ,@Column_Name   = 'col2'
   ,@Column_Value  = '100';
GO

EXEC [dbo].[insert_data] 
   @Table_Name     = 'mytable' 
   ,@Column_Name   = 'col3'
   ,@Column_Value  = '2015-11-27T00:00:00';
GO

SqlFiddleDemo

说明:

  1. 不要将其视为生产就绪代码,只作为存根/起始点!!
  2. 您的INSERT对我没有意义,因为它还应该UPDATE现有行(一次插入一个值会留下NULL/default value的其他字段
  3. 请注意可能SQL Injection所以引用标识符,参数化值
  4. 检查表/列是否存在,并且提供的值是否可以转换为其数据类型,如果不是,则添加将转换@Column_Value的代码并非每个数据类型都可以隐式地从string
  5. 转发
  6. 使用普通INSERT INTO
  7. 重新考虑