使用动态SQL返回TABLE的T-SQL函数

时间:2017-10-09 18:58:08

标签: sql-server function tsql dynamic-sql

编辑:有些提供帮助的人不清楚要求的性质,所以我会尽可能清楚地说明:

我们需要实例化基础表的视图,并且此视图必须能够连接到另一个表;难点在于直到执行连接的即席查询的运行时才知道基础表的标识。 我们想做这样的事情:

  select * from foo
   inner join dynamicallyInstantiatedTable(condition) DT
   on foo.zipcode = DT.zipcode

如果函数使用动态SQL,那么创建一个返回TABLE的函数似乎不可能。这是无效的:

   declare @tablename varchar(50);
   -- <snip> code to determine the name of @tablename

   declare @statement varchar(1000);
   set @statement = 'select * from ' + @tablename;
   exec( @statement);

错误:

  

无效使用副作用操作符&#39; EXECUTE STRING&#39;在一个   功能

如果由于某种原因事先不知道表名(例如表格经常被添加,我们必须选择最新的表格,比如说),是否可以动态地进行选择在存储过程或函数中返回一个表吗?

4 个答案:

答案 0 :(得分:0)

功能中的动态SQL。没有。

  

是否可以动态执行select并返回表    在存储过程 或函数中?

也许我错过了一些东西(不会是第一个),但这似乎是一个简单的存储过程:

The Proc

create proc dbo.getRowsFrom @tablename varchar(50) as
exec('select * from ' + @tablename);

使用

exec dbo.getRowsFrom '<my table>';

这就是你要找的东西吗?

答案 1 :(得分:0)

你应该用例子来解释你的要求。任何人都不清楚。

我认为所有事情都可以在单个proc中完成,不需要其他proc或UDF。

declare @tblname varchar(500)
select  @tblname=name from sys.objects
where type_desc ='USER_TABLE'
order by create_date DESC

declare @Sql varchar(max)=''
set @Sql='select * into #tmp from '+@tblname+'  '

set @Sql=@Sql+' select *  from #tmp   drop table #tmp'
exec (@Sql)

答案 2 :(得分:0)

关于您的“加入”情况的细节很少,但跳转到最终的联接结果可能更容易,而不是孤立地关注输入表。

这里我将输入表'a'加入查找表'ref',并输出连接结果。 如果明天你有另一个输入表'b' - 这个proc将把它连接到查找表。 唯一的要求是连接列是一致的。

  declare 
  @inputTableName nvarchar(128)
  ,@sqlExec nvarchar(max)

  set @inputTableName = 'b';

  if(not exists (select 1 from INFORMATION_SCHEMA.TABLES where table_schema = 'test' and TABLE_NAME = 'myView'))
  begin
        select @sqlExec = 'create view test.myView as 
                            select I.*,R.[text] from test.[' + @inputTableName + '] I inner join test.ref  R on I.col0 = R.col0'
end else begin
        select @sqlExec = 'alter view test.myView as 
                            select I.*,R.[text] from test.[' + @inputTableName + '] I inner join test.ref  R on I.col0 = R.col0'
end
    exec (@sqlExec)

select * from test.myView

答案 3 :(得分:0)

我们走了。

我不经常使用同义词,但CREATE SYNONYM支持动态SQL。

std::end(entry.first)