【问题标题】:SELECT INTO dynamic temp table using procedure with dynamic parameter使用带有动态参数的过程选择 INTO 动态临时表
【发布时间】:2018-06-14 15:38:14
【问题描述】:

我找不到问题的完整解决方案。我有一个将动态输入作为参数值的现有存储过程。我需要执行这个过程(使用动态变量)并且想以某种方式 SELECT * INTO #mytable 而不必声明临时表的模式。

我尝试过使用 OPENROWSET,但它不允许我指定变量(只能硬编码):

select * into #table from openrowset('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 'exec SERVER..MYSTOREDPROCEDURE @parameter = 123')

我知道的唯一另一种方法是将它包装在一个字符串中并使用 EXEC(@sql),但我不知道如何从中“SELECT * INTO #table”。

我有哪些选择?我可以创建一个可以返回动态表的 UDF 表函数吗?值得怀疑...

【问题讨论】:

  • 我真的不明白这里有什么问题?如果您CREATE 一个临时表并在同一连接中执行动态 SQL,则可以引用它。例如:CREATE TABLE #test (ID int); EXEC sp_executesql N'INSERT INTO #test VALUES (1);'; SELECT * FROM #test; DROP TABLE #test;
  • @Larnu 我想我找到了,他不想声明临时表的架构。
  • 如果你有能力创建它,你的其余代码打算如何使用这个具有未知模式的表?

标签: sql sql-server


【解决方案1】:

我在这里猜测,但您需要在动态 SQL 中完成所有操作。所以,取而代之的是:

DECLARE @SQL nvarchar(MAX);
DECLARE @param nvarchar(10) = 123;
SET @SQL = N'SELECT *' + NCHAR(10) +
           N'INTO #table' + NCHAR(10) +
           N'FROM OPENROWSET(''SQLNCLI'', ''Server=localhost;Trusted_Connection=yes;'', ''exec SERVER..MYSTOREDPROCEDURE @parameter = ' + QUOTENAME(@param,N'''') +N''');' + NCHAR(10) +
           N'SELECT *' + NCHAR(10) + --Of course, I assume you're doing something more complex that a SELECT *.
           N'FROM #table;';
PRINT @SQL;
EXEC sp_executesql @SQL;

【讨论】:

  • 这就是我所看到的,但是如何从 exec 语句之外访问 #table 呢? #table 不是在 tempdb 中创建的吗?在我执行了第一个插入到 #table 的语句后,我似乎无法访问它。
  • @RyanPeters 您无法在动态 SQL 之外访问在动态 SQL 中创建的临时表,但是,情况正好相反(如我的原始评论所示)。
  • 因此,您最好先使用INTO tempdb..[table],然后在批处理结束时使用DROP TABLE tempdb..[table];
【解决方案2】:

我想我明白了。我真的只需要修改临时变量名称即可将临时表放入全局范围。这适用于我的实际表格(我为这篇文章重命名了它们)。

IF OBJECT_ID ('tempdb..##mytemptable') is not null drop table ##mytemptable

declare @id int = 112

declare @sql nvarchar(max) ='SELECT * INTO ##mytemptable FROM OPENROWSET(''SQLNCLI'', ''Server=localhost;Trusted_Connection=yes;'', ''exec SERVER..MyStoredProcedure @ID =' + convert(varchar(10), id) + ''')'

-- invokes and inserts into ##mytemptable
exec sp_executesql @sql

-- now I can query from the global scope
select * from ##mytemptable

【讨论】:

  • 你知道你必须小心。如果代码从不同的连接针对不同的源/过程运行,您的结果可能是不可预测的。
  • 对。幸运的是,这将是一个每天一次的过程。
  • 那你为什么不使用一个或一系列的临时表:每个过程一个?这将比创建临时表更快,并且仅在该数据库范围内可见。
猜你喜欢
  • 1970-01-01
  • 2016-01-22
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 2018-07-31
  • 2020-08-29
相关资源
最近更新 更多