【问题标题】:Create a list of dynamic queries from an array in SQL Server 2008从 SQL Server 2008 中的数组创建动态查询列表
【发布时间】:2014-06-12 14:47:26
【问题描述】:

我从Fill dynamic array with values from an array 拆分了这个问题。下面是我现在拥有的实际代码。

首先是动态代码,其次是我希望动态代码输出的 3 个示例查询(但它没有输出)。我收到一个错误Invalid column name "field",或者当我将field 更改为#tmp_auditlog_fields.field 时,出现the column "field" cannot be bound 的错误。后一个错误可能是由于我没有加入任何表,但我不知道要加入表的字段,因为#tmp_auditlogs_fields 只不过是一个创建一堆查询的数组,与数据库中的任何真实数据无关.

如何获得所需的输出?非常感谢任何帮助:-)

-- dynamic code

create table #tmp_auditlog_fields (
  id int identity(1,1),
  field varchar(255),
  details varchar(255)
);

insert into #tmp_auditlog_fields (field, details) values
    ('a', 'foo'),
    ('b', 'bar'),
    ('c', 'baz'),
;

declare @sql nvarchar(max);
declare @cnt int, @i int = 1;

select @cnt = max(id) from #tmp_auditlog_fields;

while @i <= @cnt
    begin
        select @sql = 
            'select t.objectID, t.DocID as ' + field + 
            ' into #tmp_auditlog_' + field + 
            ' from #tmp_auditlog_subselection t where Details like ' + 
            details FROM  tmp_auditlog_fields WHERE id = @i
        exec sp_executesql @sql
        select @i = @i + 1
    end 
;

-- example queries

select t.ObjectID, t.DocID as a 
into #tmp_auditlog_a from #tmp_auditlog_subselection t
where Details like 'foo';

select t.ObjectID, t.DocID as b 
into #tmp_auditlog_b from #tmp_auditlog_subselection t
where Details like 'bar';

select t.ObjectID, t.DocID as c 
into #tmp_auditlog_c from #tmp_auditlog_subselection t
where Details like 'baz';

SQL Fiddle 尝试:

declare @sql nvarchar(max);
declare @id int;

create table #tmp_auditlog_subselection (
  stuff varchar(255),
  other varchar(255)
);

insert into #tmp_auditlog_subselection (stuff, other) values
  ('foo', 'bar'),
  ('baz', 'bat'),
  ('lorem', 'ipsum')
;

create table #tmp_auditlog_fields (
  id int identity(1,1),
  field varchar(255),
  details varchar(255)
);

insert into #tmp_auditlog_fields (field, details) values
  ('a', 'foo'),
  ('b', 'bar'),
  ('c', 'baz')
;

while exists(select * from #tmp_auditlog_fields where id >= @id)
    begin
        select @sql = 
            'select t.objectID, t.DocID as ' + field + 
            ' into #tmp_auditlog_' + field + 
            ' from #tmp_auditlog_subselection t where Details like ' + 
            details FROM tmp_auditlog_fields WHERE id = @i;
        exec @sql
        select @id = min(id) from #tmp_auditlog_fields where id > @id;
    end 
;

select * from #tmp_auditlog_a;

【问题讨论】:

  • 在您的select @sql = ... 之后添加FROM #tmp_auditlog_fields。当前查询不知道要从哪个表中提取 fielddetails 列。

标签: sql sql-server sql-server-2008


【解决方案1】:

您在这里缺少 from 语句和 where 语句:

while @i <= @cnt
    begin
        select @sql = 
            'select t.objectID, t.DocID as ' + field + 
            ' into #tmp_auditlog_' + field + 
            ' from #tmp_auditlog_subselection t where Details like ' + details FROM #tmp_auditlog_fields WHERE id = @i
        exec sp_executesql @sql
        select @i = @i + 1
  end

【讨论】:

  • 它们应该是 - 你可以尝试使用全局临时表:##temp_auditlog_foo
  • 当我尝试在我的机器上运行时,出现两个错误:('b', 'bar'), ('c', 'baz'), ; 之后的额外逗号,并且还缺少此处的井号:details FROM tmp_auditlog_fields WHERE id = @i
  • 在动态 sql 中创建的临时表仅在该动态 sql 中起作用。在动态 sql 之外创建的临时表的范围是这样的,以便当前会话以及动态会话可以访问它。但是,正如 Dave.Gugg 建议的那样,全局临时表是一种替代方法。
  • 我没怎么用过 SQL Fiddle。在我刚才的测试尝试中,似乎使用; 似乎正在分解发出的批次并导致变量超出范围。
  • 您的小提琴链接没有任何临时表。我试图在这里重现我认为你想要的东西:sqlfiddle.com/#!3/dcae9/20
猜你喜欢
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2017-06-15
  • 2013-09-24
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多