查询表中列出的所有数据库

Mic*_*mon 4 sql-server t-sql sql-server-2008-r2

我一直在使用游标来获取结果,但是返回结果集需要很长时间。我希望找到一种方法来快速返回结果(如果可能的话)。这是我的带有垃圾 DDL 的数据结构。

第一个问题是每个员工都有自己的桌子。我知道这是一个主要的设计缺陷,我们正在迅速解决这个问题,但在所有元素都更新之前我需要一个替代方案。所有 3 个表geoffrey, jorge, mitch都具有相同的结构,我附上了示例 DDL geoffrey, & jorge,下面是一个示例查询,显示了我需要从两个表中的每一个查询的内容。

非常感谢有关如何实现这一结果的任何帮助!

Create Table #ReviewDB
(
  [TableName] varchar(500)
  ,[ServerDBTable] varchar(MAX)
)
Insert Into #ReviewDB VALUES
('geoffrey', 'beans.franks.dbo.geoffrey')
,('jorge', 'smallpox.virus.dbo.jorge')
,('mitch', 'mosquito.insect.dbo.mitch')
Create Table #geoffrey
(
  recordID int IDENTITY(1,1) PRIMARY KEY
  ,firstname varchar(500)
  ,lastname varchar(500)
  ,address varchar(500)
  ,city varchar(500)
  ,state varchar(500)
  ,zip varchar(500)
  ,phone varchar(500)
  ,itemsold varchar(500)
  ,saledate datetime
  ,managerapproved varchar(500)
)
Insert Into #geoffrey VALUES
('manny', 'ramirez', '1111111 aoaswdfrljkasdf ', 'topaz', 'mn', '1111', '9995552222', 'sofa', '01/21/2016', '')
,('hi', 'ho', '2323 aoaswdfrljkasdf ', 'topaz', 'mn', '1111', '6662229888', 'chair', '02/21/2016', '')
,('ee', 'aa', '4646 aoaswdfrljkasdf ', 'topaz', 'mn', '1111', '3332221919', 'ottoman', '01/21/2016', '')
Create Table #jorge
(
  recordID int IDENTITY(1,1) PRIMARY KEY
  ,firstname varchar(500)
  ,lastname varchar(500)
  ,address varchar(500)
  ,city varchar(500)
  ,state varchar(500)
  ,zip varchar(500)
  ,phone varchar(500)
  ,itemsold varchar(500)
  ,saledate datetime
  ,managerapproved varchar(500)
)
Insert Into #jorge VALUES
('aa', 'bb', '1111111 c street ', 'holt', 'tn', '2222', '1113334444', 'sofa', '01/21/2016', '')
,('cc', 'ddo', '2323 b street ', 'holt', 'tn', '2222', '8889997788', 'chair', '02/21/2016', '')
,('mm', 'rr', '4646 e street ', 'holt', 'tn', '2222', '8889998877', 'ottoman', '03/21/2016', '')
Create Table #managerrevieweddata
(
  ID int IDENTITY(1,1) PRIMARY KEY
  ,recordID int
  ,dbname varchar(500)
  ,managernotes text
  ,regionalmanager varchar(500)
  ,districtmanager varchar(500)
  ,incentiveitem varchar(500)
)
Insert Into #managerrevieweddata VALUES
('1', 'geoffrey', 'Valid sale, remind to offer upsell next time.', 'Regional Manager', 'District Manager', 'No')
,('2', 'jorge', 'Review with salesman', 'Regional Manager', 'District Manager', 'NO')
Run Code Online (Sandbox Code Playgroud)

这是一个查询,显示了我想要的输出是什么。

我需要一种方法来查询 #ReviewDB 中的每个 serverdbtable 并返回以下选择语句

Declare @saledate datetime
Set @saledate = '03/21/2016'

Select a.firstname, a.lastname, a.address, a.city, 
a.state, a.zip, a.phone,   a.itemsold, a.saledate,
b.dbname, b.managernotes, b.regionalmanager, 
b.districtmanager, b.incentiveitem
FROM #ReviewDB.ServerDBTable a
INNER JOIN #managerrevieweddata b
ON a.recordID = b.recordID
and a.saledate = @saledate
Run Code Online (Sandbox Code Playgroud)

Han*_*non 5

您使用的游标不太可能是返回结果延迟的原因。最有可能的是,延迟是由于对可能的大量数据运行了许多选择语句。话虽如此,我可能不会使用DECLARE CURSOR cur FOR ...构造来解决这个问题。

我通常通过生成单个动态 SQL 语句来解决此类问题,然后使用sp_executesql()或执行该语句EXEC (),如下所示:

IF COALESCE(OBJECT_ID('dbo.TableList'), 0) <> 0
DROP TABLE dbo.TableList;

CREATE TABLE dbo.TableList
(
    DatabaseName SYSNAME NOT NULL
    , SchemaName SYSNAME NOT NULL
    , TableName SYSNAME NOT NULL
);

INSERT INTO dbo.TableList(DatabaseName, SchemaName, TableName)
VALUES ('Database1', 'Schema1', 'Table1')
    ,  ('Database2', 'Schema2', 'Table2');

DECLARE @cmd NVARCHAR(MAX);
SET @cmd = '';

SELECT @cmd = @cmd + CASE WHEN @cmd = '' THEN '' ELSE CHAR(13) + CHAR(10) END 
    + 'SELECT ''' + tl.DatabaseName 
        + '.' + tl.SchemaName 
        + '.' + tl.TableName 
        + ''', * '
    + 'FROM ' + QUOTENAME(tl.DatabaseName) 
        + '.' + QUOTENAME(tl.SchemaName) 
        + '.' + QUOTENAME(tl.TableName) + ';'
FROM dbo.TableList tl;

PRINT (@cmd);
EXEC sp_executesql @cmd;
Run Code Online (Sandbox Code Playgroud)

这构造了表中所需的语句TableList,将每个语句附加到一个变量中。然后使用sp_executesql系统存储过程执行变量内容。此方法可用于解决需要根据某些查询的结果生成 T-SQL 语句的多种问题。

输出将是每行的单个结果集TableList- 您可能不希望对超过 50 或 100 个表执行此操作,因为输出可能变得无法管理。如果您有很多表,您可能需要考虑将输出插入到临时表中,然后select对该表运行单个语句。

如果TableName列中列出的表的结构相同,则可以使用 aUNION ALL将输出连接到单个结果集:

SELECT @cmd = @cmd + CASE WHEN @cmd = '' THEN '' ELSE CHAR(13) + CHAR(10) 
    + 'UNION ALL' + CHAR(13) + CHAR(10) END 
    + 'SELECT ''' + tl.DatabaseName 
        + '.' + tl.SchemaName 
        + '.' + tl.TableName 
        + ''', * '
    + 'FROM ' + QUOTENAME(tl.DatabaseName) 
        + '.' + QUOTENAME(tl.SchemaName) 
        + '.' + QUOTENAME(tl.TableName) + ';'
FROM dbo.TableList tl;
Run Code Online (Sandbox Code Playgroud)

请注意,这UNION ALL通常比UNION因为该ALL选项不需要DISTINCT在数据上运行运算符快得多。

  • 是的,当我需要构建对多个表、过程、外键等重复操作的动态命令时,这是我经常使用的方法。但是对于 OP 和 @VladimirS.,**这仍然是一个游标** , 只是没有 `DECLARE CURSOR` 或 `WHILE` 代码。您是否使用显式游标来构建最终运行的代码并不重要 - 与您最终要对所有内容执行的任何操作相比,游标期间的字符串连接将是杯水车薪那些桌子。 (4认同)