【问题标题】:SQL Server 2008 R2: stored procedure with one or more table names a parameterSQL Server 2008 R2:具有一个或多个表名的存储过程作为参数
【发布时间】:2017-10-22 14:41:12
【问题描述】:

我有这个存储过程来归档给定表的给定天数之前的数据:

CREATE PROCEDURE [dbo].[sp_util_archive_test] 
    @days int, @table_name nvarchar(64)
AS
BEGIN TRY
BEGIN TRANSACTION
    DECLARE @archive_table varchar(128),
            @src_table varchar(128);
    SET @src_table = @table_name;
    SET @archive_table = @table_name + '_archive';

    DECLARE @dropSQL nvarchar(max) = 'DROP TABLE ' + @archive_table;

    IF OBJECT_ID(@archive_table, 'U') IS NOT NULL
      EXEC (@dropSQL);

    DECLARE @sqlCommand nvarchar(1000)
    DECLARE @date varchar(75)
    SET @sqlCommand = 'Select * into [' + @archive_table + ']  from  [' + @src_table + '] WHERE date <= dateadd(d, -' + CAST(@days AS varchar(16)) + ', getdate())'
    EXECUTE sp_executesql @sqlCommand

  COMMIT
END TRY
BEGIN CATCH
  ROLLBACK
  DECLARE @Msg nvarchar(max)
  SELECT
    @Msg = ERROR_MESSAGE();
  RAISERROR ('Error Occured: %s', 20, 101, @Msg) WITH LOG;
END CATCH

现在我已经安排了多个 SQL 作业来归档多个表的数据,有没有办法通过使存储过程接受 1 个或多个表名然后一次归档所有表的数据来消除多个 SQL 作业?

【问题讨论】:

  • 听起来你想要一个表格参数,然后你会在光标中使用它。但是如果我将talbeName]; drop table users;-- 传递到您当前的程序中呢?
  • 我归档的表是日志表,除了 7 天的数据之外不值得维护,所以我不关心这种情况下的用户
  • 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!
  • 说得更清楚一点,这是一个SQL注入的风险。使用动态 SQL 是有风险的。

标签: sql sql-server stored-procedures sql-server-2008-r2


【解决方案1】:

忽视注射风险;您可以将分隔字符串传递到参数中,然后循环遍历执行每个迭代的现有存储过程的结果。

例如@param = 'table1|Table2|Table3|Table4'

在“|”上分割 循环遍历所有结果并为每次迭代执行您的 SP。

拆分示例:How to split string and insert values into table in SQL Server

【讨论】:

    【解决方案2】:

    为什么要复杂化?使用多个作业步骤或将多行放在一个步骤中:

    EXEC [dbo].[sp_util_archive_test] 50, 'table1';
    EXEC [dbo].[sp_util_archive_test] 70, 'table2';
    EXEC [dbo].[sp_util_archive_test] 80, 'table3';
    EXEC [dbo].[sp_util_archive_test] 10, 'table4';
    

    【讨论】:

      猜你喜欢
      • 2015-01-26
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多