2017-08-15 64 views
0

我正在加载一个特定的问题,即在连接到主数据库时从特定数据库(以及一组数据库)加载表的列表。目前我的查询加载服务器上的所有数据库,然后通过这些数据库循环通过RAISERROR将信息发送回客户端。当这个循环正在执行时,我需要一个嵌套循环来加载当前数据库的所有表格,以便稍后传输,一旦查询完成,将它作为SELECT。我遇到的问题是,这将作为C#代码中的单个查询来执行。理想情况下,我想在SQL中加载所有内容并将其返回给客户端进行处理。例如:SQL:连接到另一个表时从指定数据库拉表

WHILE (@dbLoop < @dbCount) BEGIN 
    -- Do cool things and send details back to client. 
    SET @dbName = (SELECT _name FROM dbTemp WHERE _id = @dbLoop); 
    -- USE [@dbName] 
    -- Get a count of the tables from info schema on the newly specified database. 
    WHILE (@tableLoop < @tableCount) BEGIN 
      -- USE [@dbName] 
      -- Do super cool things and load tables from info schema. 
      SET @tableLoop += 1; 
    END 

    SET @dbLoop += 1; 
END 

-- Return the list of tables from all databases to the client for use with SQLDataAdapter. 
SELECT * FROM tableTemp; 

此主题非常简单;我只需要一种方法来访问指定数据库中的表(最好是通过名称),而无需更改对象上的连接,并且不必在我的C#代码中有一个循环来处理对每个数据库上的相同查询C#方面。将所有内容加载到SQL中并将其发送回应用程序会更高效。任何可以提供的帮助都会很棒!

感谢, 杰米

+1

你为什么不写一个存储过程? –

+0

想到了这一点,并被告知我们不使用任何存储过程,除了微软提供的存储过程,因为它们存在安全风险。此外,如果有人也问我为什么不使用游标查询,我们的DBA不允许游标查询,除非可以将其作为迫切需要。 – lxxtacoxxl

+1

@lxxtacoxxl - 实际上它是相反的 - SPs更安全。 – Hogan

回答

0

好的,花了整整一天的时间对此进行研究之后,我终于想出了一个解决方案。我将所有数据库加载到一个表变量中,然后我开始循环这些数据库并将其详细信息发送回客户端。在数据库细节本身已通过RAISERROR发送到客户端之后,我利用sp_executesql执行一个新的子查询,并指定当前数据库以获取在主结束时处理的表列表。以下示例展示了此过程的基本结构,以供其他人将来遇到此问题。

再次感谢大家的帮助!

-Jamie

DECLARE @LoopCounter INT = 1, @DatabaseCount INT = 0; 
DECLARE @SQL NVARCHAR(MAX), @dbName NVARCHAR(MAX); 
DECLARE @Databases TABLE (_id INT, _name NVARCHAR(MAX)); 
DECLARE @Tables TABLE (_name NVARCHAR(MAX), _type NVARCHAR(15)); 

INSERT INTO @Databases 
SELECT ROW_NUMBER() OVER(ORDER BY name) AS id, name 
FROM sys.databases 
WHERE name NOT IN ('master', 'tempdb', 'msdb', 'model'); 

SET @DatabaseCount = (SELECT COUNT(*) FROM @Databases); 

WHILE (@LoopCounter <= @DatabaseCount) BEGIN 
    SET @dbName = (SELECT _name FROM @Databases WHERE _id = @LoopCounter); 
    SET @SQL NVARCHAR(MAX) = 'SELECT TABLE_NAME, TABLE_TYPE 
          FROM [' + @dbName + '].INFORMATION_SCHEMA.TABLES'; 
     INSERT INTO @Tables EXEC sp_executesql @SQL; 
    SET @LoopCounter += 1; 
END 
1

所有的表都在元数据中你可以做一个问号,并加入到你的,你想看看模式的列表。

SELECT tab.name 
FROM sys.tables AS tab 
JOIN sys.schemas AS sch on tab.schema_id = sch.schema_id 
JOIN dbTemp temp on sch.name = temp.[_name] 

这将返回作为结果集返回的表的列表。

+0

这没有返回任何结果,尝试它自己仍然没有结果。我将最终的JOIN更改为where子句,将模式名称与特定的数据库名称(实际上是几个名称)进行比较。 – lxxtacoxxl

+0

只是取出最后一个连接并将sch.name添加到结果中......然后您将知道所有您想要和不想要的模式名称。 – Hogan

0

后运行(通常通过GO语句声明USE [@dbName]生效。

USE [@dbName] 
GO 

上述2线将让你开始使用新的数据库。你不能在你的SQL中间使用或SP。

,你可以用另外一个选择是使用点符号,即语法用dbname..tablename查询您的表。

double dot notation post

+0

名称'@dbName'找不到数据库。这与双点和单点记号相同。 – lxxtacoxxl

相关问题