2009-07-16 2 views
1

Я ищу, чтобы вытащить определенную строку из числа таблиц, имеющих критерии имени поля1. Проблема, с которой я сталкиваюсь, заключается в том, что когда я совмещаю имя владельца и таблицы и пытаюсь вызвать «select criteria1 from @t где linenum = 1», SQL ожидает, что @t будет таблицей. Мне нужно знать, как построить полное имя таблицы, а затем передать ее этому запросу. Я знаю, что могу использовать язык программирования для доступа к БД, но мне нужно, чтобы это было в SQL. Если кто-то знает лучший способ сделать это, это тоже будет здорово.Построение FROM в SQL

declare @next as varchar 
declare @owner varchar 

while 1=1 
begin 
    set @next = (select top 1 o.name FROM syscolumns c inner join sysobjects o on c.id = o.id 
       where c.name = 'criteria1' and o.id > @next order by o.id)  

    if @next is null 
    break 
    else 
    begin 
    set @owner = (select top 1 u.name 
        FROM syscolumns c inner join 
         sysobjects o on c.id = o.id left join 
         sysusers u on o.uid=u.uid 
        where c.name = 'criteria1' and o.id = @next order by o.id) 
    declare @t as varchar 
    set @t = @owner+'.'[email protected] 
    select criteria1 from @t where linenum = 1  
    end 
    continue 
end 

ответ

4

Вы можете построить весь запрос, который вы хотите как VARCHAR(), а затем выполнить его с хранимой процедурой sp_executesql.

http://msdn.microsoft.com/en-us/library/ms188001.aspx

В вашем случае, что немного в конце становится

declare @sql varchar(512); 
set @sql = 'select criteria1 from ' + @t + ' where linenum = 1'   
sp_executesql @sql 
+3

В качестве примечания стороны, вы должны очень осторожно относиться к любой возможной инъекции при движении по этому маршруту. –

+0

@Chris +1 - но если MisterBigs вытаскивает tablenames из sysobjects, он должен быть в порядке. Если кто-то не создал таблицу с именем «dual; drop table students», - http://xkcd.com/327/ – banjollity

+1

Используйте QUOTENAME (@T) при построении строки. –

2

Рассматривали вы следующий построить в хранимой процедуре?

CASE @tablename 
    WHEN 'table1' THEN SELECT * FROM table1 
    WHEN 'table2' THEN SELECT * FROM table2 
    WHEN 'table3' THEN SELECT * FROM table3 
    WHEN 'table4' THEN SELECT * FROM table4 
    END 

В случае, если вы в браке с динамическим SQL (считается плохим выбором для этой проблемы пространства), this guide to dynamic SQL should help a lot. Это помогло мне, и я активно использовал динамический SQL.

+0

Спасибо, что посмотрю ссылку, которую вы опубликовали. Я не знаю имен таблиц, и их несколько тысяч, поэтому sp не был бы хорош для этого. –

0

Возможно, просмотр можно использовать здесь?

CREATE VIEW vCriterias 
AS 
SELECT 'Table1' AS TableName, 
linenum, 
criteria1 
FROM Table1 
UNION ALL 
SELECT 'Table2' AS TableName, 
linenum, 
criteria1 
FROM Table2 
UNION ALL 
SELECT 'Table3' AS TableName, 
linenum, 
criteria1 
FROM Table3 

go 

Тогда выбор как:

SELECT criteria1 
    FROM vCriterias 
    WHERE linenum = 3 
    AND TableName IN ('Table1','Table3') 
1

Спасибо за помощь. Это то, чем я закончил.

declare cur cursor for 
select u.name + '.' + o.name tname 
    FROM sysobject o left join 
     syscolumns c on c.id = o.id left join 
     sysusers u on o.uid=u.uid 
    where c.name = 'criteria1' 

declare @tn as varchar(512) 
open cur 
fetch next from cur into @tn 

create table holding_table (val varchar(512), table_name varchar(512)) 
declare @sql nvarchar(1000) 

while @@FETCH_STATUS = 0 
begin 
    set @sql = 'insert into holding_table select criteria1, ''' + @tn + ''' from ' + @tn + ' where linenum = 1' 
    execute sp_executesql @sql 
    fetch next from cur into @tn  
end 
close cur 
deallocate cur 
Смежные вопросы