Run a query in loop, with the results of another query First, I want to list databases with a specific table:

 SELECT name
FROM   sys.databases
WHERE  CASE
         WHEN state_desc = 'ONLINE' 
              THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[TB_INF_CLI]', 'U')
       END IS NOT NULL 


Then, I want to use the database_name inside a loop, to list all indexes of this table ( TB_INF_CLI )  of all these databases, with this query:

SELECT DB_NAME() AS Database_Name
, o.name AS Table_Name
, i.name AS Index_Name
, i.type_desc AS Index_Type
FROM sys.indexes i
INNER JOIN sys.objects o ON i.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE i.name IS NOT NULL
AND o.type = 'U'
ORDER BY o.name, i.type


How can I do this without msForEachDb?

with this solution, I can only list the dabatase i'm connected. I can't understand how can I implement the database_name inside this query:

SELECT DB_NAME() AS Database_Name
, o.name AS Table_Name
, i.name AS Index_Name
, i.type_desc AS Index_Type
FROM sys.indexes i
INNER JOIN sys.objects o ON i.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE i.name IS NOT NULL
AND o.type = 'U'
and db_name() in
(SELECT name
FROM   sys.databases
WHERE  CASE
         WHEN state_desc = 'ONLINE' 
              THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[TB_INF_CLI]', 'U')
       END IS NOT NULL 
)
ORDER BY o.name, i.type




EDIT:

i could achieve what I want with this:

create table ##TB_REN (database_name varchar(200),table_name varchar(200),index_name varchar(200),index_type varchar(200))
sp_msforeachdb'use [?]
insert into ##TB_REN( database_name,table_name,index_name,index_type)
SELECT db_name() AS Database_Name
, o.name AS Table_Name
, i.name AS Index_Name
, i.type_desc AS Index_Type
FROM sys.indexes i
INNER JOIN sys.objects o ON i.object_id = o.object_id
INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE i.name IS NOT NULL
and o.name =''TB_INF_CLI''
AND o.type = ''U''
ORDER BY o.name, i.type'


Is there  a better solution??
If you want to assemble the statement at runtime, you're locked into Dynamic SQL as far as I know.  I don't like sp_MSforeachdb as well because it's undocumented and I've ran into bugs with it, so here's an alternative that doesn't require its use:

DECLARE @cmd nvarchar(max) = N'';

SELECT @cmd = @cmd + N'
UNION ALL

SELECT ' + QUOTENAME(QUOTENAME(name),N'''') + N' AS Database_Name
, o.name AS Table_Name
, i.name AS Index_Name
, i.type_desc AS Index_Type
FROM sys.indexes i
INNER JOIN ' + QUOTENAME(name) + '.sys.objects o ON i.object_id = o.object_id
INNER JOIN ' + QUOTENAME(name) + '.sys.schemas sc ON o.schema_id =     sc.schema_id
WHERE i.name IS NOT NULL
AND o.type = ''U'''
FROM sys.databases
WHERE database_id &gt; 4  -- comment out if you want to include system databses

SELECT @cmd = STUFF(@cmd, 1, 13, N'') + N' ORDER BY 1, 2'

PRINT @cmd

EXEC sp_executesql @cmd;