T-SQL 存储过程,用于从服务器上的任何表获取数据以进行 CSV 导出 (SQL Server 2016)



已回答/已解决。

长话短说,我需要一个存储过程,它将从几个不同的视图中获取数据并将其放入.CSV文件中。很简单,但我就是我,我决定写一些东西,可以从任何可能想要的表中获取数据。我决定最后采用 2 个程序:

  1. 遍历包含所有参数(目录、架构、表名、导出路径/文件名等)的表,并将其提供给第二个存储过程(理论上,如果/当需要导出不同的数据时,它应该使将来更容易管理)。这个相当简单,不会引起任何问题。

  2. 拿起列名(这非常容易 - 以防它对任何人有帮助)

    select @SQL = 'insert into Temp_Export_Headers ' +
    'select COLUMN_NAME ' +
    'from [' +  @loc_Source_Database + '].information_schema.columns ' +
    'where table_name = ''' +  @loc_Source_Table + '''' 
    

    select @Headers = coalesce(@Headers + ',', '') + convert(varchar, Column_Name)
    from Temp_Export_Headers
    

之后,我想将所有数据从"实际"表转储到临时表中,这本身就很容易,但这就是事情开始走下坡路的地方。

select @SQL =
'drop table if exists TempData ' +
'select * ' +
'into TempData ' +
'from [' + @loc_Source_Database + '].' + @loc_Source_Schema + '.' + @loc_Source_Table + ' with (nolock) ' 

Select *只是暂时的,以后可能会用变量替换它,现在它可以在 dev 上处于这种状态。

现在我想遍历TempData并插入我想要的东西(目前的所有内容,将在不久的将来添加一些技巧和 where 子句)并将其放入另一个临时表中,其中包含实际 CSV 导出的所有内容。

  • 有没有办法在我的TempData中添加一个自递增列,而不必寻找并摆脱原始的PK/身份?(不同的表会有不同的值/名称,对于具有我的知识/经验的人来说,以合理的方式循环浏览有点噩梦,所以我只是喜欢一个简单的列,从 1 开始并以最后一行编号结束)

@ShubhamPandey的答案正是我所追求的,下面的代码是我疲惫的头脑在疯狂的边缘的产物(但是,它确实有效)

select @SQL = 
'alter table TempData ' +
'add Uni_Count int'
select @SQL2 =
'declare @UniCount int ' +
'select @UniCount = 0 ' +
'update tempdata with (rowlock) ' +
'set @UniCount = Uni_Count = @UniCount + 1' 

这两个版本的执行速度都比select * into快,无需任何其他操作。我还无法理解的东西。

  • 有没有更好/更明智的方法来做到这一点?(我对循环的推理 - 某些表/视图可能会有很多数据,其中大多数每天执行,计划是在系统不那么繁忙时在周六/周日导出所有内容,并每天"更新"从上一个最高唯一 id 到当前。

循环是一个可怕的想法。为了说明它有多糟糕:

  • 循环访问 10k 行意味着执行时间为 1 分 21 秒。
  • 不循环访问 500k 行会导致执行时间为 56 秒。

由于您在插入时正在创建表,因此您始终可以使用如下语句继续前进:

select @SQL =
'drop table if exists TempData ' +
'select ROW_NUMBER() OVER (<some column name>) AS [Id], * ' +
'into TempData ' +
'from [' + @loc_Source_Database + '].' + @loc_Source_Schema + '.' + @loc_Source_Table + ' with (nolock) ' 

这将在 TempData 表中为您创建一个自动递增索引

最新更新